From 1b128373c2acb747c3827cdfd9c1863fb8492d62 Mon Sep 17 00:00:00 2001 From: brain Date: Mon, 5 Feb 2007 22:29:02 +0000 Subject: Not safe for use yet git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@6502 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/socket.h | 1 + include/users.h | 2 +- src/socket.cpp | 68 +++++++++++++++++++++++++++++++++++++++----------------- src/users.cpp | 12 ++++++++-- 4 files changed, 59 insertions(+), 24 deletions(-) diff --git a/include/socket.h b/include/socket.h index eebc172cf..63546f887 100644 --- a/include/socket.h +++ b/include/socket.h @@ -151,6 +151,7 @@ class ListenSocket : public EventHandler */ InspIRCd* ServerInstance; std::string desc; + int family; public: /** Create a new listening socket */ diff --git a/include/users.h b/include/users.h index 487bbb2ba..709f4b739 100644 --- a/include/users.h +++ b/include/users.h @@ -708,7 +708,7 @@ class userrec : public connection * @param ip The IP address of the user * @return This function has no return value, but a call to AddClient may remove the user. */ - static void AddClient(InspIRCd* Instance, int socket, int port, bool iscached, insp_inaddr ip); + static void AddClient(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip); /** Oper down. * This will clear the +o usermode and unset the user's oper type diff --git a/src/socket.cpp b/src/socket.cpp index dd52bb33a..111299b09 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -42,6 +42,14 @@ ListenSocket::ListenSocket(InspIRCd* Instance, int sockfd, insp_sockaddr client, Instance->Log(DEBUG,"CRAP"); if (!Instance->BindSocket(this->fd,client,server,port,addr)) this->fd = -1; +#ifdef IPV6 + if ((!*addr) || (strchr(addr,':'))) + this->family = AF_INET6; + else + this->family = AF_INET; +#else + this->family = AF_INET; +#endif } ListenSocket::~ListenSocket() @@ -56,32 +64,52 @@ ListenSocket::~ListenSocket() void ListenSocket::HandleEvent(EventType et, int errornum) { - insp_sockaddr sock_us; // our port number - socklen_t uslen; // length of our port number - insp_sockaddr client; - socklen_t length; + sockaddr* sock_us = new sockaddr[2]; // our port number + sockaddr* client = new sockaddr[2]; + socklen_t uslen, length; // length of our port number int incomingSockfd, in_port; - uslen = sizeof(sock_us); - length = sizeof(client); - incomingSockfd = accept (this->GetFd(),(struct sockaddr*)&client, &length); - - if ((incomingSockfd > -1) && (!getsockname(incomingSockfd, (sockaddr*)&sock_us, &uslen))) + +#ifdef IPV6 + if (this->family == AF_INET6) + { + uslen = sizeof(sockaddr_in6); + length = sizeof(sockaddr_in6); + } + else + { + uslen = sizeof(sockaddr_in); + length = sizeof(sockaddr_in); + } +#else + uslen = sizeof(sockaddr_in); + length = sizeof(sockaddr_in); +#endif + incomingSockfd = accept (this->GetFd(), (sockaddr*)client, &length); + + if ((incomingSockfd > -1) && (!getsockname(incomingSockfd, sock_us, &uslen))) { + char buf[MAXBUF]; #ifdef IPV6 - in_port = ntohs(sock_us.sin6_port); + if (this->family == AF_INET6) + { + inet_ntop(AF_INET6, &((const sockaddr_in6*)client)->sin6_addr, buf, sizeof(buf)); + in_port = ntohs(((sockaddr_in6*)sock_us)->sin6_port); + } + else + { + inet_ntop(AF_INET, &((const sockaddr_in*)client)->sin_addr, buf, sizeof(buf)); + in_port = ntohs(((sockaddr_in*)sock_us)->sin_port); + } #else - in_port = ntohs(sock_us.sin_port); + inet_ntop(AF_INET, &((const sockaddr_in*)client)->sin_addr, buf, sizeof(buf)); + in_port = ntohs(((sockaddr_in*)sock_us)->sin_port); #endif NonBlocking(incomingSockfd); if (ServerInstance->Config->GetIOHook(in_port)) { try { -#ifdef IPV6 - ServerInstance->Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, insp_ntoa(client.sin6_addr), in_port); -#else - ServerInstance->Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, insp_ntoa(client.sin_addr), in_port); -#endif + ServerInstance->Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, buf, in_port); } catch (CoreException& modexcept) { @@ -89,11 +117,7 @@ void ListenSocket::HandleEvent(EventType et, int errornum) } } ServerInstance->stats->statsAccept++; -#ifdef IPV6 - userrec::AddClient(ServerInstance, incomingSockfd, in_port, false, client.sin6_addr); -#else - userrec::AddClient(ServerInstance, incomingSockfd, in_port, false, client.sin_addr); -#endif + userrec::AddClient(ServerInstance, incomingSockfd, in_port, false, this->family, client); } else { @@ -101,6 +125,8 @@ void ListenSocket::HandleEvent(EventType et, int errornum) close(incomingSockfd); ServerInstance->stats->statsRefused++; } + delete[] client; + delete[] sock_us; } /* Match raw bytes using CIDR bit matching, used by higher level MatchCIDR() */ diff --git a/src/users.cpp b/src/users.cpp index b42eb5e00..f47c33011 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -802,11 +802,19 @@ void userrec::AddToWhoWas() } /* add a client connection to the sockets list */ -void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, insp_inaddr ip) +void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip) { std::string tempnick = ConvToStr(socket) + "-unknown"; user_hash::iterator iter = Instance->clientlist->find(tempnick); - const char *ipaddr = insp_ntoa(ip); + char ipaddr[MAXBUF]; +#ifdef IPV6 + if (socketfamily = AF_INET6) + inet_ntop(AF_INET6, &((const sockaddr_in6*)ip)->sin6_addr, ipaddr, sizeof(ipaddr)); + else + inet_ntop(AF_INET, &((const sockaddr_in*)ip)->sin_addr, ipaddr, sizeof(ipaddr)); +#else + inet_ntop(AF_INET, &((const sockaddr_in*)ip)->sin_addr, ipaddr, sizeof(ipaddr)); +#endif userrec* New; int j = 0; -- cgit v1.2.3