diff --git a/indra/llmessage/llhost.cpp b/indra/llmessage/llhost.cpp index 61a84de8e..9bf94ef3f 100644 --- a/indra/llmessage/llhost.cpp +++ b/indra/llmessage/llhost.cpp @@ -59,11 +59,12 @@ LLHost::LLHost(const std::string& ip_and_port) mIP = ip_string_to_u32(ip_str.c_str()); mPort = atol(port_str.c_str()); } + mHostNotFound = 0; } std::string LLHost::getString() const { - return llformat("%s:%u", u32_to_ip_string(mIP), mPort); + return llformat("%s:%hu", u32_to_ip_string(mIP), mPort); } @@ -87,16 +88,27 @@ std::string LLHost::getHostName() const llwarns << "LLHost::getHostName() : Invalid IP address" << llendl; return std::string(); } + if (mHostNotFound) + { + // We already checked this... avoid freezing the viewer 5 seconds again and again. + llwarns << "LLHost::getHostName() : Returning cached HOST_NOT_FOUND." << llendl; + return std::string(); + } he = gethostbyaddr((char *)&mIP, sizeof(mIP), AF_INET); if (!he) { #if LL_WINDOWS - llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " - << WSAGetLastError() << llendl; + int err = WSAGetLastError(); + int err_host_not_found = WSAHOST_NOT_FOUND; #else - llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " - << h_errno << llendl; + int err = h_errno; + int err_host_not_found = HOST_NOT_FOUND; #endif + llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " << err << llendl; + if (err == err_host_not_found) + { + mHostNotFound = 1; + } return std::string(); } else @@ -125,6 +137,7 @@ BOOL LLHost::setHostByName(const std::string& hostname) if (he) { mIP = *(U32 *)he->h_addr_list[0]; + mHostNotFound = 0; return TRUE; } else diff --git a/indra/llmessage/llhost.h b/indra/llmessage/llhost.h index 0cf52a415..8d7f6be63 100644 --- a/indra/llmessage/llhost.h +++ b/indra/llmessage/llhost.h @@ -38,7 +38,8 @@ const U32 INVALID_HOST_IP_ADDRESS = 0x0; class LLHost { protected: - U32 mPort; + U16 mPort; + mutable U16 mHostNotFound; // Singularity addition; caches a failed IP -> hostname lookup. U32 mIP; public: @@ -47,17 +48,20 @@ public: // CREATORS LLHost() : mPort(INVALID_PORT), + mHostNotFound(1), mIP(INVALID_HOST_IP_ADDRESS) { } // STL's hash_map expect this T() LLHost( U32 ipv4_addr, U32 port ) - : mPort( port ) + : mPort(port), + mHostNotFound(0) { mIP = ipv4_addr; } LLHost( const std::string& ipv4_addr, U32 port ) - : mPort( port ) + : mPort(port), + mHostNotFound(0) { mIP = ip_string_to_u32(ipv4_addr.c_str()); } @@ -68,6 +72,7 @@ public: U32 port = (U32)(ip_port & (U64)0xFFFFFFFF); mIP = ip; mPort = port; + mHostNotFound = 0; } explicit LLHost(const std::string& ip_and_port); @@ -76,15 +81,15 @@ public: { } // MANIPULATORS - void set( U32 ip, U32 port ) { mIP = ip; mPort = port; } - void set( const std::string& ipstr, U32 port ) { mIP = ip_string_to_u32(ipstr.c_str()); mPort = port; } - void setAddress( const std::string& ipstr ) { mIP = ip_string_to_u32(ipstr.c_str()); } - void setAddress( U32 ip ) { mIP = ip; } + void set( U32 ip, U32 port ) { mIP = ip; mPort = port; mHostNotFound = 0; } + void set( const std::string& ipstr, U32 port ) { mIP = ip_string_to_u32(ipstr.c_str()); mPort = port; mHostNotFound = 0; } + void setAddress( const std::string& ipstr ) { mIP = ip_string_to_u32(ipstr.c_str()); mHostNotFound = 0; } + void setAddress( U32 ip ) { mIP = ip; mHostNotFound = 0; } void setPort( U32 port ) { mPort = port; } BOOL setHostByName(const std::string& hname); LLHost& operator=(const LLHost &rhs); - void invalidate() { mIP = INVALID_HOST_IP_ADDRESS; mPort = INVALID_PORT;}; + void invalidate() { mIP = INVALID_HOST_IP_ADDRESS; mPort = INVALID_PORT; mHostNotFound = 1; } // READERS U32 getAddress() const { return mIP; } diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 0e8e97f3a..dc62522cf 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -1071,7 +1071,11 @@ std::string LLViewerParcelMedia::extractDomain(std::string url) url = url.substr(pos + 1, count); } - if (url.find(gAgent.getRegion()->getHost().getHostName()) == 0 || url.find(last_region) == 0) + //Singu note: The call to getHostName() freezes the viewer for a few seconds if the region has no reverse DNS... + // Avoid calling it three times therefore -- not to mention that if it fails, it returns an empty string which + // does NOT mean that it should match the current url as if the current url contains the current regions hostname! + std::string const hostname = gAgent.getRegion()->getHost().getHostName(); + if ((!hostname.empty() && url.find(hostname) == 0) || url.find(last_region) == 0) { // This must be a scripted object rezzed in the region: // extend the concept of "domain" to encompass the @@ -1080,7 +1084,7 @@ std::string LLViewerParcelMedia::extractDomain(std::string url) // Get rid of any port number pos = url.find('/'); // We earlier made sure that there's one - url = gAgent.getRegion()->getHost().getHostName() + url.substr(pos); + url = hostname + url.substr(pos); pos = url.find('?'); if (pos != std::string::npos) @@ -1111,10 +1115,12 @@ std::string LLViewerParcelMedia::extractDomain(std::string url) } } - // Remember this region, so to cope with requests occuring just after a // TP out of it. - last_region = gAgent.getRegion()->getHost().getHostName(); + if (!hostname.empty()) // Singu note: also make sure that last_region doesn't become empty. + { + last_region = hostname; + } return url; }