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 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];
00165
00166 if (strlen(string)+1 > MAX_STRING)
00167 {
00168 llerrs << "LLHost::setHostByName() : Address string is too long: "
00169 << string << llendl;
00170 }
00171
00172 strncpy(local_name, string,MAX_STRING);
00173 local_name[MAX_STRING-1] = '\0';
00174 #if LL_WINDOWS
00175
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
00196 S32 error_number = h_errno;
00197 switch(error_number)
00198 {
00199 case TRY_AGAIN:
00200 llwarns << "LLHost::setAddress(): try again" << llendl;
00201 break;
00202 case HOST_NOT_FOUND:
00203 case NO_ADDRESS:
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
00235
00236
00237
00238
00239