X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Flistensocket.cpp;h=82d899bb4d67c3d0742f53bd71c4a5216f3b0392;hb=cb1464555eb711c0fd74e31aadaa9558d9b61b5d;hp=313396ed7829b52a448b61069eaada1df711d274;hpb=50234923b292122bb19296952b947d55b1760c62;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/listensocket.cpp b/src/listensocket.cpp index 313396ed7..82d899bb4 100644 --- a/src/listensocket.cpp +++ b/src/listensocket.cpp @@ -2,7 +2,7 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * InspIRCd: (C) 2002-2008 InspIRCd Development Team + * InspIRCd: (C) 2002-2009 InspIRCd Development Team * See: http://www.inspircd.org/wiki/index.php/Credits * * This program is free but copyrighted software; see @@ -120,7 +120,7 @@ void ListenSocketBase::AcceptInternal() } static char buf[MAXBUF]; - static char target[MAXBUF]; + static char target[MAXBUF]; *target = *buf = '\0'; @@ -128,15 +128,38 @@ void ListenSocketBase::AcceptInternal() if (this->family == AF_INET6) { inet_ntop(AF_INET6, &((const sockaddr_in6*)client)->sin6_addr, buf, sizeof(buf)); - if (!strncmp(buf, "::ffff:", 7)) - { - memmove(buf, buf+7, sizeof(buf)-7); - } socklen_t raddrsz = sizeof(sockaddr_in6); if (getsockname(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)); + + /* + * This case is the be all and end all patch to catch and nuke 4in6 + * instead of special-casing shit all over the place and wreaking merry + * havoc with crap, instead, we just recreate sockaddr and strip ::ffff: prefix + * if it's a 4in6 IP. + * + * This is, of course, much improved over the older way of handling this + * (pretend it doesn't exist + hack around it -- yes, both were done!) + * + * Big, big thanks to danieldg for his work on this. + * -- w00t + */ + 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); + 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 #endif @@ -172,5 +195,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); }