00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #include "OW_SocketAddress.hpp"
00038 #include "OW_ByteSwap.hpp"
00039 #include "OW_Assertion.hpp"
00040 #include "OW_Mutex.hpp"
00041 #include "OW_MutexLock.hpp"
00042 #include "OW_ExceptionIds.hpp"
00043
00044 extern "C"
00045 {
00046 #if !defined(OW_WIN32)
00047 #include <netdb.h>
00048 #include <netinet/in.h>
00049 #include <arpa/inet.h>
00050 #include <sys/param.h>
00051 #include <sys/utsname.h>
00052 #include <unistd.h>
00053 #endif
00054
00055 #include <errno.h>
00056 }
00057
00058 namespace OW_NAMESPACE
00059 {
00060
00061 OW_DEFINE_EXCEPTION_WITH_ID(UnknownHost);
00062 OW_DEFINE_EXCEPTION_WITH_ID(SocketAddress);
00063
00064 const char* const SocketAddress::ALL_LOCAL_ADDRESSES = "0.0.0.0";
00065
00066 #if !defined(OW_WIN32)
00067
00068
00069 SocketAddress
00070 SocketAddress::getUDS(const String& filename)
00071 {
00072 SocketAddress rval;
00073 rval.m_type = UDS;
00074 rval.m_name = filename;
00075 rval.m_address = "localhost";
00076 memset(&rval.m_UDSNativeAddress, 0, sizeof(rval.m_UDSNativeAddress));
00077 rval.m_UDSNativeAddress.sun_family = AF_UNIX;
00078 strncpy(rval.m_UDSNativeAddress.sun_path, filename.c_str(),
00079 sizeof(rval.m_UDSNativeAddress.sun_path) - 1);
00080 #ifdef OW_SOLARIS
00081 rval.m_nativeSize = ::strlen(rval.m_UDSNativeAddress.sun_path) +
00082 offsetof(struct sockaddr_un, sun_path);
00083 #elif defined OW_OPENUNIX
00084 rval.m_UDSNativeAddress.sun_len = sizeof(rval.m_UDSNativeAddress);
00085 rval.m_nativeSize = ::strlen(rval.m_UDSNativeAddress.sun_path) +
00086 offsetof(struct sockaddr_un, sun_path);
00087 #elif defined OW_AIX || defined OW_DARWIN
00088
00089 rval.m_UDSNativeAddress.sun_len = filename.length() + 1;
00090 rval.m_nativeSize = ::strlen(rval.m_UDSNativeAddress.sun_path) +
00091 offsetof(struct sockaddr_un, sun_path) + 1;
00092 #elif defined OW_FREEBSD
00093 rval.m_nativeSize = ::strlen(rval.m_UDSNativeAddress.sun_path)
00094 + sizeof(rval.m_UDSNativeAddress.sun_len)
00095 + sizeof(rval.m_UDSNativeAddress.sun_family);
00096 #else
00097 rval.m_nativeSize = sizeof(rval.m_UDSNativeAddress.sun_family) +
00098 ::strlen(rval.m_UDSNativeAddress.sun_path);
00099 #endif
00100 return rval;
00101 }
00102
00103 #endif // #if !defined(OW_WIN32)
00104
00106 SocketAddress::SocketAddress()
00107 : m_nativeSize(0) , m_type(UNSET)
00108 {
00109 }
00110
00111 #ifndef OW_HAVE_GETHOSTBYNAME_R
00112 Mutex gethostbynameMutex;
00113 #endif
00114
00116
00117 SocketAddress
00118 SocketAddress::getByName(const String& hostName, UInt16 port)
00119 {
00120 #if defined(OW_HAVE_GETHOSTBYNAME_R) && defined(OW_GETHOSTBYNAME_R_ARGUMENTS)
00121 hostent hostbuf;
00122 hostent* host = &hostbuf;
00123 #if (OW_GETHOSTBYNAME_R_ARGUMENTS == 6)
00124 char buf[2048];
00125 int h_err = 0;
00126 if (gethostbyname_r(hostName.c_str(), &hostbuf, buf, sizeof(buf),
00127 &host, &h_err) == -1)
00128 {
00129 host = NULL;
00130 }
00131 #elif (OW_GETHOSTBYNAME_R_ARGUMENTS == 5)
00132
00133 char buf[2048];
00134 int h_err(0);
00135
00136 host = gethostbyname_r(hostName.c_str(), &hostbuf, buf, sizeof(buf), &h_err);
00137
00138 #elif (OW_GETHOSTBYNAME_R_ARGUMENTS == 3)
00139 hostent_data hostdata;
00140 if (gethostbyname_r(hostName.c_str(), &hostbuf, &hostdata) != 0)
00141 {
00142 host = NULL;
00143 }
00144
00145 #else
00146 #error Not yet supported: gethostbyname_r() with other argument counts.
00147 #endif
00148 #else
00149 MutexLock mlock(gethostbynameMutex);
00150 hostent* host = gethostbyname(hostName.c_str());
00151 #endif
00152
00153 if (!host)
00154 {
00155 OW_THROW(UnknownHostException, String("Unknown host: ").concat(hostName).c_str());
00156 }
00157 in_addr addr;
00158 memcpy(&addr, host->h_addr_list[0], sizeof(addr));
00159 return getFromNativeForm(addr, port, host->h_name);
00160 }
00161
00163
00164 SocketAddress
00165 SocketAddress::getFromNativeForm( const InetSocketAddress_t& nativeForm)
00166 {
00167 return SocketAddress(nativeForm);
00168 }
00169
00170 #if !defined(OW_WIN32)
00171
00172
00173 SocketAddress
00174 SocketAddress::getFromNativeForm( const UnixSocketAddress_t& nativeForm)
00175 {
00176 return SocketAddress(nativeForm);
00177 }
00178 #endif // !defined(OW_WIN32)
00179
00181
00182 SocketAddress
00183 SocketAddress::getFromNativeForm( const InetAddress_t& nativeForm,
00184 UInt16 nativePort, const String& hostName)
00185 {
00186 InetSocketAddress_t addr;
00187 memset(&addr, 0, sizeof(addr));
00188 addr.sin_family = AF_INET;
00189 addr.sin_port = hton16(nativePort);
00190 addr.sin_addr = nativeForm;
00191 SocketAddress p = SocketAddress(addr);
00192 p.m_type = INET;
00193 p.m_name = hostName;
00194 return p;
00195 }
00197 const SocketAddress_t* SocketAddress::getNativeForm() const
00198 {
00199 if (m_type == INET)
00200 {
00201 return reinterpret_cast<const sockaddr*>(&m_inetNativeAddress);
00202 }
00203
00204 #if !defined(OW_WIN32)
00205 else if (m_type == UDS)
00206 {
00207 return reinterpret_cast<const sockaddr*>(&m_UDSNativeAddress);
00208 }
00209 #endif
00210
00211 return 0;
00212 }
00213
00215 const InetSocketAddress_t* SocketAddress::getInetAddress() const
00216 {
00217 return &m_inetNativeAddress;
00218 }
00219
00220 #if !defined(OW_WIN32)
00221
00222
00223
00224 const UnixSocketAddress_t* SocketAddress::getUnixAddress() const
00225 {
00226 return &m_UDSNativeAddress;
00227 }
00228 #endif
00229
00231 SocketAddress
00232 SocketAddress::getAnyLocalHost(UInt16 port)
00233 {
00234 struct in_addr addr;
00235 addr.s_addr = hton32(INADDR_ANY);
00236 SocketAddress rval = getFromNativeForm(addr, port, "localhost");
00237 char buf[256];
00238 gethostname(buf, sizeof(buf));
00239 String hname(buf);
00240 if (hname.indexOf('.') == String::npos)
00241 {
00242 #if defined(OW_HAVE_GETHOSTBYNAME_R) && defined(OW_GETHOSTBYNAME_R_ARGUMENTS)
00243 hostent hostbuf;
00244 hostent* hent = &hostbuf;
00245 #if (OW_GETHOSTBYNAME_R_ARGUMENTS == 6)
00246 char local_buf[2048];
00247 int h_err = 0;
00248 if (gethostbyname_r(buf, &hostbuf, local_buf, sizeof(local_buf),
00249 &hent, &h_err) == -1)
00250 {
00251 hent = NULL;
00252 }
00253 #elif (OW_GETHOSTBYNAME_R_ARGUMENTS == 5)
00254
00255 char local_buf[2048];
00256 int h_err(0);
00257
00258 hent = gethostbyname_r(buf, &hostbuf, local_buf, sizeof(local_buf), &h_err);
00259
00260 #elif (OW_GETHOSTBYNAME_R_ARGUMENTS == 3)
00261 hostent_data hostdata;
00262 if (gethostbyname_r(buf, &hostbuf, &hostdata) != 0)
00263 {
00264 hent = NULL;
00265 }
00266
00267 #else
00268 #error Not yet supported: gethostbyname_r() with other argument counts.
00269 #endif
00270 #else
00271 MutexLock mlock(gethostbynameMutex);
00272 hostent* hent = gethostbyname(buf);
00273 #endif
00274 if (hent && hent->h_name && (strlen(hent->h_name) > 0))
00275 {
00276 hname = String(hent->h_name);
00277 }
00278 }
00279 rval.m_name = hname;
00280 return rval;
00281 }
00282
00284 void SocketAddress::assignFromNativeForm(
00285 const InetSocketAddress_t* address, size_t )
00286 {
00287 m_type = INET;
00288 memcpy(&m_inetNativeAddress, address, sizeof(m_inetNativeAddress));
00289 m_address = inet_ntoa(m_inetNativeAddress.sin_addr);
00290 m_nativeSize = sizeof(m_inetNativeAddress);
00291 }
00292
00293 #if !defined(OW_WIN32)
00294
00295 void SocketAddress::assignFromNativeForm(
00296 const UnixSocketAddress_t* address, size_t )
00297 {
00298 m_type = UDS;
00299 memcpy(&m_UDSNativeAddress, address, sizeof(m_UDSNativeAddress));
00300 m_address = "localhost";
00301 m_name = m_UDSNativeAddress.sun_path;
00302 m_nativeSize = sizeof(m_UDSNativeAddress);
00303 }
00304 #endif // !defined(OW_WIN32)
00305
00307 UInt16 SocketAddress::getPort() const
00308 {
00309 OW_ASSERT(m_type == INET);
00310 return ntoh16(m_inetNativeAddress.sin_port);
00311 }
00312
00313 #if !defined(OW_WIN32)
00314
00315 SocketAddress::SocketAddress(const UnixSocketAddress_t& nativeForm)
00316 : m_nativeSize(0), m_type(UDS)
00317 {
00318 assignFromNativeForm(&nativeForm, sizeof(nativeForm));
00319 }
00320 #endif // !defined(OW_WIN32)
00321
00323 SocketAddress::SocketAddress(const InetSocketAddress_t& nativeForm)
00324 : m_nativeSize(0), m_type(INET)
00325 {
00326 assignFromNativeForm(&nativeForm, sizeof(nativeForm));
00327 }
00329 const String SocketAddress::getName() const
00330 {
00331 return m_name;
00332 }
00334 const String SocketAddress::getAddress() const
00335 {
00336 return m_address;
00337 }
00339 size_t SocketAddress::getNativeFormSize() const
00340 {
00341 return m_nativeSize;
00342 }
00344 SocketAddress SocketAddress::allocEmptyAddress(AddressType type)
00345 {
00346 if (type == INET)
00347 {
00348 sockaddr_in addr;
00349 memset(&addr, 0, sizeof(addr));
00350 addr.sin_family = AF_INET;
00351 return SocketAddress(SocketAddress::getFromNativeForm(addr));
00352 }
00353 #if !defined(OW_WIN32)
00354 else if (type == UDS)
00355 {
00356 sockaddr_un addr;
00357 memset(&addr, 0, sizeof(addr));
00358 addr.sun_family = AF_UNIX;
00359 return SocketAddress(SocketAddress::getFromNativeForm(addr));
00360 }
00361 #endif
00362
00363 OW_THROW(SocketAddressException, "Bad Address Type");
00364 }
00366 const String
00367 SocketAddress::toString() const
00368 {
00369 OW_ASSERT(m_type != UNSET);
00370 String rval;
00371 if (m_type == INET)
00372 {
00373 rval = getAddress() + ":" + String(UInt32(getPort()));
00374 }
00375 else
00376 {
00377 rval = this->m_name;
00378 }
00379 return rval;
00380 }
00381
00382 }
00383