📄 sockets.cxx
字号:
hostname = host_info->h_name;
if (host_info->h_addr != NULL)
#ifndef _WIN32_WCE
address = *(DWORD *)host_info->h_addr;
#else
address = PIPSocket::Address(host_info->h_length, (const BYTE *)host_info->h_addr);
#endif
aliases.AppendString(host_info->h_name);
PINDEX i;
for (i = 0; host_info->h_aliases[i] != NULL; i++)
aliases.AppendString(host_info->h_aliases[i]);
for (i = 0; host_info->h_addr_list[i] != NULL; i++) {
#ifndef _WIN32_WCE
PIPSocket::Address ip(*(DWORD *)host_info->h_addr_list[i]);
#else
PIPSocket::Address ip(host_info->h_length, (const BYTE *)host_info->h_addr_list[i]);
#endif
aliases.AppendString(ip.AsString());
}
for (i = 0; i < aliases.GetSize(); i++)
if (aliases[i] *= original)
return;
aliases.AppendString(original);
}
#if P_HAS_IPV6
PIPCacheData::PIPCacheData(struct addrinfo * addr_info, const char * original)
{
PINDEX i;
if (addr_info == NULL) {
address = 0;
return;
}
// Fill Host primary informations
hostname = addr_info->ai_canonname; // Fully Qualified Domain Name (FQDN)
if (addr_info->ai_addr != NULL)
address = PIPSocket::Address(addr_info->ai_family, addr_info->ai_addrlen, addr_info->ai_addr);
// Next entries
while (addr_info != NULL) {
AddEntry(addr_info);
addr_info = addr_info->ai_next;
}
// Add original as alias or allready added ?
for (i = 0; i < aliases.GetSize(); i++) {
if (aliases[i] *= original)
return;
}
aliases.AppendString(original);
}
void PIPCacheData::AddEntry(struct addrinfo * addr_info)
{
PINDEX i;
if (addr_info == NULL)
return;
// Add canonical name
BOOL add_it = TRUE;
for (i = 0; i < aliases.GetSize(); i++) {
if (addr_info->ai_canonname != NULL && (aliases[i] *= addr_info->ai_canonname)) {
add_it = FALSE;
break;
}
}
if (add_it && addr_info->ai_canonname != NULL)
aliases.AppendString(addr_info->ai_canonname);
// Add IP address
PIPSocket::Address ip(addr_info->ai_family, addr_info->ai_addrlen, addr_info->ai_addr);
add_it = TRUE;
for (i = 0; i < aliases.GetSize(); i++) {
if (aliases[i] *= ip.AsString()) {
add_it = FALSE;
break;
}
}
if (add_it)
aliases.AppendString(ip.AsString());
}
#endif
static PTimeInterval GetConfigTime(const char * /*key*/, DWORD dflt)
{
//PConfig cfg("DNS Cache");
//return cfg.GetInteger(key, dflt);
return dflt;
}
BOOL PIPCacheData::HasAged() const
{
static PTimeInterval retirement = GetConfigTime("Age Limit", 300000); // 5 minutes
PTime now;
PTimeInterval age = now - birthDate;
return age > retirement;
}
BOOL PHostByName::GetHostName(const PString & name, PString & hostname)
{
PIPCacheData * host = GetHost(name);
if (host != NULL) {
hostname = host->GetHostName();
hostname.MakeUnique();
}
mutex.Signal();
return host != NULL;
}
BOOL PHostByName::GetHostAddress(const PString & name, PIPSocket::Address & address)
{
PIPCacheData * host = GetHost(name);
if (host != NULL)
address = host->GetHostAddress();
mutex.Signal();
return host != NULL;
}
BOOL PHostByName::GetHostAliases(const PString & name, PStringArray & aliases)
{
PIPCacheData * host = GetHost(name);
if (host != NULL) {
const PStringList & a = host->GetHostAliases();
aliases.SetSize(a.GetSize());
for (PINDEX i = 0; i < a.GetSize(); i++)
aliases[i] = a[i];
}
mutex.Signal();
return host != NULL;
}
PIPCacheData * PHostByName::GetHost(const PString & name)
{
mutex.Wait();
PCaselessString key = name;
PIPCacheData * host = GetAt(key);
int localErrNo = NETDB_SUCCESS;
if (host != NULL && host->HasAged()) {
SetAt(key, NULL);
host = NULL;
}
if (host == NULL) {
mutex.Signal();
#if P_HAS_IPV6
struct addrinfo *res;
struct addrinfo hints = { AI_CANONNAME, PF_UNSPEC };
hints.ai_family = defaultIpAddressFamily;
localErrNo = getaddrinfo((const char *)name, NULL , &hints, &res);
mutex.Wait();
if (localErrNo != NETDB_SUCCESS)
return NULL;
host = new PIPCacheData(res, name);
freeaddrinfo(res);
#else // P_HAS_IPV6
int retry = 3;
struct hostent * host_info;
#ifdef P_AIX
struct hostent_data ht_data;
memset(&ht_data, 0, sizeof(ht_data));
struct hostent hostEnt;
do {
host_info = &hostEnt;
::gethostbyname_r(name,
host_info,
&ht_data);
localErrNo = h_errno;
} while (localErrNo == TRY_AGAIN && --retry > 0);
#elif defined(P_RTEMS) || defined(P_CYGWIN) || defined(P_MINGW)
host_info = ::gethostbyname(name);
localErrNo = h_errno;
#elif defined P_VXWORKS
struct hostent hostEnt;
host_info = Vx_gethostbyname((char *)name, &hostEnt);
localErrNo = h_errno;
#elif defined P_LINUX
char buffer[REENTRANT_BUFFER_LEN];
struct hostent hostEnt;
do {
if (::gethostbyname_r(name,
&hostEnt,
buffer, REENTRANT_BUFFER_LEN,
&host_info,
&localErrNo) == 0)
localErrNo = NETDB_SUCCESS;
} while (localErrNo == TRY_AGAIN && --retry > 0);
#elif (defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB)) || defined(__NUCLEUS_PLUS__)
char buffer[REENTRANT_BUFFER_LEN];
struct hostent hostEnt;
do {
host_info = ::gethostbyname_r(name,
&hostEnt,
buffer, REENTRANT_BUFFER_LEN,
&localErrNo);
} while (localErrNo == TRY_AGAIN && --retry > 0);
#else
host_info = ::gethostbyname(name);
localErrNo = h_errno;
#endif
mutex.Wait();
if (localErrNo != NETDB_SUCCESS || retry == 0)
return NULL;
host = new PIPCacheData(host_info, name);
#endif //P_HAS_IPV6
SetAt(key, host);
}
if (host->GetHostAddress() == 0)
return NULL;
return host;
}
BOOL PHostByAddr::GetHostName(const PIPSocket::Address & addr, PString & hostname)
{
PIPCacheData * host = GetHost(addr);
if (host != NULL) {
hostname = host->GetHostName();
hostname.MakeUnique();
}
mutex.Signal();
return host != NULL;
}
BOOL PHostByAddr::GetHostAddress(const PIPSocket::Address & addr, PIPSocket::Address & address)
{
PIPCacheData * host = GetHost(addr);
if (host != NULL)
address = host->GetHostAddress();
mutex.Signal();
return host != NULL;
}
BOOL PHostByAddr::GetHostAliases(const PIPSocket::Address & addr, PStringArray & aliases)
{
PIPCacheData * host = GetHost(addr);
if (host != NULL) {
const PStringList & a = host->GetHostAliases();
aliases.SetSize(a.GetSize());
for (PINDEX i = 0; i < a.GetSize(); i++)
aliases[i] = a[i];
}
mutex.Signal();
return host != NULL;
}
PIPCacheData * PHostByAddr::GetHost(const PIPSocket::Address & addr)
{
mutex.Wait();
PIPCacheKey key = addr;
PIPCacheData * host = GetAt(key);
if (host != NULL && host->HasAged()) {
SetAt(key, NULL);
host = NULL;
}
if (host == NULL) {
mutex.Signal();
int retry = 3;
int localErrNo = NETDB_SUCCESS;
struct hostent * host_info;
#ifdef P_AIX
struct hostent_data ht_data;
struct hostent hostEnt;
do {
host_info = &hostEnt;
::gethostbyaddr_r((char *)addr.GetPointer(), addr.GetSize(),
PF_INET,
host_info,
&ht_data);
localErrNo = h_errno;
} while (localErrNo == TRY_AGAIN && --retry > 0);
#elif defined P_RTEMS || defined P_CYGWIN || defined P_MINGW
host_info = ::gethostbyaddr(addr.GetPointer(), addr.GetSize(), PF_INET);
localErrNo = h_errno;
#elif defined P_VXWORKS
struct hostent hostEnt;
host_info = Vx_gethostbyaddr(addr.GetPointer(), &hostEnt);
#elif defined P_LINUX
char buffer[REENTRANT_BUFFER_LEN];
struct hostent hostEnt;
do {
::gethostbyaddr_r(addr.GetPointer(), addr.GetSize(),
PF_INET,
&hostEnt,
buffer, REENTRANT_BUFFER_LEN,
&host_info,
&localErrNo);
} while (localErrNo == TRY_AGAIN && --retry > 0);
#elif (defined(P_PTHREADS) && !defined(P_THREAD_SAFE_CLIB)) || defined(__NUCLEUS_PLUS__)
char buffer[REENTRANT_BUFFER_LEN];
struct hostent hostEnt;
do {
host_info = ::gethostbyaddr_r(addr.GetPointer(), addr.GetSize(),
PF_INET,
&hostEnt,
buffer, REENTRANT_BUFFER_LEN,
&localErrNo);
} while (localErrNo == TRY_AGAIN && --retry > 0);
#else
host_info = ::gethostbyaddr(addr.GetPointer(), addr.GetSize(), PF_INET);
localErrNo = h_errno;
#if defined(_WIN32) || defined(WINDOWS) // Kludge to avoid strange 95 bug
extern int P_IsOldWin95();
if (P_IsOldWin95() && host_info != NULL && host_info->h_addr_list[0] != NULL)
host_info->h_addr_list[1] = NULL;
#endif
#endif
mutex.Wait();
if (localErrNo != NETDB_SUCCESS || retry == 0)
return NULL;
host = new PIPCacheData(host_info, addr.AsString());
SetAt(key, host);
}
if (host->GetHostAddress() == 0)
return NULL;
return host;
}
//////////////////////////////////////////////////////////////////////////////
// P_fd_set
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4127)
#endif
P_fd_set::P_fd_set()
{
Construct();
Zero();
}
P_fd_set::P_fd_set(SOCKET fd)
{
Construct();
Zero();
FD_SET(fd, set);
}
P_fd_set & P_fd_set::operator=(SOCKET fd)
{
PAssert(fd < max_fd, PInvalidParameter);
Zero();
FD_SET(fd, set);
return *this;
}
P_fd_set & P_fd_set::operator+=(SOCKET fd)
{
PAssert(fd < max_fd, PInvalidParameter);
FD_SET(fd, set);
return *this;
}
P_fd_set & P_fd_set::operator-=(SOCKET fd)
{
PAssert(fd < max_fd, PInvalidParameter);
FD_CLR(fd, set);
return *this;
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
//////////////////////////////////////////////////////////////////////////////
// P_timeval
P_timeval::P_timeval()
{
tval.tv_usec = 0;
tval.tv_sec = 0;
infinite = FALSE;
}
P_timeval & P_timeval::operator=(const PTimeInterval & time)
{
infinite = time == PMaxTimeInterval;
tval.tv_usec = (long)(time.GetMilliSeconds()%1000)*1000;
tval.tv_sec = time.GetSeconds();
return *this;
}
//////////////////////////////////////////////////////////////////////////////
// PSocket
PSocket::PSocket()
{
port = 0;
#if P_HAS_RECVMSG
catchReceiveToAddr = FALSE;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -