From 96fd1823351b63a9fbafdb21f1fe356858d305e7 Mon Sep 17 00:00:00 2001 From: depyraken Date: Tue, 29 Mar 2016 02:29:35 +0200 Subject: [PATCH] add isloopbackIPAddress prototype to code/nel/include/nel/net/inet_address.h add isloopbackIPAddress to code/nel/src/net/inet_address.cpp add IPv4&IPv6 loopback IP addresses to localAddresses In code/nel/src/net/unified_network.cpp: replace is127001 calls by isloopbackIPAddress change wrong comments about default network id (nid = 0xFF) When the selected connectionId is not valid warnings are not triggered anymore when using default network (nid = 0xFF): the logs were full of warnings and the server was lagging When nid = 0xFF, the new connectionId is stored into DefaultNetwork When nid <> 0xFF, the new connectionId is stored into NetworkConnectionAssociations[nid] --HG-- branch : develop --- code/nel/include/nel/net/inet_address.h | 9 ++++++ code/nel/src/net/inet_address.cpp | 40 +++++++++++++++++++++---- code/nel/src/net/unified_network.cpp | 29 +++++++++++------- 3 files changed, 61 insertions(+), 17 deletions(-) diff --git a/code/nel/include/nel/net/inet_address.h b/code/nel/include/nel/net/inet_address.h index dcf5b3708..fa75d47f9 100644 --- a/code/nel/include/nel/net/inet_address.h +++ b/code/nel/include/nel/net/inet_address.h @@ -32,6 +32,12 @@ struct in6_addr; #ifdef NL_OS_WINDOWS // automatically add the win socket library if you use nel network part #pragma comment(lib, "ws2_32.lib") + +// it seems that the default loop back address is not defined for ipv6 +#ifndef IN6ADDR_LOOPBACK_INIT +#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } +#endif + #endif namespace NLMISC @@ -137,6 +143,9 @@ public: /// Returns true if this CInetAddress is 127.0.0.1 bool is127001 () const; + /// Returns true if this CInetAddress is a loop back address + bool CInetAddress::isloopbackIPAddress () const; + /// Creates a CInetAddress object with local host address, port=0 static CInetAddress localHost(); diff --git a/code/nel/src/net/inet_address.cpp b/code/nel/src/net/inet_address.cpp index 9dc7f5d00..aaa43ab29 100644 --- a/code/nel/src/net/inet_address.cpp +++ b/code/nel/src/net/inet_address.cpp @@ -700,6 +700,13 @@ std::vector CInetAddress::localAddresses() throw ESocket( "Unable to get local hostname" ); } + // for loopback ipv4 + struct in_addr *psin_addrIPv4 = NULL; + + // for loopback ipv6 + struct in6_addr *psin_addrIPv6 = NULL; + + // 2. Get address list vector vect; @@ -723,16 +730,27 @@ std::vector CInetAddress::localAddresses() while (p != NULL) { // check address family - if (p->ai_family == AF_INET) - { - // ipv4 + if (p->ai_family == AF_INET){ // ipv4 + // loopback ipv4 + if(!psin_addrIPv4){ // add loopback address only once + struct in_addr *psin_addrIPv4 = new in_addr; + psin_addrIPv4->s_addr = htonl(INADDR_LOOPBACK); + vect.push_back(CInetAddress(psin_addrIPv4, localhost)); + } + struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; vect.push_back( CInetAddress( &ipv4->sin_addr, localhost ) ); + } - else if (p->ai_family == AF_INET6) - { - // ipv6 + else if (p->ai_family == AF_INET6){ // ipv6 + // loopback ipv6 + if(!psin_addrIPv6){ // add loopback address only once + struct in6_addr aLoopback6 = IN6ADDR_LOOPBACK_INIT; + psin_addrIPv6 = &aLoopback6; + vect.push_back(CInetAddress(psin_addrIPv6, localhost)); + } + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr; vect.push_back( CInetAddress( &ipv6->sin6_addr, localhost ) ); @@ -758,6 +776,16 @@ bool CInetAddress::is127001 () const return (internalIPAddress () == htonl(0x7F000001)); } +bool CInetAddress::isloopbackIPAddress () const +{ + const char *sIPAddress = ipAddress().c_str(); + + return (strcmp(sIPAddress, "::") == 0) || + (strcmp(sIPAddress, "::1") == 0) || + (strcmp(sIPAddress, "127.0.0.1") == 0) || + (strcmp(sIPAddress, "0:0:0:0:0:0:0:1") == 0); +} + std::string vectorCInetAddressToString(const std::vector &addrs) { diff --git a/code/nel/src/net/unified_network.cpp b/code/nel/src/net/unified_network.cpp index 0f4396ef5..1dedbb119 100644 --- a/code/nel/src/net/unified_network.cpp +++ b/code/nel/src/net/unified_network.cpp @@ -828,17 +828,16 @@ void CUnifiedNetwork::addService(const string &name, const vector for (uint i = 0; i < addr.size(); i++) { // first we have to look if we have a network that can established the connection - + uint j = 0; - // it s 127.0.0.1, it s ok - if (!addr[i].is127001 ()) - { + + if (!addr[i].isloopbackIPAddress ()){ // it 's loopback ip address, it s ok + for (j = 0; j < laddr.size (); j++) { if (laddr[j].internalNetAddress () == addr[i].internalNetAddress ()) { - // it's ok, we can try - break; + break; // it's ok, we can try } } @@ -1272,8 +1271,7 @@ uint8 CUnifiedNetwork::findConnectionId (TServiceId sid, uint8 nid) uint8 connectionId = _IdCnx[sid.get()].DefaultNetwork; if (nid == 0xFF) - { - // it s often happen because they didn't set a good network configuration, so it s in debug to disable it easily + { // default network //nldebug ("HNETL5: nid %hu, will use the default connection %hu", (uint16)nid, (uint16)connectionId); } else if (nid >= _IdCnx[sid.get()].NetworkConnectionAssociations.size()) @@ -1294,8 +1292,9 @@ uint8 CUnifiedNetwork::findConnectionId (TServiceId sid, uint8 nid) if (connectionId >= _IdCnx[sid.get()].Connections.size() || !_IdCnx[sid.get()].Connections[connectionId].valid() || !_IdCnx[sid.get()].Connections[connectionId].CbNetBase->connected()) { - // there's a problem with the selected connectionID, so try to find a valid one - nlwarning ("HNETL5: Can't find selected connection id %hu to send message to %s because connection is not valid or connected, find a valid connection id", (uint16)connectionId, _IdCnx[sid.get()].ServiceName.c_str ()); + + if(nid != 0xFF) // not a default network. There's a problem with the selected connectionID, so try to find a valid one + nlwarning ("HNETL5: Can't find selected connection id %hu to send message to %s because connection is not valid or connected, find a valid connection id", (uint16)connectionId, _IdCnx[sid.get()].ServiceName.c_str ()); for (connectionId = 0; connectionId < _IdCnx[sid.get()].Connections.size(); connectionId++) { @@ -1303,6 +1302,14 @@ uint8 CUnifiedNetwork::findConnectionId (TServiceId sid, uint8 nid) { // we found one at last, use this one //nldebug ("HNETL5: Ok, we found a valid connectionid, use %hu", (uint16)connectionId); + if(nid < _IdCnx[sid.get()].NetworkConnectionAssociations.size()){ + _IdCnx[sid.get()].NetworkConnectionAssociations[nid] = connectionId; // we set the preferred networkConnectionAssociation + } else { + if(nid == 0xFF){ + _IdCnx[sid.get()].DefaultNetwork = connectionId; + } + } + nlwarning ("HNETL5: selected connection id %hu from network %hu to send message to %s", (uint16)connectionId, (uint16)nid, _IdCnx[sid.get()].ServiceName.c_str ()); break; } } @@ -1782,7 +1789,7 @@ bool CUnifiedNetwork::isServiceLocal (TServiceId sid) { for (uint j = 0; j < _IdCnx[sid.get()].ExtAddress.size(); j++) { - if (_IdCnx[sid.get()].ExtAddress[j].is127001 ()) + if (_IdCnx[sid.get()].ExtAddress[j].isloopbackIPAddress ()) return true; if (_IdCnx[sid.get()].ExtAddress[j].internalIPAddress () == laddr[i].internalIPAddress ())