summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorw00t <w00t@e03df62e-2008-0410-955e-edbf42e46eb7>2008-11-01 20:20:11 +0000
committerw00t <w00t@e03df62e-2008-0410-955e-edbf42e46eb7>2008-11-01 20:20:11 +0000
commitab65273f9ff40c0761514d1067b6631ec5a0e422 (patch)
tree7c2d1f1694c348debff372c440510bc6129d9434
parent73de881eafbd3d201ce4be472bd35349773d74bd (diff)
Simulate AF_INET addresses for 4in6 connections [danieldg]
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@10779 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/usermanager.h2
-rw-r--r--src/listensocket.cpp19
-rw-r--r--src/usermanager.cpp6
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));