Changed non-reentrant network functions to be reentrant and
thread safe.
This commit is contained in:
parent
11e29ff7eb
commit
586a5a81ab
|
@ -15,6 +15,7 @@
|
||||||
#include "CNetwork.h"
|
#include "CNetwork.h"
|
||||||
#include "XNetwork.h"
|
#include "XNetwork.h"
|
||||||
#include "CLog.h"
|
#include "CLog.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
//
|
//
|
||||||
// CNetwork
|
// CNetwork
|
||||||
|
@ -29,7 +30,6 @@ int (PASCAL FAR *CNetwork::getpeername)(CNetwork::Socket s, CNetwork::Address FA
|
||||||
int (PASCAL FAR *CNetwork::getsockname)(CNetwork::Socket s, CNetwork::Address FAR *name, CNetwork::AddressLength FAR * namelen);
|
int (PASCAL FAR *CNetwork::getsockname)(CNetwork::Socket s, CNetwork::Address FAR *name, CNetwork::AddressLength FAR * namelen);
|
||||||
int (PASCAL FAR *CNetwork::getsockopt)(CNetwork::Socket s, int level, int optname, void FAR * optval, CNetwork::AddressLength FAR *optlen);
|
int (PASCAL FAR *CNetwork::getsockopt)(CNetwork::Socket s, int level, int optname, void FAR * optval, CNetwork::AddressLength FAR *optlen);
|
||||||
unsigned long (PASCAL FAR *CNetwork::inet_addr)(const char FAR * cp);
|
unsigned long (PASCAL FAR *CNetwork::inet_addr)(const char FAR * cp);
|
||||||
char FAR * (PASCAL FAR *CNetwork::inet_ntoa)(struct in_addr in);
|
|
||||||
int (PASCAL FAR *CNetwork::listen)(CNetwork::Socket s, int backlog);
|
int (PASCAL FAR *CNetwork::listen)(CNetwork::Socket s, int backlog);
|
||||||
ssize_t (PASCAL FAR *CNetwork::read)(CNetwork::Socket s, void FAR * buf, size_t len);
|
ssize_t (PASCAL FAR *CNetwork::read)(CNetwork::Socket s, void FAR * buf, size_t len);
|
||||||
ssize_t (PASCAL FAR *CNetwork::recv)(CNetwork::Socket s, void FAR * buf, size_t len, int flags);
|
ssize_t (PASCAL FAR *CNetwork::recv)(CNetwork::Socket s, void FAR * buf, size_t len, int flags);
|
||||||
|
@ -41,23 +41,20 @@ int (PASCAL FAR *CNetwork::setsockopt)(CNetwork::Socket s, int level, int optnam
|
||||||
int (PASCAL FAR *CNetwork::shutdown)(CNetwork::Socket s, int how);
|
int (PASCAL FAR *CNetwork::shutdown)(CNetwork::Socket s, int how);
|
||||||
CNetwork::Socket (PASCAL FAR *CNetwork::socket)(int af, int type, int protocol);
|
CNetwork::Socket (PASCAL FAR *CNetwork::socket)(int af, int type, int protocol);
|
||||||
ssize_t (PASCAL FAR *CNetwork::write)(CNetwork::Socket s, const void FAR * buf, size_t len);
|
ssize_t (PASCAL FAR *CNetwork::write)(CNetwork::Socket s, const void FAR * buf, size_t len);
|
||||||
struct hostent FAR * (PASCAL FAR *CNetwork::gethostbyaddr)(const char FAR * addr, int len, int type);
|
|
||||||
struct hostent FAR * (PASCAL FAR *CNetwork::gethostbyname)(const char FAR * name);
|
|
||||||
int (PASCAL FAR *CNetwork::gethostname)(char FAR * name, int namelen);
|
int (PASCAL FAR *CNetwork::gethostname)(char FAR * name, int namelen);
|
||||||
struct servent FAR * (PASCAL FAR *CNetwork::getservbyport)(int port, const char FAR * proto);
|
|
||||||
struct servent FAR * (PASCAL FAR *CNetwork::getservbyname)(const char FAR * name, const char FAR * proto);
|
|
||||||
struct protoent FAR * (PASCAL FAR *CNetwork::getprotobynumber)(int proto);
|
|
||||||
struct protoent FAR * (PASCAL FAR *CNetwork::getprotobyname)(const char FAR * name);
|
|
||||||
int (PASCAL FAR *CNetwork::getsockerror)(void);
|
int (PASCAL FAR *CNetwork::getsockerror)(void);
|
||||||
int (PASCAL FAR *CNetwork::gethosterror)(void);
|
|
||||||
int (PASCAL FAR *CNetwork::setblocking)(CNetwork::Socket s, bool blocking);
|
|
||||||
int (PASCAL FAR *CNetwork::setnodelay)(CNetwork::Socket s, bool blocking);
|
|
||||||
|
|
||||||
#if WINDOWS_LIKE
|
#if WINDOWS_LIKE
|
||||||
|
|
||||||
int (PASCAL FAR *CNetwork::select)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout);
|
int (PASCAL FAR *CNetwork::select)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout);
|
||||||
int (PASCAL FAR *CNetwork::WSACleanup)(void);
|
int (PASCAL FAR *CNetwork::WSACleanup)(void);
|
||||||
int (PASCAL FAR *CNetwork::__WSAFDIsSet)(CNetwork::Socket, fd_set FAR *);
|
int (PASCAL FAR *CNetwork::__WSAFDIsSet)(CNetwork::Socket, fd_set FAR *);
|
||||||
|
struct hostent FAR * (PASCAL FAR *CNetwork::gethostbyaddr_n)(const char FAR * addr, int len, int type);
|
||||||
|
struct hostent FAR * (PASCAL FAR *CNetwork::gethostbyname_n)(const char FAR * name);
|
||||||
|
struct servent FAR * (PASCAL FAR *CNetwork::getservbyport_n)(int port, const char FAR * proto);
|
||||||
|
struct servent FAR * (PASCAL FAR *CNetwork::getservbyname_n)(const char FAR * name, const char FAR * proto);
|
||||||
|
struct protoent FAR * (PASCAL FAR *CNetwork::getprotobynumber_n)(int proto);
|
||||||
|
struct protoent FAR * (PASCAL FAR *CNetwork::getprotobyname_n)(const char FAR * name);
|
||||||
const int CNetwork::Error = SOCKET_ERROR;
|
const int CNetwork::Error = SOCKET_ERROR;
|
||||||
const CNetwork::Socket CNetwork::Null = INVALID_SOCKET;
|
const CNetwork::Socket CNetwork::Null = INVALID_SOCKET;
|
||||||
|
|
||||||
|
@ -202,7 +199,7 @@ CNetwork::init2(
|
||||||
setfunc(getsockname, getsockname, int (PASCAL FAR *)(Socket s, Address FAR *name, AddressLength FAR * namelen));
|
setfunc(getsockname, getsockname, int (PASCAL FAR *)(Socket s, Address FAR *name, AddressLength FAR * namelen));
|
||||||
setfunc(getsockopt, getsockopt, int (PASCAL FAR *)(Socket s, int level, int optname, void FAR * optval, AddressLength FAR *optlen));
|
setfunc(getsockopt, getsockopt, int (PASCAL FAR *)(Socket s, int level, int optname, void FAR * optval, AddressLength FAR *optlen));
|
||||||
setfunc(inet_addr, inet_addr, unsigned long (PASCAL FAR *)(const char FAR * cp));
|
setfunc(inet_addr, inet_addr, unsigned long (PASCAL FAR *)(const char FAR * cp));
|
||||||
setfunc(inet_ntoa, inet_ntoa, char FAR * (PASCAL FAR *)(struct in_addr in));
|
setfunc(inet_ntoa_n, inet_ntoa, char FAR * (PASCAL FAR *)(struct in_addr in));
|
||||||
setfunc(listen, listen, int (PASCAL FAR *)(Socket s, int backlog));
|
setfunc(listen, listen, int (PASCAL FAR *)(Socket s, int backlog));
|
||||||
setfunc(recv, recv, ssize_t (PASCAL FAR *)(Socket s, void FAR * buf, size_t len, int flags));
|
setfunc(recv, recv, ssize_t (PASCAL FAR *)(Socket s, void FAR * buf, size_t len, int flags));
|
||||||
setfunc(recvfrom, recvfrom, ssize_t (PASCAL FAR *)(Socket s, void FAR * buf, size_t len, int flags, Address FAR *from, AddressLength FAR * fromlen));
|
setfunc(recvfrom, recvfrom, ssize_t (PASCAL FAR *)(Socket s, void FAR * buf, size_t len, int flags, Address FAR *from, AddressLength FAR * fromlen));
|
||||||
|
@ -211,23 +208,20 @@ CNetwork::init2(
|
||||||
setfunc(setsockopt, setsockopt, int (PASCAL FAR *)(Socket s, int level, int optname, const void FAR * optval, AddressLength optlen));
|
setfunc(setsockopt, setsockopt, int (PASCAL FAR *)(Socket s, int level, int optname, const void FAR * optval, AddressLength optlen));
|
||||||
setfunc(shutdown, shutdown, int (PASCAL FAR *)(Socket s, int how));
|
setfunc(shutdown, shutdown, int (PASCAL FAR *)(Socket s, int how));
|
||||||
setfunc(socket, socket, Socket (PASCAL FAR *)(int af, int type, int protocol));
|
setfunc(socket, socket, Socket (PASCAL FAR *)(int af, int type, int protocol));
|
||||||
setfunc(gethostbyaddr, gethostbyaddr, struct hostent FAR * (PASCAL FAR *)(const char FAR * addr, int len, int type));
|
|
||||||
setfunc(gethostbyname, gethostbyname, struct hostent FAR * (PASCAL FAR *)(const char FAR * name));
|
|
||||||
setfunc(gethostname, gethostname, int (PASCAL FAR *)(char FAR * name, int namelen));
|
setfunc(gethostname, gethostname, int (PASCAL FAR *)(char FAR * name, int namelen));
|
||||||
setfunc(getservbyport, getservbyport, struct servent FAR * (PASCAL FAR *)(int port, const char FAR * proto));
|
setfunc(gethostbyaddr_n, gethostbyaddr, struct hostent FAR * (PASCAL FAR *)(const char FAR * addr, int len, int type));
|
||||||
setfunc(getservbyname, getservbyname, struct servent FAR * (PASCAL FAR *)(const char FAR * name, const char FAR * proto));
|
setfunc(gethostbyname_n, gethostbyname, struct hostent FAR * (PASCAL FAR *)(const char FAR * name));
|
||||||
setfunc(getprotobynumber, getprotobynumber, struct protoent FAR * (PASCAL FAR *)(int proto));
|
setfunc(getservbyport_n, getservbyport, struct servent FAR * (PASCAL FAR *)(int port, const char FAR * proto));
|
||||||
setfunc(getprotobyname, getprotobyname, struct protoent FAR * (PASCAL FAR *)(const char FAR * name));
|
setfunc(getservbyname_n, getservbyname, struct servent FAR * (PASCAL FAR *)(const char FAR * name, const char FAR * proto));
|
||||||
|
setfunc(getprotobynumber_n, getprotobynumber, struct protoent FAR * (PASCAL FAR *)(int proto));
|
||||||
|
setfunc(getprotobyname_n, getprotobyname, struct protoent FAR * (PASCAL FAR *)(const char FAR * name));
|
||||||
setfunc(getsockerror, WSAGetLastError, int (PASCAL FAR *)(void));
|
setfunc(getsockerror, WSAGetLastError, int (PASCAL FAR *)(void));
|
||||||
setfunc(gethosterror, WSAGetLastError, int (PASCAL FAR *)(void));
|
|
||||||
setfunc(WSACleanup, WSACleanup, int (PASCAL FAR *)(void));
|
setfunc(WSACleanup, WSACleanup, int (PASCAL FAR *)(void));
|
||||||
setfunc(__WSAFDIsSet, __WSAFDIsSet, int (PASCAL FAR *)(CNetwork::Socket, fd_set FAR *));
|
setfunc(__WSAFDIsSet, __WSAFDIsSet, int (PASCAL FAR *)(CNetwork::Socket, fd_set FAR *));
|
||||||
setfunc(select, select, int (PASCAL FAR *)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout));
|
setfunc(select, select, int (PASCAL FAR *)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout));
|
||||||
poll = poll2;
|
poll = poll2;
|
||||||
read = read2;
|
read = read2;
|
||||||
write = write2;
|
write = write2;
|
||||||
setblocking = setblocking2;
|
|
||||||
setnodelay = setnodelay2;
|
|
||||||
|
|
||||||
s_networkModule = module;
|
s_networkModule = module;
|
||||||
}
|
}
|
||||||
|
@ -244,15 +238,130 @@ CNetwork::write2(Socket s, const void FAR* buf, size_t len)
|
||||||
return send(s, buf, len, 0);
|
return send(s, buf, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CString PASCAL FAR
|
||||||
|
CNetwork::inet_ntoa(struct in_addr in)
|
||||||
|
{
|
||||||
|
// winsock returns strings per-thread
|
||||||
|
return CString(inet_ntoa_n(in));
|
||||||
|
}
|
||||||
|
|
||||||
int PASCAL FAR
|
int PASCAL FAR
|
||||||
CNetwork::setblocking2(CNetwork::Socket s, bool blocking)
|
CNetwork::gethostbyaddr(CHostInfo* hostinfo,
|
||||||
|
const char FAR * addr, int len, int type)
|
||||||
|
{
|
||||||
|
assert(hostinfo != NULL);
|
||||||
|
|
||||||
|
// winsock returns structures per-thread
|
||||||
|
struct hostent FAR* info = gethostbyaddr_n(addr, len, type);
|
||||||
|
if (info == NULL) {
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CHostInfo tmp(info);
|
||||||
|
hostinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::gethostbyname(CHostInfo* hostinfo,
|
||||||
|
const char FAR * name)
|
||||||
|
{
|
||||||
|
assert(hostinfo != NULL);
|
||||||
|
|
||||||
|
// winsock returns structures per-thread
|
||||||
|
struct hostent FAR* info = gethostbyname_n(name);
|
||||||
|
if (info == NULL) {
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CHostInfo tmp(info);
|
||||||
|
hostinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::getservbyport(CServiceInfo* servinfo,
|
||||||
|
int port, const char FAR * proto)
|
||||||
|
{
|
||||||
|
assert(servinfo != NULL);
|
||||||
|
|
||||||
|
// winsock returns structures per-thread
|
||||||
|
struct servent FAR* info = getservbyport_n(port, proto);
|
||||||
|
if (info == NULL) {
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CServiceInfo tmp(info);
|
||||||
|
servinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::getservbyname(CServiceInfo* servinfo,
|
||||||
|
const char FAR * name, const char FAR * proto)
|
||||||
|
{
|
||||||
|
assert(servinfo != NULL);
|
||||||
|
|
||||||
|
// winsock returns structures per-thread
|
||||||
|
struct servent FAR* info = getservbyname_n(name, proto);
|
||||||
|
if (info == NULL) {
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CServiceInfo tmp(info);
|
||||||
|
servinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::getprotobynumber(CProtocolInfo* protoinfo,
|
||||||
|
int proto)
|
||||||
|
{
|
||||||
|
assert(protoinfo != NULL);
|
||||||
|
|
||||||
|
// winsock returns structures per-thread
|
||||||
|
struct protoinfo FAR* info = getprotobynumber_n(proto);
|
||||||
|
if (info == NULL) {
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CProtocolInfo tmp(info);
|
||||||
|
protoinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::getprotobyname(CProtocolInfo* protoinfo,
|
||||||
|
const char FAR * name)
|
||||||
|
{
|
||||||
|
assert(protoinfo != NULL);
|
||||||
|
|
||||||
|
// winsock returns structures per-thread
|
||||||
|
struct protoinfo FAR* info = getprotobyname_n(name);
|
||||||
|
if (info == NULL) {
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CProtocolInfo tmp(info);
|
||||||
|
protoinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::setblocking(CNetwork::Socket s, bool blocking)
|
||||||
{
|
{
|
||||||
int flag = blocking ? 0 : 1;
|
int flag = blocking ? 0 : 1;
|
||||||
return ioctl(s, FIONBIO, &flag);
|
return ioctl(s, FIONBIO, &flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PASCAL FAR
|
int PASCAL FAR
|
||||||
CNetwork::setnodelay2(CNetwork::Socket s, bool nodelay)
|
CNetwork::setnodelay(CNetwork::Socket s, bool nodelay)
|
||||||
{
|
{
|
||||||
BOOL flag = nodelay ? 1 : 0;
|
BOOL flag = nodelay ? 1 : 0;
|
||||||
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
|
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
|
||||||
|
@ -262,6 +371,9 @@ CNetwork::setnodelay2(CNetwork::Socket s, bool nodelay)
|
||||||
|
|
||||||
#if UNIX_LIKE
|
#if UNIX_LIKE
|
||||||
|
|
||||||
|
#include "CMutex.h"
|
||||||
|
#include "CLock.h"
|
||||||
|
|
||||||
#if HAVE_SYS_TYPES_H
|
#if HAVE_SYS_TYPES_H
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -284,6 +396,8 @@ CNetwork::setnodelay2(CNetwork::Socket s, bool nodelay)
|
||||||
const int CNetwork::Error = -1;
|
const int CNetwork::Error = -1;
|
||||||
const CNetwork::Socket CNetwork::Null = -1;
|
const CNetwork::Socket CNetwork::Null = -1;
|
||||||
|
|
||||||
|
static CMutex* s_networkMutex = NULL;
|
||||||
|
|
||||||
#define setfunc(var, name, type) var = (type)::name
|
#define setfunc(var, name, type) var = (type)::name
|
||||||
|
|
||||||
UInt32
|
UInt32
|
||||||
|
@ -313,6 +427,15 @@ CNetwork::swapntohs(UInt16 v)
|
||||||
void
|
void
|
||||||
CNetwork::init()
|
CNetwork::init()
|
||||||
{
|
{
|
||||||
|
assert(s_networkMutex == NULL);
|
||||||
|
|
||||||
|
try {
|
||||||
|
s_networkMutex = new CMutex;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
throw XNetworkFailed();
|
||||||
|
}
|
||||||
|
|
||||||
setfunc(accept, accept, Socket (PASCAL FAR *)(Socket s, Address FAR *addr, AddressLength FAR *addrlen));
|
setfunc(accept, accept, Socket (PASCAL FAR *)(Socket s, Address FAR *addr, AddressLength FAR *addrlen));
|
||||||
setfunc(bind, bind, int (PASCAL FAR *)(Socket s, const Address FAR *addr, AddressLength namelen));
|
setfunc(bind, bind, int (PASCAL FAR *)(Socket s, const Address FAR *addr, AddressLength namelen));
|
||||||
setfunc(close, close, int (PASCAL FAR *)(Socket s));
|
setfunc(close, close, int (PASCAL FAR *)(Socket s));
|
||||||
|
@ -322,7 +445,6 @@ CNetwork::init()
|
||||||
setfunc(getsockname, getsockname, int (PASCAL FAR *)(Socket s, Address FAR *name, AddressLength FAR * namelen));
|
setfunc(getsockname, getsockname, int (PASCAL FAR *)(Socket s, Address FAR *name, AddressLength FAR * namelen));
|
||||||
setfunc(getsockopt, getsockopt, int (PASCAL FAR *)(Socket s, int level, int optname, void FAR * optval, AddressLength FAR *optlen));
|
setfunc(getsockopt, getsockopt, int (PASCAL FAR *)(Socket s, int level, int optname, void FAR * optval, AddressLength FAR *optlen));
|
||||||
setfunc(inet_addr, inet_addr, unsigned long (PASCAL FAR *)(const char FAR * cp));
|
setfunc(inet_addr, inet_addr, unsigned long (PASCAL FAR *)(const char FAR * cp));
|
||||||
setfunc(inet_ntoa, inet_ntoa, char FAR * (PASCAL FAR *)(struct in_addr in));
|
|
||||||
setfunc(listen, listen, int (PASCAL FAR *)(Socket s, int backlog));
|
setfunc(listen, listen, int (PASCAL FAR *)(Socket s, int backlog));
|
||||||
#if HAVE_POLL
|
#if HAVE_POLL
|
||||||
setfunc(poll, poll, int (PASCAL FAR *)(CNetwork::PollEntry fds[], int nfds, int timeout));
|
setfunc(poll, poll, int (PASCAL FAR *)(CNetwork::PollEntry fds[], int nfds, int timeout));
|
||||||
|
@ -338,23 +460,15 @@ CNetwork::init()
|
||||||
setfunc(shutdown, shutdown, int (PASCAL FAR *)(Socket s, int how));
|
setfunc(shutdown, shutdown, int (PASCAL FAR *)(Socket s, int how));
|
||||||
setfunc(socket, socket, Socket (PASCAL FAR *)(int af, int type, int protocol));
|
setfunc(socket, socket, Socket (PASCAL FAR *)(int af, int type, int protocol));
|
||||||
setfunc(write, write, ssize_t (PASCAL FAR *)(CNetwork::Socket s, const void FAR * buf, size_t len));
|
setfunc(write, write, ssize_t (PASCAL FAR *)(CNetwork::Socket s, const void FAR * buf, size_t len));
|
||||||
setfunc(gethostbyaddr, gethostbyaddr, struct hostent FAR * (PASCAL FAR *)(const char FAR * addr, int len, int type));
|
|
||||||
setfunc(gethostbyname, gethostbyname, struct hostent FAR * (PASCAL FAR *)(const char FAR * name));
|
|
||||||
setfunc(getservbyport, getservbyport, struct servent FAR * (PASCAL FAR *)(int port, const char FAR * proto));
|
|
||||||
setfunc(getservbyname, getservbyname, struct servent FAR * (PASCAL FAR *)(const char FAR * name, const char FAR * proto));
|
|
||||||
setfunc(getprotobynumber, getprotobynumber, struct protoent FAR * (PASCAL FAR *)(int proto));
|
|
||||||
setfunc(getprotobyname, getprotobyname, struct protoent FAR * (PASCAL FAR *)(const char FAR * name));
|
|
||||||
gethostname = gethostname2;
|
gethostname = gethostname2;
|
||||||
getsockerror = getsockerror2;
|
getsockerror = getsockerror2;
|
||||||
gethosterror = gethosterror2;
|
|
||||||
setblocking = setblocking2;
|
|
||||||
setnodelay = setnodelay2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CNetwork::cleanup()
|
CNetwork::cleanup()
|
||||||
{
|
{
|
||||||
// do nothing
|
delete s_networkMutex;
|
||||||
|
s_networkMutex = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PASCAL FAR
|
int PASCAL FAR
|
||||||
|
@ -369,14 +483,130 @@ CNetwork::getsockerror2(void)
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PASCAL FAR
|
CString PASCAL FAR
|
||||||
CNetwork::gethosterror2(void)
|
CNetwork::inet_ntoa(struct in_addr in)
|
||||||
{
|
{
|
||||||
return h_errno;
|
// single threaded access to inet_ntoa functions
|
||||||
|
CLock lock(s_networkMutex);
|
||||||
|
return CString(::inet_ntoa(in));
|
||||||
}
|
}
|
||||||
|
|
||||||
int PASCAL FAR
|
int PASCAL FAR
|
||||||
CNetwork::setblocking2(CNetwork::Socket s, bool blocking)
|
CNetwork::gethostbyaddr(CHostInfo* hostinfo,
|
||||||
|
const char FAR * addr, int len, int type)
|
||||||
|
{
|
||||||
|
assert(hostinfo != NULL);
|
||||||
|
|
||||||
|
// single threaded access to netdb functions
|
||||||
|
CLock lock(s_networkMutex);
|
||||||
|
struct hostent FAR* info = ::gethostbyaddr(addr, len, type);
|
||||||
|
if (info == NULL) {
|
||||||
|
return h_errno;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CHostInfo tmp(info);
|
||||||
|
hostinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::gethostbyname(CHostInfo* hostinfo,
|
||||||
|
const char FAR * name)
|
||||||
|
{
|
||||||
|
assert(hostinfo != NULL);
|
||||||
|
|
||||||
|
// single threaded access to netdb functions
|
||||||
|
CLock lock(s_networkMutex);
|
||||||
|
struct hostent FAR* info = ::gethostbyname(name);
|
||||||
|
if (info == NULL) {
|
||||||
|
return h_errno;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CHostInfo tmp(info);
|
||||||
|
hostinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::getservbyport(CServiceInfo* servinfo,
|
||||||
|
int port, const char FAR * proto)
|
||||||
|
{
|
||||||
|
assert(servinfo != NULL);
|
||||||
|
|
||||||
|
// single threaded access to netdb functions
|
||||||
|
CLock lock(s_networkMutex);
|
||||||
|
struct servent FAR* info = ::getservbyport(port, proto);
|
||||||
|
if (info == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CServiceInfo tmp(info);
|
||||||
|
servinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::getservbyname(CServiceInfo* servinfo,
|
||||||
|
const char FAR * name, const char FAR * proto)
|
||||||
|
{
|
||||||
|
assert(servinfo != NULL);
|
||||||
|
|
||||||
|
// single threaded access to netdb functions
|
||||||
|
CLock lock(s_networkMutex);
|
||||||
|
struct servent FAR* info = ::getservbyname(name, proto);
|
||||||
|
if (info == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CServiceInfo tmp(info);
|
||||||
|
servinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::getprotobynumber(CProtocolInfo* protoinfo,
|
||||||
|
int proto)
|
||||||
|
{
|
||||||
|
assert(protoinfo != NULL);
|
||||||
|
|
||||||
|
// single threaded access to netdb functions
|
||||||
|
CLock lock(s_networkMutex);
|
||||||
|
struct protoent FAR* info = ::getprotobynumber(proto);
|
||||||
|
if (info == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CProtocolInfo tmp(info);
|
||||||
|
protoinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::getprotobyname(CProtocolInfo* protoinfo,
|
||||||
|
const char FAR * name)
|
||||||
|
{
|
||||||
|
assert(protoinfo != NULL);
|
||||||
|
|
||||||
|
// single threaded access to netdb functions
|
||||||
|
CLock lock(s_networkMutex);
|
||||||
|
struct protoent FAR* info = ::getprotobyname(name);
|
||||||
|
if (info == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CProtocolInfo tmp(info);
|
||||||
|
protoinfo->swap(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PASCAL FAR
|
||||||
|
CNetwork::setblocking(CNetwork::Socket s, bool blocking)
|
||||||
{
|
{
|
||||||
int mode = fcntl(s, F_GETFL, 0);
|
int mode = fcntl(s, F_GETFL, 0);
|
||||||
if (mode == -1) {
|
if (mode == -1) {
|
||||||
|
@ -395,7 +625,7 @@ CNetwork::setblocking2(CNetwork::Socket s, bool blocking)
|
||||||
}
|
}
|
||||||
|
|
||||||
int PASCAL FAR
|
int PASCAL FAR
|
||||||
CNetwork::setnodelay2(CNetwork::Socket s, bool nodelay)
|
CNetwork::setnodelay(CNetwork::Socket s, bool nodelay)
|
||||||
{
|
{
|
||||||
int flag = nodelay ? 1 : 0;
|
int flag = nodelay ? 1 : 0;
|
||||||
setsockopt(s, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
|
setsockopt(s, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
|
||||||
|
@ -502,3 +732,98 @@ CNetwork::poll2(PollEntry fd[], int nfds, int timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// CNetwork::CHostInfo
|
||||||
|
//
|
||||||
|
|
||||||
|
CNetwork::CHostInfo::CHostInfo(const struct hostent* hent)
|
||||||
|
{
|
||||||
|
assert(hent != NULL);
|
||||||
|
|
||||||
|
m_name = hent->h_name;
|
||||||
|
m_addressType = hent->h_addrtype;
|
||||||
|
m_addressLength = hent->h_length;
|
||||||
|
for (char** scan = hent->h_aliases; *scan != NULL; ++scan) {
|
||||||
|
m_aliases.push_back(*scan);
|
||||||
|
}
|
||||||
|
|
||||||
|
// concatenate addresses together
|
||||||
|
UInt32 n = 0;
|
||||||
|
for (char** scan = hent->h_addr_list; *scan != NULL; ++scan) {
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
m_addressData.reserve(n);
|
||||||
|
for (char** scan = hent->h_addr_list; *scan != NULL; ++scan) {
|
||||||
|
m_addressData.append(*scan, m_addressLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set pointers into concatenated data
|
||||||
|
const char* data = m_addressData.data();
|
||||||
|
for (char** scan = hent->h_addr_list; *scan != NULL; ++scan) {
|
||||||
|
m_addresses.push_back(data);
|
||||||
|
data += m_addressLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CNetwork::CHostInfo::swap(CHostInfo& v)
|
||||||
|
{
|
||||||
|
std::swap(m_name, v.m_name);
|
||||||
|
std::swap(m_aliases, v.m_aliases);
|
||||||
|
std::swap(m_addressType, v.m_addressType);
|
||||||
|
std::swap(m_addressLength, v.m_addressLength);
|
||||||
|
std::swap(m_addresses, v.m_addresses);
|
||||||
|
std::swap(m_addressData, v.m_addressData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// CNetwork::CServiceInfo
|
||||||
|
//
|
||||||
|
|
||||||
|
CNetwork::CServiceInfo::CServiceInfo(const struct servent* sent)
|
||||||
|
{
|
||||||
|
assert(sent != NULL);
|
||||||
|
|
||||||
|
m_name = sent->s_name;
|
||||||
|
m_port = sent->s_port;
|
||||||
|
m_protocol = sent->s_proto;
|
||||||
|
for (char** scan = sent->s_aliases; *scan != NULL; ++scan) {
|
||||||
|
m_aliases.push_back(*scan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CNetwork::CServiceInfo::swap(CServiceInfo& v)
|
||||||
|
{
|
||||||
|
std::swap(m_name, v.m_name);
|
||||||
|
std::swap(m_aliases, v.m_aliases);
|
||||||
|
std::swap(m_port, v.m_port);
|
||||||
|
std::swap(m_protocol, v.m_protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// CNetwork::CProtocolInfo
|
||||||
|
//
|
||||||
|
|
||||||
|
CNetwork::CProtocolInfo::CProtocolInfo(const struct protoent* pent)
|
||||||
|
{
|
||||||
|
assert(pent != NULL);
|
||||||
|
|
||||||
|
m_name = pent->p_name;
|
||||||
|
m_protocol = pent->p_proto;
|
||||||
|
for (char** scan = pent->p_aliases; *scan != NULL; ++scan) {
|
||||||
|
m_aliases.push_back(*scan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CNetwork::CProtocolInfo::swap(CProtocolInfo& v)
|
||||||
|
{
|
||||||
|
std::swap(m_name, v.m_name);
|
||||||
|
std::swap(m_aliases, v.m_aliases);
|
||||||
|
std::swap(m_protocol, v.m_protocol);
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#define CNETWORK_H
|
#define CNETWORK_H
|
||||||
|
|
||||||
#include "BasicTypes.h"
|
#include "BasicTypes.h"
|
||||||
|
#include "CString.h"
|
||||||
|
#include "stdvector.h"
|
||||||
|
|
||||||
#if HAVE_SYS_TYPES_H
|
#if HAVE_SYS_TYPES_H
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
|
@ -82,6 +84,61 @@ public:
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//! Host name information
|
||||||
|
class CHostInfo {
|
||||||
|
public:
|
||||||
|
CHostInfo() { }
|
||||||
|
CHostInfo(const struct hostent*);
|
||||||
|
|
||||||
|
void swap(CHostInfo&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef std::vector<CString> AliasList;
|
||||||
|
typedef std::vector<const char*> AddressList;
|
||||||
|
|
||||||
|
CString m_name;
|
||||||
|
AliasList m_aliases;
|
||||||
|
int m_addressType;
|
||||||
|
int m_addressLength;
|
||||||
|
AddressList m_addresses;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_addressData;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Network service information
|
||||||
|
class CServiceInfo {
|
||||||
|
public:
|
||||||
|
CServiceInfo() { }
|
||||||
|
CServiceInfo(const struct servent*);
|
||||||
|
|
||||||
|
void swap(CServiceInfo&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef std::vector<CString> AliasList;
|
||||||
|
|
||||||
|
CString m_name;
|
||||||
|
AliasList m_aliases;
|
||||||
|
int m_port;
|
||||||
|
CString m_protocol;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Network protocol information
|
||||||
|
class CProtocolInfo {
|
||||||
|
public:
|
||||||
|
CProtocolInfo() { }
|
||||||
|
CProtocolInfo(const struct protoent*);
|
||||||
|
|
||||||
|
void swap(CProtocolInfo&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef std::vector<CString> AliasList;
|
||||||
|
|
||||||
|
CString m_name;
|
||||||
|
AliasList m_aliases;
|
||||||
|
int m_protocol;
|
||||||
|
};
|
||||||
|
|
||||||
//! @name manipulators
|
//! @name manipulators
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
|
@ -142,7 +199,7 @@ public:
|
||||||
kNO_RECOVERY = NO_RECOVERY,
|
kNO_RECOVERY = NO_RECOVERY,
|
||||||
kTRY_AGAIN = TRY_AGAIN,
|
kTRY_AGAIN = TRY_AGAIN,
|
||||||
#endif
|
#endif
|
||||||
kHNone = 0
|
kHOST_OK = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
@ -158,7 +215,7 @@ public:
|
||||||
static int (PASCAL FAR *getsockname)(Socket s, Address FAR *name, AddressLength FAR * namelen);
|
static int (PASCAL FAR *getsockname)(Socket s, Address FAR *name, AddressLength FAR * namelen);
|
||||||
static int (PASCAL FAR *getsockopt)(Socket s, int level, int optname, void FAR * optval, AddressLength FAR *optlen);
|
static int (PASCAL FAR *getsockopt)(Socket s, int level, int optname, void FAR * optval, AddressLength FAR *optlen);
|
||||||
static unsigned long (PASCAL FAR *inet_addr)(const char FAR * cp);
|
static unsigned long (PASCAL FAR *inet_addr)(const char FAR * cp);
|
||||||
static char FAR * (PASCAL FAR *inet_ntoa)(struct in_addr in);
|
static CString PASCAL FAR inet_ntoa(struct in_addr in);
|
||||||
static int (PASCAL FAR *listen)(Socket s, int backlog);
|
static int (PASCAL FAR *listen)(Socket s, int backlog);
|
||||||
static ssize_t (PASCAL FAR *read)(Socket s, void FAR * buf, size_t len);
|
static ssize_t (PASCAL FAR *read)(Socket s, void FAR * buf, size_t len);
|
||||||
static ssize_t (PASCAL FAR *recv)(Socket s, void FAR * buf, size_t len, int flags);
|
static ssize_t (PASCAL FAR *recv)(Socket s, void FAR * buf, size_t len, int flags);
|
||||||
|
@ -170,27 +227,26 @@ public:
|
||||||
static int (PASCAL FAR *shutdown)(Socket s, int how);
|
static int (PASCAL FAR *shutdown)(Socket s, int how);
|
||||||
static Socket (PASCAL FAR *socket)(int af, int type, int protocol);
|
static Socket (PASCAL FAR *socket)(int af, int type, int protocol);
|
||||||
static ssize_t (PASCAL FAR *write)(Socket s, const void FAR * buf, size_t len);
|
static ssize_t (PASCAL FAR *write)(Socket s, const void FAR * buf, size_t len);
|
||||||
static struct hostent FAR * (PASCAL FAR *gethostbyaddr)(const char FAR * addr, int len, int type);
|
|
||||||
static struct hostent FAR * (PASCAL FAR *gethostbyname)(const char FAR * name);
|
|
||||||
static int (PASCAL FAR *gethostname)(char FAR * name, int namelen);
|
static int (PASCAL FAR *gethostname)(char FAR * name, int namelen);
|
||||||
static struct servent FAR * (PASCAL FAR *getservbyport)(int port, const char FAR * proto);
|
static int PASCAL FAR gethostbyaddr(CHostInfo* hostinfo, const char FAR * addr, int len, int type);
|
||||||
static struct servent FAR * (PASCAL FAR *getservbyname)(const char FAR * name, const char FAR * proto);
|
static int PASCAL FAR gethostbyname(CHostInfo* hostinfo, const char FAR * name);
|
||||||
static struct protoent FAR * (PASCAL FAR *getprotobynumber)(int proto);
|
static int PASCAL FAR getservbyport(CServiceInfo* servinfo, int port, const char FAR * proto);
|
||||||
static struct protoent FAR * (PASCAL FAR *getprotobyname)(const char FAR * name);
|
static int PASCAL FAR getservbyname(CServiceInfo* servinfo, const char FAR * name, const char FAR * proto);
|
||||||
|
static int PASCAL FAR getprotobynumber(CProtocolInfo* protoinfo, int proto);
|
||||||
|
static int PASCAL FAR getprotobyname(CProtocolInfo* protoinfo, const char FAR * name);
|
||||||
static int (PASCAL FAR *getsockerror)(void);
|
static int (PASCAL FAR *getsockerror)(void);
|
||||||
static int (PASCAL FAR *gethosterror)(void);
|
|
||||||
|
|
||||||
// convenience functions (only available after init())
|
// convenience functions (only available after init())
|
||||||
|
|
||||||
//! Set socket to (non-)blocking operation
|
//! Set socket to (non-)blocking operation
|
||||||
static int (PASCAL FAR *setblocking)(CNetwork::Socket s, bool blocking);
|
static int PASCAL FAR setblocking(CNetwork::Socket s, bool blocking);
|
||||||
|
|
||||||
//! Turn Nagle algorithm on or off on socket
|
//! Turn Nagle algorithm on or off on socket
|
||||||
/*!
|
/*!
|
||||||
Set socket to send messages immediately (true) or to collect small
|
Set socket to send messages immediately (true) or to collect small
|
||||||
messages into one packet (false).
|
messages into one packet (false).
|
||||||
*/
|
*/
|
||||||
static int (PASCAL FAR *setnodelay)(CNetwork::Socket s, bool nodelay);
|
static int PASCAL FAR setnodelay(CNetwork::Socket s, bool nodelay);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if WINDOWS_LIKE
|
#if WINDOWS_LIKE
|
||||||
|
@ -200,19 +256,40 @@ private:
|
||||||
static void init2(HMODULE);
|
static void init2(HMODULE);
|
||||||
static ssize_t PASCAL FAR read2(Socket s, void FAR * buf, size_t len);
|
static ssize_t PASCAL FAR read2(Socket s, void FAR * buf, size_t len);
|
||||||
static ssize_t PASCAL FAR write2(Socket s, const void FAR * buf, size_t len);
|
static ssize_t PASCAL FAR write2(Socket s, const void FAR * buf, size_t len);
|
||||||
static int PASCAL FAR setblocking2(CNetwork::Socket s, bool blocking);
|
|
||||||
static int PASCAL FAR setnodelay2(CNetwork::Socket s, bool nodelay);
|
|
||||||
static int (PASCAL FAR *WSACleanup)(void);
|
static int (PASCAL FAR *WSACleanup)(void);
|
||||||
static int (PASCAL FAR *__WSAFDIsSet)(CNetwork::Socket, fd_set FAR *);
|
static int (PASCAL FAR *__WSAFDIsSet)(CNetwork::Socket, fd_set FAR *);
|
||||||
static int (PASCAL FAR *select)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout);
|
static int (PASCAL FAR *select)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout);
|
||||||
|
static char FAR * (PASCAL FAR *inet_ntoa_n)(struct in_addr in);
|
||||||
|
static struct hostent FAR * (PASCAL FAR *gethostbyaddr_n)(const char FAR * addr, int len, int type);
|
||||||
|
static struct hostent FAR * (PASCAL FAR *gethostbyname_n)(const char FAR * name);
|
||||||
|
static struct servent FAR * (PASCAL FAR *getservbyport_n)(int port, const char FAR * proto);
|
||||||
|
static struct servent FAR * (PASCAL FAR *getservbyname_n)(const char FAR * name, const char FAR * proto);
|
||||||
|
static struct protoent FAR * (PASCAL FAR *getprotobynumber_n)(int proto);
|
||||||
|
static struct protoent FAR * (PASCAL FAR *getprotobyname_n)(const char FAR * name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if UNIX_LIKE
|
#if UNIX_LIKE
|
||||||
static int PASCAL FAR gethostname2(char FAR * name, int namelen);
|
static int PASCAL FAR gethostname2(char FAR * name, int namelen);
|
||||||
static int PASCAL FAR getsockerror2(void);
|
static int PASCAL FAR getsockerror2(void);
|
||||||
static int PASCAL FAR gethosterror2(void);
|
#endif
|
||||||
static int PASCAL FAR setblocking2(CNetwork::Socket s, bool blocking);
|
|
||||||
static int PASCAL FAR setnodelay2(CNetwork::Socket s, bool nodelay);
|
#if WINDOWS_LIKE || UNIX_LIKE
|
||||||
|
/* FIXME -- reentrant netdb stuff
|
||||||
|
create classes for hostent, servent, protoent.
|
||||||
|
each class can clean itself up automatically.
|
||||||
|
inside CNetwork we'll convert from netdb structs to classes.
|
||||||
|
clients will pass a class pointer which CNetwork will assign to (or swap into).
|
||||||
|
won't need free...() functions to clean up structs.
|
||||||
|
each class should know how to copy from respective netdb struct.
|
||||||
|
will need to fix CNetworkAddress to use classes.
|
||||||
|
*/
|
||||||
|
static void copyhostent(struct hostent FAR * dst, const struct hostent FAR * src);
|
||||||
|
static void copyservent(struct servent FAR * dst, const struct servent FAR * src);
|
||||||
|
static void copyprotoent(struct protoent FAR * dst, const struct protoent FAR * src);
|
||||||
|
|
||||||
|
static void freehostent(struct hostent FAR * ent);
|
||||||
|
static void freeservent(struct servent FAR * ent);
|
||||||
|
static void freeprotoent(struct protoent FAR * ent);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WINDOWS_LIKE || !HAVE_POLL
|
#if WINDOWS_LIKE || !HAVE_POLL
|
||||||
|
|
|
@ -126,27 +126,29 @@ CNetworkAddress::CNetworkAddress(const CString& hostname_, UInt16 port) :
|
||||||
}
|
}
|
||||||
|
|
||||||
// look up name
|
// look up name
|
||||||
struct hostent* hent = CNetwork::gethostbyname(hostname.c_str());
|
CNetwork::CHostInfo hostInfo;
|
||||||
if (hent == NULL) {
|
switch (CNetwork::gethostbyname(&hostInfo, hostname.c_str())) {
|
||||||
switch (CNetwork::gethosterror()) {
|
case CNetwork::kHOST_OK:
|
||||||
case CNetwork::kHOST_NOT_FOUND:
|
break;
|
||||||
throw XSocketAddress(XSocketAddress::kNotFound, hostname, port);
|
|
||||||
|
|
||||||
case CNetwork::kNO_DATA:
|
case CNetwork::kHOST_NOT_FOUND:
|
||||||
throw XSocketAddress(XSocketAddress::kNoAddress, hostname, port);
|
throw XSocketAddress(XSocketAddress::kNotFound, hostname, port);
|
||||||
|
|
||||||
case CNetwork::kNO_RECOVERY:
|
case CNetwork::kNO_DATA:
|
||||||
case CNetwork::kTRY_AGAIN:
|
throw XSocketAddress(XSocketAddress::kNoAddress, hostname, port);
|
||||||
default:
|
|
||||||
throw XSocketAddress(XSocketAddress::kUnknown, hostname, port);
|
case CNetwork::kNO_RECOVERY:
|
||||||
}
|
case CNetwork::kTRY_AGAIN:
|
||||||
|
default:
|
||||||
|
throw XSocketAddress(XSocketAddress::kUnknown, hostname, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_in* inetAddress = reinterpret_cast<
|
struct sockaddr_in* inetAddress = reinterpret_cast<
|
||||||
struct sockaddr_in*>(&m_address);
|
struct sockaddr_in*>(&m_address);
|
||||||
inetAddress->sin_family = hent->h_addrtype;
|
inetAddress->sin_family = hostInfo.m_addressType;
|
||||||
inetAddress->sin_port = CNetwork::swaphtons(port);
|
inetAddress->sin_port = CNetwork::swaphtons(port);
|
||||||
memcpy(&inetAddress->sin_addr, hent->h_addr_list[0], hent->h_length);
|
memcpy(&inetAddress->sin_addr, hostInfo.m_addresses[0],
|
||||||
|
hostInfo.m_addressLength);
|
||||||
memset(inetAddress->sin_zero, 0, sizeof(inetAddress->sin_zero));
|
memset(inetAddress->sin_zero, 0, sizeof(inetAddress->sin_zero));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue