diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-09-01 15:07:11 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-09-01 15:07:11 +0000 |
commit | 5f4095e595fe36c6f83df96b7c59cb459b966ed3 (patch) | |
tree | 868b4a7d1f9bfcf3b85d9679fd7cbe48c6cc2005 | |
parent | a64a4665e0a2898ec08cf5996bdbf63c2567310e (diff) |
Change IP address storage in User to use more IPv4/IPv6 common code
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11575 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | include/usermanager.h | 2 | ||||
-rw-r--r-- | include/users.h | 18 | ||||
-rw-r--r-- | src/listensocket.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_cgiirc.cpp | 12 | ||||
-rw-r--r-- | src/modules/m_cloaking.cpp | 8 | ||||
-rw-r--r-- | src/modules/m_connectban.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_spanningtree/uid.cpp | 5 | ||||
-rw-r--r-- | src/user_resolver.cpp | 17 | ||||
-rw-r--r-- | src/usermanager.cpp | 24 | ||||
-rw-r--r-- | src/users.cpp | 113 |
10 files changed, 63 insertions, 140 deletions
diff --git a/include/usermanager.h b/include/usermanager.h index 01547029e..c2f89729a 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, sockaddr* ip, const std::string &targetip); + void AddUser(InspIRCd* Instance, int socket, int port, bool iscached, irc::sockets::sockaddrs* ip, const std::string &targetip); /** Disconnect a user gracefully * @param user The user to remove diff --git a/include/users.h b/include/users.h index 175ad0d0f..0964de9b9 100644 --- a/include/users.h +++ b/include/users.h @@ -472,28 +472,22 @@ class CoreExport User : public EventHandler */ bool quitting; - /** IPV4 or IPV6 ip address. Use SetSockAddr to set this and GetProtocolFamily/ - * GetIPString/GetPort to obtain its values. + /** IPV4 or IPV6 ip address, binary format. Use SetSockAddr to set this and + * GetIPString/GetPort to obtain its value in a readable manner */ - sockaddr* ip; + irc::sockets::sockaddrs ip; /** Initialize the clients sockaddr - * @param protocol_family The protocol family of the IP address, AF_INET or AF_INET6 - * @param ip A human-readable IP address for this user matching the protcol_family - * @param port The port number of this user or zero for a remote user + * @param ip A human-readable IP address for this user + * @param port The port number of this user (zero if unknown) */ - void SetSockAddr(int protocol_family, const char* ip, int port); + void SetSockAddr(const char* ip, int port); /** Get port number from sockaddr * @return The port number of this user. */ int GetPort(); - /** Get protocol family from sockaddr - * @return The protocol family of this user, either AF_INET or AF_INET6 - */ - int GetProtocolFamily(); - /** Get IP string from sockaddr, using static internal buffer * @return The IP string */ diff --git a/src/listensocket.cpp b/src/listensocket.cpp index 0145f86d8..452925bf3 100644 --- a/src/listensocket.cpp +++ b/src/listensocket.cpp @@ -154,5 +154,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, &client.sa, ipconnectedto); + ServerInstance->Users->AddUser(ServerInstance, nfd, bind_port, false, &client, ipconnectedto); } diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index 580060464..048f8bde0 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -117,7 +117,7 @@ class CGIResolver : public Resolver them->host.assign(result,0, 64); them->dhost.assign(result, 0, 64); if (querytype) - them->SetSockAddr(them->GetProtocolFamily(), result.c_str(), them->GetPort()); + them->SetSockAddr(result.c_str(), them->GetPort()); them->ident.assign("~cgiirc", 0, 8); them->InvalidateCache(); them->CheckLines(true); @@ -318,7 +318,7 @@ public: if(user->GetExt("cgiirc_webirc_ip", webirc_ip)) { ServerInstance->Users->RemoveCloneCounts(user); - user->SetSockAddr(user->GetProtocolFamily(), webirc_ip->c_str(), user->GetPort()); + user->SetSockAddr(webirc_ip->c_str(), user->GetPort()); delete webirc_ip; user->InvalidateCache(); user->Shrink("cgiirc_webirc_ip"); @@ -342,10 +342,10 @@ public: bool valid = false; ServerInstance->Users->RemoveCloneCounts(user); #ifdef IPV6 - if (user->GetProtocolFamily() == AF_INET6) - valid = (inet_pton(AF_INET6, user->password.c_str(), &((sockaddr_in6*)user->ip)->sin6_addr) > 0); + if (user->ip.sa.sa_family == AF_INET6) + valid = (inet_pton(AF_INET6, user->password.c_str(), &user->ip.in6.sin6_addr) > 0); else - valid = (inet_aton(user->password.c_str(), &((sockaddr_in*)user->ip)->sin_addr)); + valid = (inet_aton(user->password.c_str(), &user->ip.in4.sin_addr)); #else if (inet_aton(user->password.c_str(), &((sockaddr_in*)user->ip)->sin_addr)) valid = true; @@ -407,7 +407,7 @@ public: user->Extend("cgiirc_realhost", new std::string(user->host)); user->Extend("cgiirc_realip", new std::string(user->GetIPString())); ServerInstance->Users->RemoveCloneCounts(user); - user->SetSockAddr(user->GetProtocolFamily(), newip, user->GetPort()); + user->SetSockAddr(newip, user->GetPort()); ServerInstance->Users->AddLocalClone(user); ServerInstance->Users->AddGlobalClone(user); user->CheckClass(); diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp index 59dd008af..29a5e1421 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -413,10 +413,10 @@ class ModuleCloaking : public Module #ifdef IPV6 in6_addr testaddr; in_addr testaddr2; - if ((dest->GetProtocolFamily() == AF_INET6) && (inet_pton(AF_INET6,dest->host.c_str(),&testaddr) < 1) && (hostcloak.length() <= 64)) + if ((dest->ip.sa.sa_family == AF_INET6) && (inet_pton(AF_INET6,dest->host.c_str(),&testaddr) < 1) && (hostcloak.length() <= 64)) /* Invalid ipv6 address, and ipv6 user (resolved host) */ b = hostcloak; - else if ((dest->GetProtocolFamily() == AF_INET) && (inet_aton(dest->host.c_str(),&testaddr2) < 1) && (hostcloak.length() <= 64)) + else if ((dest->ip.sa.sa_family == AF_INET) && (inet_aton(dest->host.c_str(),&testaddr2) < 1) && (hostcloak.length() <= 64)) /* Invalid ipv4 address, and ipv4 user (resolved host) */ b = hostcloak; else @@ -435,10 +435,10 @@ class ModuleCloaking : public Module else { #ifdef IPV6 - if (dest->GetProtocolFamily() == AF_INET6) + if (dest->ip.sa.sa_family == AF_INET6) b = cu->Cloak6(dest->GetIPString()); + else #endif - if (dest->GetProtocolFamily() == AF_INET) b = cu->Cloak4(dest->GetIPString()); } diff --git a/src/modules/m_connectban.cpp b/src/modules/m_connectban.cpp index 524edb8a5..a00fc6733 100644 --- a/src/modules/m_connectban.cpp +++ b/src/modules/m_connectban.cpp @@ -72,7 +72,7 @@ class ModuleConnectBan : public Module int range = 32; clonemap::iterator i; - switch (u->GetProtocolFamily()) + switch (u->ip.sa.sa_family) { case AF_INET6: range = ipv6_cidr; diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp index 40f8e18ab..5b155e188 100644 --- a/src/modules/m_spanningtree/uid.cpp +++ b/src/modules/m_spanningtree/uid.cpp @@ -157,10 +157,7 @@ bool TreeSocket::ParseUID(const std::string &source, std::deque<std::string> &pa if (params[8][0] != '+') params[8] = "+" + params[8]; - if (params[6].find_first_of(":") != std::string::npos) - _new->SetSockAddr(AF_INET6, params[6].c_str(), 0); - else - _new->SetSockAddr(AF_INET, params[6].c_str(), 0); + _new->SetSockAddr(params[6].c_str(), 0); ServerInstance->Users->AddGlobalClone(_new); diff --git a/src/user_resolver.cpp b/src/user_resolver.cpp index 0213a3cbf..95fa13eaf 100644 --- a/src/user_resolver.cpp +++ b/src/user_resolver.cpp @@ -35,11 +35,10 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl, { bool lcached = false; #ifdef IPV6 - if (this->bound_user->GetProtocolFamily() == AF_INET6) + if (this->bound_user->ip.sa.sa_family == AF_INET6) { - /* IPV6 forward lookup (with possibility of 4in6) */ - const char* ip = this->bound_user->GetIPString(); - res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, (!strncmp(ip, "0::ffff:", 8) ? DNS_QUERY_A : DNS_QUERY_AAAA), lcached); + /* IPV6 forward lookup */ + res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, DNS_QUERY_AAAA, lcached); } else /* IPV4 lookup (mixed protocol mode) */ @@ -60,16 +59,15 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl, { /* Both lookups completed */ - sockaddr* user_ip = this->bound_user->ip; + irc::sockets::sockaddrs* user_ip = &this->bound_user->ip; bool rev_match = false; #ifdef IPV6 - if (user_ip->sa_family == AF_INET6) + if (user_ip->sa.sa_family == AF_INET6) { struct in6_addr res_bin; if (inet_pton(AF_INET6, result.c_str(), &res_bin)) { - sockaddr_in6* user_ip6 = reinterpret_cast<sockaddr_in6*>(user_ip); - rev_match = !memcmp(&user_ip6->sin6_addr, &res_bin, sizeof(res_bin)); + rev_match = !memcmp(&user_ip->in6.sin6_addr, &res_bin, sizeof(res_bin)); } } else @@ -78,8 +76,7 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl, struct in_addr res_bin; if (inet_pton(AF_INET, result.c_str(), &res_bin)) { - sockaddr_in* user_ip4 = reinterpret_cast<sockaddr_in*>(user_ip); - rev_match = !memcmp(&user_ip4->sin_addr, &res_bin, sizeof(res_bin)); + rev_match = !memcmp(&user_ip->in4.sin_addr, &res_bin, sizeof(res_bin)); } } diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 0ebf1f6c7..14f022972 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, sockaddr* ip, const std::string &targetip) +void UserManager::AddUser(InspIRCd* Instance, int socket, int port, bool iscached, irc::sockets::sockaddrs* 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. @@ -35,16 +35,8 @@ void UserManager::AddUser(InspIRCd* Instance, int socket, int port, bool iscache return; } - char ipaddr[MAXBUF]; -#ifdef IPV6 - 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(ip->sa_family, ipaddr, port); + memcpy(&New->ip, ip, sizeof(*ip)); /* Give each of the modules an attempt to hook the user for I/O */ FOREACH_MOD_I(Instance, I_OnHookUserIO, OnHookUserIO(New, targetip)); @@ -53,7 +45,7 @@ void UserManager::AddUser(InspIRCd* Instance, int socket, int port, bool iscache { try { - New->GetIOHook()->OnRawSocketAccept(socket, ipaddr, port); + New->GetIOHook()->OnRawSocketAccept(socket, New->GetIPString(), port); } catch (CoreException& modexcept) { @@ -220,7 +212,7 @@ void UserManager::AddLocalClone(User *user) { int range = 32; clonemap::iterator x; - switch (user->GetProtocolFamily()) + switch (user->ip.sa.sa_family) { case AF_INET6: range = ServerInstance->Config->c_ipv6_range; @@ -241,7 +233,7 @@ void UserManager::AddGlobalClone(User *user) { int range = 32; clonemap::iterator x; - switch (user->GetProtocolFamily()) + switch (user->ip.sa.sa_family) { case AF_INET6: range = ServerInstance->Config->c_ipv6_range; @@ -261,7 +253,7 @@ void UserManager::AddGlobalClone(User *user) void UserManager::RemoveCloneCounts(User *user) { int range = 32; - switch (user->GetProtocolFamily()) + switch (user->ip.sa.sa_family) { case AF_INET6: range = ServerInstance->Config->c_ipv6_range; @@ -295,7 +287,7 @@ void UserManager::RemoveCloneCounts(User *user) unsigned long UserManager::GlobalCloneCount(User *user) { int range = 32; - switch (user->GetProtocolFamily()) + switch (user->ip.sa.sa_family) { case AF_INET6: range = ServerInstance->Config->c_ipv6_range; @@ -314,7 +306,7 @@ unsigned long UserManager::GlobalCloneCount(User *user) unsigned long UserManager::LocalCloneCount(User *user) { int range = 32; - switch (user->GetProtocolFamily()) + switch (user->ip.sa.sa_family) { case AF_INET6: range = ServerInstance->Config->c_ipv6_range; diff --git a/src/users.cpp b/src/users.cpp index f210ed470..44dd9b0f2 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -107,9 +107,7 @@ void User::StartDNSLookup() const char* sip = this->GetIPString(); UserResolver *res_reverse; - QueryType resolvtype = strchr(sip, ':') ? DNS_QUERY_PTR6 : DNS_QUERY_PTR4; - // when GetProtocolFamily() works correctly with 4in6, this can be replaced by - // this->GetProtocolFamily() == AF_INET ? DNS_QUERY_PTR4 : DNS_QUERY_PTR6; + QueryType resolvtype = this->ip.sa.sa_family == AF_INET6 ? DNS_QUERY_PTR6 : DNS_QUERY_PTR4; res_reverse = new UserResolver(this->ServerInstance, this, sip, resolvtype, cached); this->ServerInstance->AddResolver(res_reverse, cached); @@ -215,10 +213,10 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance bytes_in = bytes_out = cmds_in = cmds_out = 0; quietquit = quitting = exempt = haspassed = dns_done = false; fd = -1; + ip.sa.sa_family = AF_UNSPEC; recvq.clear(); sendq.clear(); Visibility = NULL; - ip = NULL; MyClass = NULL; AllowedPrivs = AllowedOperCommands = NULL; chans.clear(); @@ -264,20 +262,9 @@ User::~User() this->InvalidateCache(); this->DecrementModes(); - if (ip) - { + if (ip.sa.sa_family != AF_UNSPEC) ServerInstance->Users->RemoveCloneCounts(this); - if (this->GetProtocolFamily() == AF_INET) - { - delete (sockaddr_in*)ip; - } - else - { - delete (sockaddr_in6*)ip; - } - } - ServerInstance->Users->uuidlist->erase(uuid); } @@ -1072,77 +1059,44 @@ bool User::ForceNickChange(const char* newnick) return false; } -void User::SetSockAddr(int protocol_family, const char* sip, int port) +void User::SetSockAddr(const char* sip, int port) { this->cachedip = ""; - switch (protocol_family) + if (inet_pton(AF_INET, sip, &ip.in4.sin_addr)) { - case AF_INET6: - { - sockaddr_in6* sin = new sockaddr_in6; - sin->sin6_family = AF_INET6; - sin->sin6_port = port; - inet_pton(AF_INET6, sip, &sin->sin6_addr); - this->ip = (sockaddr*)sin; - } - break; - case AF_INET: - { - sockaddr_in* sin = new sockaddr_in; - sin->sin_family = AF_INET; - sin->sin_port = port; - inet_pton(AF_INET, sip, &sin->sin_addr); - this->ip = (sockaddr*)sin; - } - break; - default: - ServerInstance->Logs->Log("USERS",DEBUG,"Uh oh, I dont know protocol %d to be set on '%s'!", protocol_family, this->nick.c_str()); - break; + ip.in4.sin_family = AF_INET; + ip.in4.sin_port = port; + return; + } + else if (inet_pton(AF_INET6, sip, &ip.in6.sin6_addr)) + { + ip.in6.sin6_family = AF_INET6; + ip.in6.sin6_port = port; + } + else + { + ServerInstance->Logs->Log("USERS",DEBUG,"Uh oh, I dont know how to read IP '%s' on '%s'!", + sip, this->nick.c_str()); } } int User::GetPort() { - if (this->ip == NULL) - return 0; - - switch (this->GetProtocolFamily()) + switch (this->ip.sa.sa_family) { case AF_INET6: - { - sockaddr_in6* sin = (sockaddr_in6*)this->ip; - return sin->sin6_port; - } - break; + return this->ip.in6.sin6_port; case AF_INET: - { - sockaddr_in* sin = (sockaddr_in*)this->ip; - return sin->sin_port; - } - break; - default: - break; + return this->ip.in4.sin_port; } return 0; } -int User::GetProtocolFamily() -{ - if (this->ip == NULL) - return 0; - - sockaddr_in* sin = (sockaddr_in*)this->ip; - return sin->sin_family; -} - const char* User::GetCIDRMask(int range) { static char buf[44]; - if (this->ip == NULL) - return ""; - if (range < 0) throw "Negative range, sorry, no."; @@ -1150,22 +1104,18 @@ const char* User::GetCIDRMask(int range) * Original code written by Oliver Lupton (Om). * Integrated by me. Thanks. :) -- w00t */ - switch (this->GetProtocolFamily()) + switch (this->ip.sa.sa_family) { case AF_INET6: { /* unsigned char s6_addr[16]; */ struct in6_addr v6; - sockaddr_in6* sin; int i, bytestozero, extrabits; char buffer[40]; if(range > 128) throw "CIDR mask width greater than address width (IPv6, 128 bit)"; - /* Access the user's IP structure directly */ - sin = (sockaddr_in6*)this->ip; - /* To create the CIDR mask we want to set all the bits after 'range' bits of the address * to zero. This means the last (128 - range) bits of the address must be set to zero. * Hence this number divided by 8 is the number of whole bytes from the end of the address @@ -1184,7 +1134,7 @@ const char* User::GetCIDRMask(int range) */ for(i = 0; i < (16 - bytestozero); i++) { - v6.s6_addr[i] = sin->sin6_addr.s6_addr[i]; + v6.s6_addr[i] = ip.in6.sin6_addr.s6_addr[i]; } /* And zero all the remaining bytes in the IP. */ @@ -1203,15 +1153,13 @@ const char* User::GetCIDRMask(int range) case AF_INET: { struct in_addr v4; - sockaddr_in* sin; char buffer[16]; if (range > 32) throw "CIDR mask width greater than address width (IPv4, 32 bit)"; /* Users already have a sockaddr* pointer (User::ip) which contains either a v4 or v6 structure */ - sin = (sockaddr_in*)this->ip; - v4.s_addr = sin->sin_addr.s_addr; + v4.s_addr = ip.in4.sin_addr.s_addr; /* To create the CIDR mask we want to set all the bits after 'range' bits of the address * to zero. This means the last (32 - range) bits of the address must be set to zero. @@ -1245,20 +1193,16 @@ const char* User::GetIPString() { static char buf[40]; - if (this->ip == NULL) - return ""; - if (!this->cachedip.empty()) return this->cachedip.c_str(); - switch (this->GetProtocolFamily()) + switch (this->ip.sa.sa_family) { case AF_INET6: { - static char temp[1024]; + static char temp[41]; - sockaddr_in6* sin = (sockaddr_in6*)this->ip; - inet_ntop(sin->sin6_family, &sin->sin6_addr, buf, sizeof(buf)); + inet_ntop(ip.in6.sin6_family, &ip.in6.sin6_addr, buf, sizeof(buf)); /* IP addresses starting with a : on irc are a Bad Thing (tm) */ if (*buf == ':') { @@ -1274,8 +1218,7 @@ const char* User::GetIPString() break; case AF_INET: { - sockaddr_in* sin = (sockaddr_in*)this->ip; - inet_ntop(sin->sin_family, &sin->sin_addr, buf, sizeof(buf)); + inet_ntop(ip.in4.sin_family, &ip.in4.sin_addr, buf, sizeof(buf)); this->cachedip = buf; return buf; } |