X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsocket.cpp;h=465f8cc733c53a3e8a9a228e8dce27eb2741e5e5;hb=c3e52465901f11226616a2a93393c3d07295b45d;hp=e481846942f0931664c5e39d82ddaad594010d6b;hpb=6c99a01008197c59832eb916dad8d6211f00a3e2;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/socket.cpp b/src/socket.cpp index e48184694..465f8cc73 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -20,6 +20,12 @@ using namespace irc::sockets; +/* Private static member data must be initialized in this manner */ +unsigned int ListenSocket::socketcount = 0; +sockaddr* ListenSocket::sock_us = NULL; +sockaddr* ListenSocket::client = NULL; +sockaddr* ListenSocket::raddr = NULL; + /* Used when comparing CIDR masks for the modulus bits left over. * A lot of ircd's seem to do this: * ((-1) << (8 - (mask % 8))) @@ -51,6 +57,16 @@ ListenSocket::ListenSocket(InspIRCd* Instance, int port, char* addr) : ServerIns this->family = AF_INET; Instance->SE->AddFd(this); } + /* Saves needless allocations */ + if (socketcount == 0) + { + /* All instances of ListenSocket share these, so reference count it */ + ServerInstance->Logs->Log("SOCKET", DEBUG,"Allocate sockaddr structures"); + sock_us = new sockaddr[2]; + client = new sockaddr[2]; + raddr = new sockaddr[2]; + } + socketcount++; } ListenSocket::~ListenSocket() @@ -63,86 +79,88 @@ ListenSocket::~ListenSocket() ServerInstance->Logs->Log("SOCKET", DEBUG,"Failed to cancel listener: %s", strerror(errno)); this->fd = -1; } + socketcount--; + if (socketcount == 0) + { + delete[] sock_us; + delete[] client; + delete[] raddr; + } } - -// XXX this is a bit of an untidy way to avoid reallocating this constantly. also, we leak it on shutdown.. but that's kinda minor - w -static sockaddr *sock_us; -static sockaddr *client; -static bool setup_sock = false; - -void ListenSocket::HandleEvent(EventType, int) +void ListenSocket::HandleEvent(EventType e, int err) { - socklen_t uslen, length; // length of our port number - int incomingSockfd, in_port; - - if (!setup_sock) + switch (e) { - sock_us = new sockaddr[2]; - client = new sockaddr[2]; - setup_sock = true; - } + case EVENT_ERROR: + ServerInstance->Logs->Log("SOCKET",DEFAULT,"ListenSocket::HandleEvent() received a socket engine error event! well shit! '%s'", strerror(err)); + break; + case EVENT_WRITE: + ServerInstance->Logs->Log("SOCKET",DEBUG,"*** BUG *** ListenSocket::HandleEvent() got a WRITE event!!!"); + break; + case EVENT_READ: + { + ServerInstance->Logs->Log("SOCKET",DEBUG,"HandleEvent for Listensoket"); + socklen_t uslen, length; // length of our port number + int incomingSockfd, in_port; #ifdef IPV6 - if (this->family == AF_INET6) - { - uslen = sizeof(sockaddr_in6); - length = sizeof(sockaddr_in6); - } - else + if (this->family == AF_INET6) + { + uslen = sizeof(sockaddr_in6); + length = sizeof(sockaddr_in6); + } + else #endif - { - uslen = sizeof(sockaddr_in); - length = sizeof(sockaddr_in); - } - - incomingSockfd = ServerInstance->SE->Accept(this, (sockaddr*)client, &length); + { + uslen = sizeof(sockaddr_in); + length = sizeof(sockaddr_in); + } - if ((incomingSockfd > -1) && (!ServerInstance->SE->GetSockName(this, sock_us, &uslen))) - { - char buf[MAXBUF]; - char target[MAXBUF]; + incomingSockfd = ServerInstance->SE->Accept(this, (sockaddr*)client, &length); - *target = *buf = '\0'; + if ((incomingSockfd > -1) && (!ServerInstance->SE->GetSockName(this, sock_us, &uslen))) + { + char buf[MAXBUF]; + char target[MAXBUF]; - sockaddr* raddr = new sockaddr[2]; + *target = *buf = '\0'; #ifdef IPV6 - if (this->family == AF_INET6) - { - in_port = ntohs(((sockaddr_in6*)sock_us)->sin6_port); - inet_ntop(AF_INET6, &((const sockaddr_in6*)client)->sin6_addr, buf, sizeof(buf)); - socklen_t raddrsz = sizeof(sockaddr_in6); - if (getpeername(incomingSockfd, (sockaddr*) raddr, &raddrsz) == 0) - inet_ntop(AF_INET6, &((const sockaddr_in6*)raddr)->sin6_addr, target, sizeof(target)); - else - ServerInstance->Logs->Log("SOCKET", DEBUG, "Can't get peername: %s", strerror(errno)); - } - else + if (this->family == AF_INET6) + { + in_port = ntohs(((sockaddr_in6*)sock_us)->sin6_port); + inet_ntop(AF_INET6, &((const sockaddr_in6*)client)->sin6_addr, buf, sizeof(buf)); + socklen_t raddrsz = sizeof(sockaddr_in6); + if (getpeername(incomingSockfd, (sockaddr*) raddr, &raddrsz) == 0) + inet_ntop(AF_INET6, &((const sockaddr_in6*)raddr)->sin6_addr, target, sizeof(target)); + else + ServerInstance->Logs->Log("SOCKET", DEBUG, "Can't get peername: %s", strerror(errno)); + } + else #endif - { - inet_ntop(AF_INET, &((const sockaddr_in*)client)->sin_addr, buf, sizeof(buf)); - in_port = ntohs(((sockaddr_in*)sock_us)->sin_port); - socklen_t raddrsz = sizeof(sockaddr_in); - if (getpeername(incomingSockfd, (sockaddr*) raddr, &raddrsz) == 0) - inet_ntop(AF_INET, &((const sockaddr_in*)raddr)->sin_addr, target, sizeof(target)); - else - ServerInstance->Logs->Log("SOCKET", DEBUG, "Can't get peername: %s", strerror(errno)); + { + inet_ntop(AF_INET, &((const sockaddr_in*)client)->sin_addr, buf, sizeof(buf)); + in_port = ntohs(((sockaddr_in*)sock_us)->sin_port); + socklen_t raddrsz = sizeof(sockaddr_in); + if (getpeername(incomingSockfd, (sockaddr*) raddr, &raddrsz) == 0) + inet_ntop(AF_INET, &((const sockaddr_in*)raddr)->sin_addr, target, sizeof(target)); + else + ServerInstance->Logs->Log("SOCKET", DEBUG, "Can't get peername: %s", strerror(errno)); + } + ServerInstance->SE->NonBlocking(incomingSockfd); + ServerInstance->stats->statsAccept++; + ServerInstance->Users->AddUser(ServerInstance, incomingSockfd, in_port, false, this->family, client, target); + } + else + { + ServerInstance->SE->Shutdown(incomingSockfd, 2); + ServerInstance->SE->Close(incomingSockfd); + ServerInstance->stats->statsRefused++; + } } - - delete[] raddr; - - ServerInstance->SE->NonBlocking(incomingSockfd); - - ServerInstance->stats->statsAccept++; - ServerInstance->Users->AddClient(ServerInstance, incomingSockfd, in_port, false, this->family, client, target); - } - else - { - ServerInstance->SE->Shutdown(incomingSockfd, 2); - ServerInstance->SE->Close(incomingSockfd); - ServerInstance->stats->statsRefused++; + break; } } @@ -492,7 +510,7 @@ int InspIRCd::BindPorts(bool, int &ports_found, FailedPortList &failed_ports) { irc::portparser portrange(configToken, false); int portno = -1; - while ((portno = portrange.GetToken())) + while (0 != (portno = portrange.GetToken())) { if (*Addr == '*') *Addr = 0; @@ -565,3 +583,4 @@ int irc::sockets::insp_aton(const char* a, insp_inaddr* n) return inet_pton(AF_FAMILY, a, n); } +