X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Flistensocket.cpp;h=e4b568235b69849f0b9c72d99c36171775de7643;hb=93b0661ddaebc82df76e0268ebe0ab0c17f7cbc7;hp=d6fe2bb1ffada6476f290ea95fc3693edb000bc5;hpb=484b718ccf1505360d62401dd09e3eca6b2568d8;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/listensocket.cpp b/src/listensocket.cpp index d6fe2bb1f..e4b568235 100644 --- a/src/listensocket.cpp +++ b/src/listensocket.cpp @@ -19,20 +19,20 @@ /* 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; +unsigned int ListenSocketBase::socketcount = 0; +sockaddr* ListenSocketBase::sock_us = NULL; +sockaddr* ListenSocketBase::client = NULL; +sockaddr* ListenSocketBase::raddr = NULL; -ListenSocket::ListenSocket(InspIRCd* Instance, int port, char* addr) : ServerInstance(Instance), desc("plaintext"), bind_addr(addr), bind_port(port) +ListenSocketBase::ListenSocketBase(InspIRCd* Instance, int port, const std::string &addr) : ServerInstance(Instance), desc("plaintext"), bind_addr(addr), bind_port(port) { - this->SetFd(irc::sockets::OpenTCPSocket(addr)); + this->SetFd(irc::sockets::OpenTCPSocket(addr.c_str())); if (this->GetFd() > -1) { - if (!Instance->BindSocket(this->fd,port,addr)) + if (!Instance->BindSocket(this->fd,port,addr.c_str())) this->fd = -1; #ifdef IPV6 - if ((!*addr) || (strchr(addr,':'))) + if ((!*addr.c_str()) || (strchr(addr.c_str(),':'))) this->family = AF_INET6; else #endif @@ -51,7 +51,7 @@ ListenSocket::ListenSocket(InspIRCd* Instance, int port, char* addr) : ServerIns socketcount++; } -ListenSocket::~ListenSocket() +ListenSocketBase::~ListenSocketBase() { if (this->GetFd() > -1) { @@ -71,7 +71,7 @@ ListenSocket::~ListenSocket() } /* Just seperated into another func for tidiness really.. */ -void ListenSocket::AcceptInternal() +void ListenSocketBase::AcceptInternal() { ServerInstance->Logs->Log("SOCKET",DEBUG,"HandleEvent for Listensoket"); socklen_t uslen, length; // length of our port number @@ -120,7 +120,7 @@ void ListenSocket::AcceptInternal() } static char buf[MAXBUF]; - static char target[MAXBUF]; + static char target[MAXBUF]; *target = *buf = '\0'; @@ -133,6 +133,33 @@ void ListenSocket::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)); + + /* + * 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 @@ -150,7 +177,7 @@ void ListenSocket::AcceptInternal() this->OnAcceptReady(target, incomingSockfd, buf); } -void ListenSocket::HandleEvent(EventType e, int err) +void ListenSocketBase::HandleEvent(EventType e, int err) { switch (e) { @@ -166,7 +193,7 @@ void ListenSocket::HandleEvent(EventType e, int err) } } -void ListenSocket::OnAcceptReady(const std::string &ipconnectedto, int nfd, const std::string &incomingip) +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); }