llhost.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llhost.h"
00035 
00036 #include "llerror.h"
00037 
00038 #if LL_WINDOWS
00039         #define WIN32_LEAN_AND_MEAN
00040         #include <winsock2.h>
00041 #else
00042         #include <netdb.h>
00043         #include <netinet/in.h> // ntonl()
00044         #include <sys/types.h>
00045         #include <sys/socket.h>
00046         #include <arpa/inet.h>
00047 #endif
00048 
00049 LLHost LLHost::invalid(INVALID_PORT,INVALID_HOST_IP_ADDRESS);
00050 
00051 LLHost::LLHost(const std::string& ip_and_port)
00052 {
00053         std::string::size_type colon_index = ip_and_port.find(":");
00054         if (colon_index == std::string::npos)
00055         {
00056                 mIP = ip_string_to_u32(ip_and_port.c_str());
00057                 mPort = 0;
00058         }
00059         else
00060         {
00061                 std::string ip_str(ip_and_port, 0, colon_index);
00062                 std::string port_str(ip_and_port, colon_index+1);
00063 
00064                 mIP = ip_string_to_u32(ip_str.c_str());
00065                 mPort = atol(port_str.c_str());
00066         }
00067 }
00068 
00069 void LLHost::getString(char* buffer, S32 length) const
00070 {
00071         if (((U32) length) < MAXADDRSTR + 1 + 5)
00072         {
00073                 llerrs << "LLHost::getString - string too short" << llendl;
00074                 return;
00075         }
00076 
00077         snprintf(buffer, length, "%s:%u", u32_to_ip_string(mIP), mPort);        /* Flawfinder: ignore */
00078 }
00079 
00080 void LLHost::getIPString(char* buffer, S32 length) const
00081 {
00082         if ( ((U32) length) < MAXADDRSTR)
00083         {
00084                 llerrs << "LLHost::getIPString - string too short" << llendl;
00085                 return;
00086         }
00087 
00088         snprintf(buffer, length, "%s", u32_to_ip_string(mIP));  /* Flawfinder: ignore */
00089 }
00090 
00091 
00092 std::string LLHost::getIPandPort() const
00093 {
00094         char buffer[MAXADDRSTR + 1 + 5];        /*Flawfinder: ignore*/
00095         getString(buffer, sizeof(buffer));
00096         return buffer;
00097 }
00098 
00099 
00100 std::string LLHost::getIPString() const
00101 {
00102         return std::string( u32_to_ip_string( mIP ) );
00103 }
00104 
00105 
00106 void LLHost::getHostName(char *buf, S32 len) const
00107 {
00108         hostent *he;
00109 
00110         if (INVALID_HOST_IP_ADDRESS == mIP)
00111         {
00112                 llwarns << "LLHost::getHostName() : Invalid IP address" << llendl;
00113                 buf[0] = '\0';
00114                 return;
00115         }
00116         he = gethostbyaddr((char *)&mIP, sizeof(mIP), AF_INET);
00117         if (!he)
00118         {
00119 #if LL_WINDOWS
00120                 llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " 
00121                         << WSAGetLastError() << llendl;
00122 #else
00123                 llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " 
00124                         << h_errno << llendl;
00125 #endif
00126                 buf[0] = '\0';                                          
00127         }
00128         else
00129         {
00130                 strncpy(buf, he->h_name, len); /*Flawfinder: ignore*/
00131                 buf[len-1] = '\0';
00132         }
00133 }
00134 
00135 std::string LLHost::getHostName() const
00136 {
00137         hostent* he;
00138         if (INVALID_HOST_IP_ADDRESS == mIP)
00139         {
00140                 llwarns << "LLHost::getHostName() : Invalid IP address" << llendl;
00141                 return std::string();
00142         }
00143         he = gethostbyaddr((char *)&mIP, sizeof(mIP), AF_INET);
00144         if (!he)
00145         {
00146 #if LL_WINDOWS
00147                 llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " 
00148                         << WSAGetLastError() << llendl;
00149 #else
00150                 llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " 
00151                         << h_errno << llendl;
00152 #endif
00153                 return std::string();
00154         }
00155         else
00156         {
00157                 return ll_safe_string(he->h_name);
00158         }
00159 }
00160 
00161 BOOL LLHost::setHostByName(const char *string)
00162 {
00163         hostent *he;
00164         char local_name[MAX_STRING];  /*Flawfinder: ignore*/
00165 
00166         if (strlen(string)+1 > MAX_STRING) /*Flawfinder: ignore*/
00167         {
00168                 llerrs << "LLHost::setHostByName() : Address string is too long: " 
00169                         << string << llendl;
00170         }
00171 
00172         strncpy(local_name, string,MAX_STRING);  /*Flawfinder: ignore*/
00173         local_name[MAX_STRING-1] = '\0';
00174 #if LL_WINDOWS
00175         // We may need an equivalent for Linux, but not sure - djs
00176         _strupr(local_name);
00177 #endif
00178 
00179         he = gethostbyname(local_name); 
00180         if(!he) 
00181         {
00182                 U32 ip_address = inet_addr(string);
00183                 he = gethostbyaddr((char *)&ip_address, sizeof(ip_address), AF_INET);
00184         }
00185 
00186         if (he)
00187         {
00188                 mIP = *(U32 *)he->h_addr_list[0];
00189                 return TRUE;
00190         }
00191         else 
00192         {
00193                 setAddress(local_name);
00194 
00195                 // In windows, h_errno is a macro for WSAGetLastError(), so store value here
00196                 S32 error_number = h_errno;
00197                 switch(error_number) 
00198                 {
00199                         case TRY_AGAIN: // XXX how to handle this case? 
00200                                 llwarns << "LLHost::setAddress(): try again" << llendl;
00201                                 break;
00202                         case HOST_NOT_FOUND:
00203                         case NO_ADDRESS:        // NO_DATA
00204                                 llwarns << "LLHost::setAddress(): host not found" << llendl;
00205                                 break;
00206                         case NO_RECOVERY:
00207                                 llwarns << "LLHost::setAddress(): unrecoverable error" << llendl;
00208                                 break;
00209                         default:
00210                                 llwarns << "LLHost::setAddress(): unknown error - " << error_number << llendl;
00211                                 break;
00212                 }
00213                 return FALSE;
00214         }
00215 }
00216 
00217 LLHost& LLHost::operator=(const LLHost &rhs)
00218 { 
00219         if (this != &rhs)
00220         {
00221                 set(rhs.getAddress(), rhs.getPort());
00222         }
00223         return *this;           
00224 }
00225 
00226 
00227 std::ostream& operator<< (std::ostream& os, const LLHost &hh)
00228 {
00229         os << u32_to_ip_string(hh.mIP) << ":" << hh.mPort ;
00230         return os;
00231 }
00232 
00233 
00234 //std::istream& operator>> (std::istream& is, LLHost &rh)
00235 //{
00236 //      is >> rh.mIP;
00237 //    is >> rh.mPort;
00238 //    return is;
00239 //}

Generated on Fri May 16 08:32:25 2008 for SecondLife by  doxygen 1.5.5