diff options
-rw-r--r-- | include/usermanager.h | 2 | ||||
-rw-r--r-- | src/listensocket.cpp | 19 | ||||
-rw-r--r-- | src/usermanager.cpp | 6 |
3 files changed, 17 insertions, 10 deletions
diff --git a/include/usermanager.h b/include/usermanager.h index 6ec80c9db..2eb7fc0b9 100644 --- a/include/usermanager.h +++ b/include/usermanager.h @@ -78,7 +78,7 @@ class CoreExport UserManager : public Extensible * @param ip The IP address of the user * @return This function has no return value, but a call to AddClient may remove the user. */ - void AddUser(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip, const std::string &targetip); + void AddUser(InspIRCd* Instance, int socket, int port, bool iscached, sockaddr* ip, const std::string &targetip); /** Disconnect a user gracefully * @param user The user to remove diff --git a/src/listensocket.cpp b/src/listensocket.cpp index 86d36cce0..6fa6785bd 100644 --- a/src/listensocket.cpp +++ b/src/listensocket.cpp @@ -120,7 +120,7 @@ void ListenSocketBase::AcceptInternal() } static char buf[MAXBUF]; - static char target[MAXBUF]; + static char target[MAXBUF]; *target = *buf = '\0'; @@ -133,13 +133,20 @@ void ListenSocketBase::AcceptInternal() 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)); - if (!strncmp(buf, "::ffff:", 7)) + + static const unsigned char prefix4in6[12] = { 0,0,0,0, 0,0,0,0, 0,0,0xFF,0xFF }; + if (!memcmp(prefix4in6, &((const sockaddr_in6*)client)->sin6_addr, 12)) { + // strip leading ::ffff: from the IPs memmove(buf, buf+7, sizeof(buf)-7); - } - if (!strncmp(target, "::ffff:", 7)) - { memmove(target, target+7, sizeof(target)-7); + + // recreate as a sockaddr_in using the IPv4 IP + uint16_t sport = ((const sockaddr_in6*)client)->sin6_port; + struct sockaddr_in* clientv4 = (struct sockaddr_in*)client; + clientv4->sin_family = AF_INET; + clientv4->sin_port = sport; + inet_pton(AF_INET, buf, &clientv4->sin_addr); } } else @@ -176,5 +183,5 @@ void ListenSocketBase::HandleEvent(EventType e, int err) void ClientListenSocket::OnAcceptReady(const std::string &ipconnectedto, int nfd, const std::string &incomingip) { - ServerInstance->Users->AddUser(ServerInstance, nfd, bind_port, false, this->family, client, ipconnectedto); + ServerInstance->Users->AddUser(ServerInstance, nfd, bind_port, false, client, ipconnectedto); } diff --git a/src/usermanager.cpp b/src/usermanager.cpp index e526238ed..521dcec41 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -18,7 +18,7 @@ #include "bancache.h" /* add a client connection to the sockets list */ -void UserManager::AddUser(InspIRCd* Instance, int socket, int port, bool iscached, int socketfamily, sockaddr* ip, const std::string &targetip) +void UserManager::AddUser(InspIRCd* Instance, int socket, int port, bool iscached, sockaddr* ip, const std::string &targetip) { /* NOTE: Calling this one parameter constructor for User automatically * allocates a new UUID and places it in the hash_map. @@ -37,14 +37,14 @@ void UserManager::AddUser(InspIRCd* Instance, int socket, int port, bool iscache char ipaddr[MAXBUF]; #ifdef IPV6 - if (socketfamily == AF_INET6) + if (ip->sa_family == AF_INET6) inet_ntop(AF_INET6, &((const sockaddr_in6*)ip)->sin6_addr, ipaddr, sizeof(ipaddr)); else #endif inet_ntop(AF_INET, &((const sockaddr_in*)ip)->sin_addr, ipaddr, sizeof(ipaddr)); New->SetFd(socket); - New->SetSockAddr(socketfamily, ipaddr, port); + New->SetSockAddr(ip->sa_family, ipaddr, port); /* Give each of the modules an attempt to hook the user for I/O */ FOREACH_MOD_I(Instance, I_OnHookUserIO, OnHookUserIO(New, targetip)); |