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>
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);
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));
00089 }
00090
00091
00092 std::string LLHost::getIPandPort() const
00093 {
00094 char buffer[MAXADDRSTR + 1 + 5];
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);
00131 buf[len-1] = '\0';
00132 }
00133 }
00134
00135 LLString LLHost::getHostName() const
00136 {
00137 hostent *he;
00138
00139 if (INVALID_HOST_IP_ADDRESS == mIP)
00140 {
00141 llwarns << "LLHost::getHostName() : Invalid IP address" << llendl;
00142 return "";
00143 }
00144 he = gethostbyaddr((char *)&mIP, sizeof(mIP), AF_INET);
00145 if (!he)
00146 {
00147 #if LL_WINDOWS
00148 llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: "
00149 << WSAGetLastError() << llendl;
00150 #else
00151 llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: "
00152 << h_errno << llendl;
00153 #endif
00154 return "";
00155 }
00156 else
00157 {
00158 LLString hostname = he->h_name;
00159 return hostname;
00160 }
00161 }
00162
00163 BOOL LLHost::setHostByName(const char *string)
00164 {
00165 hostent *he;
00166 char local_name[MAX_STRING];
00167
00168 if (strlen(string)+1 > MAX_STRING)
00169 {
00170 llerrs << "LLHost::setHostByName() : Address string is too long: "
00171 << string << llendl;
00172 }
00173
00174 strncpy(local_name, string,MAX_STRING);
00175 local_name[MAX_STRING-1] = '\0';
00176 #if LL_WINDOWS
00177
00178 _strupr(local_name);
00179 #endif
00180
00181 he = gethostbyname(local_name);
00182 if(!he)
00183 {
00184 U32 ip_address = inet_addr(string);
00185 he = gethostbyaddr((char *)&ip_address, sizeof(ip_address), AF_INET);
00186 }
00187
00188 if (he)
00189 {
00190 mIP = *(U32 *)he->h_addr_list[0];
00191 return TRUE;
00192 }
00193 else
00194 {
00195 setAddress(local_name);
00196
00197
00198 S32 error_number = h_errno;
00199 switch(error_number)
00200 {
00201 case TRY_AGAIN:
00202 llwarns << "LLHost::setAddress(): try again" << llendl;
00203 break;
00204 case HOST_NOT_FOUND:
00205 case NO_ADDRESS:
00206 llwarns << "LLHost::setAddress(): host not found" << llendl;
00207 break;
00208 case NO_RECOVERY:
00209 llwarns << "LLHost::setAddress(): unrecoverable error" << llendl;
00210 break;
00211 default:
00212 llwarns << "LLHost::setAddress(): unknown error - " << error_number << llendl;
00213 break;
00214 }
00215 return FALSE;
00216 }
00217 }
00218
00219 LLHost& LLHost::operator=(const LLHost &rhs)
00220 {
00221 if (this != &rhs)
00222 {
00223 set(rhs.getAddress(), rhs.getPort());
00224 }
00225 return *this;
00226 }
00227
00228
00229 std::ostream& operator<< (std::ostream& os, const LLHost &hh)
00230 {
00231 os << u32_to_ip_string(hh.mIP) << ":" << hh.mPort ;
00232 return os;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241