src: IPv6 support for Windows and Linux
NOT MY WORK! Updated patches from the following: From adabfe11d45e9e8fd5bfc445dc02ea80497c308f Mon Sep 17 00:00:00 2001 From: WilliamKyle <williamkyle@126.com> Date: Thu, 2 Apr 2015 23:45:56 +0800 Subject: [PATCH 1/2] IPv6 support for Windows and Linux From a4c7ec47ad2447e8bcbb2fa99aac370c0b50d429 Mon Sep 17 00:00:00 2001 From: Fabian Krueger <krueger.fabian@gmail.com> Date: Sat, 29 Oct 2016 20:21:54 +0200 Subject: [PATCH 2/2] Fix build issue with IpcServer after applying ipv6 patch PR #4499 https://github.com/symless/synergy-core/pull/4499 Fixes Issue #4325 https://github.com/symless/synergy-core/issues/4325
This commit is contained in:
parent
426e81fa71
commit
a93338e90f
|
@ -64,6 +64,7 @@ public:
|
|||
enum EAddressFamily {
|
||||
kUNKNOWN,
|
||||
kINET,
|
||||
kINET6,
|
||||
};
|
||||
|
||||
//! Supported socket types
|
||||
|
|
|
@ -52,7 +52,8 @@
|
|||
|
||||
static const int s_family[] = {
|
||||
PF_UNSPEC,
|
||||
PF_INET
|
||||
PF_INET,
|
||||
PF_INET6,
|
||||
};
|
||||
static const int s_type[] = {
|
||||
SOCK_DGRAM,
|
||||
|
@ -190,7 +191,7 @@ ArchNetworkBSD::bindSocket(ArchSocket s, ArchNetAddress addr)
|
|||
assert(s != NULL);
|
||||
assert(addr != NULL);
|
||||
|
||||
if (bind(s->m_fd, &addr->m_addr, addr->m_len) == -1) {
|
||||
if (bind(s->m_fd, TYPED_ADDR(struct sockaddr, addr), addr->m_len) == -1) {
|
||||
throwError(errno);
|
||||
}
|
||||
}
|
||||
|
@ -223,7 +224,7 @@ ArchNetworkBSD::acceptSocket(ArchSocket s, ArchNetAddress* addr)
|
|||
|
||||
// accept on socket
|
||||
auto len = ((*addr)->m_len);
|
||||
int fd = accept(s->m_fd, &(*addr)->m_addr, &len);
|
||||
int fd = accept(s->m_fd, TYPED_ADDR(struct sockaddr, (*addr)), &len);
|
||||
(*addr)->m_len = len;
|
||||
if (fd == -1) {
|
||||
int err = errno;
|
||||
|
@ -265,7 +266,7 @@ ArchNetworkBSD::connectSocket(ArchSocket s, ArchNetAddress addr)
|
|||
assert(s != NULL);
|
||||
assert(addr != NULL);
|
||||
|
||||
if (connect(s->m_fd, &addr->m_addr, addr->m_len) == -1) {
|
||||
if (connect(s->m_fd, TYPED_ADDR(struct sockaddr, addr), addr->m_len) == -1) {
|
||||
if (errno == EISCONN) {
|
||||
return true;
|
||||
}
|
||||
|
@ -644,8 +645,7 @@ ArchNetworkBSD::newAnyAddr(EAddressFamily family)
|
|||
// fill it in
|
||||
switch (family) {
|
||||
case kINET: {
|
||||
auto* ipAddr =
|
||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
||||
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||
ipAddr->sin_family = AF_INET;
|
||||
ipAddr->sin_port = 0;
|
||||
ipAddr->sin_addr.s_addr = INADDR_ANY;
|
||||
|
@ -653,6 +653,14 @@ ArchNetworkBSD::newAnyAddr(EAddressFamily family)
|
|||
break;
|
||||
}
|
||||
|
||||
case kINET6: {
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
ipAddr->sin6_family = AF_INET6;
|
||||
ipAddr->sin6_port = 0;
|
||||
memcpy(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any));
|
||||
addr->m_len = (socklen_t)sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
delete addr;
|
||||
assert(0 && "invalid family");
|
||||
|
@ -676,48 +684,31 @@ ArchNetworkBSD::nameToAddr(const std::string& name)
|
|||
// allocate address
|
||||
auto* addr = new ArchNetAddressImpl;
|
||||
|
||||
// try to convert assuming an IPv4 dot notation address
|
||||
struct sockaddr_in inaddr{};
|
||||
memset(&inaddr, 0, sizeof(inaddr));
|
||||
if (inet_aton(name.c_str(), &inaddr.sin_addr) != 0) {
|
||||
// it's a dot notation address
|
||||
addr->m_len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
|
||||
inaddr.sin_family = AF_INET;
|
||||
inaddr.sin_port = 0;
|
||||
memcpy(&addr->m_addr, &inaddr, addr->m_len);
|
||||
}
|
||||
char ipstr[INET6_ADDRSTRLEN];
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *p;
|
||||
int ret;
|
||||
|
||||
else {
|
||||
// mutexed address lookup (ugh)
|
||||
ARCH->lockMutex(m_mutex);
|
||||
struct hostent* info = gethostbyname(name.c_str());
|
||||
if (info == nullptr) {
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
delete addr;
|
||||
throwNameError(h_errno);
|
||||
}
|
||||
|
||||
// copy over address (only IPv4 currently supported)
|
||||
if (info->h_addrtype == AF_INET) {
|
||||
addr->m_len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
|
||||
inaddr.sin_family = info->h_addrtype;
|
||||
inaddr.sin_port = 0;
|
||||
memcpy(&inaddr.sin_addr, info->h_addr_list[0],
|
||||
sizeof(inaddr.sin_addr));
|
||||
memcpy(&addr->m_addr, &inaddr, addr->m_len);
|
||||
}
|
||||
else {
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
delete addr;
|
||||
throw XArchNetworkNameUnsupported(
|
||||
"The requested name is valid but "
|
||||
"does not have a supported address family");
|
||||
}
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
|
||||
// done with static buffer
|
||||
ARCH->lockMutex(m_mutex);
|
||||
if ((ret = getaddrinfo(name.c_str(), NULL, &hints, &p)) != 0) {
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
delete addr;
|
||||
throwNameError(ret);
|
||||
}
|
||||
|
||||
if (p->ai_family == AF_INET) {
|
||||
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
|
||||
} else {
|
||||
addr->m_len = (socklen_t)sizeof(struct sockaddr_in6);
|
||||
}
|
||||
memcpy(&addr->m_addr, p->ai_addr, addr->m_len);
|
||||
freeaddrinfo(p);
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
@ -736,15 +727,16 @@ ArchNetworkBSD::addrToName(ArchNetAddress addr)
|
|||
|
||||
// mutexed name lookup (ugh)
|
||||
ARCH->lockMutex(m_mutex);
|
||||
struct hostent* info = gethostbyaddr(&addr->m_addr,
|
||||
addr->m_len, addr->m_addr.sa_family);
|
||||
if (info == nullptr) {
|
||||
char host[1024];
|
||||
char service[20];
|
||||
int ret = getnameinfo(TYPED_ADDR(struct sockaddr, addr), addr->m_len, host, sizeof(host), service, sizeof(service), 0);
|
||||
if (ret != 0) {
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
throwNameError(h_errno);
|
||||
throwNameError(ret);
|
||||
}
|
||||
|
||||
// save (primary) name
|
||||
std::string name = info->h_name;
|
||||
std::string name = host;
|
||||
|
||||
// done with static buffer
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
|
@ -759,14 +751,22 @@ ArchNetworkBSD::addrToString(ArchNetAddress addr)
|
|||
|
||||
switch (getAddrFamily(addr)) {
|
||||
case kINET: {
|
||||
auto* ipAddr =
|
||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
||||
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||
ARCH->lockMutex(m_mutex);
|
||||
std::string s = inet_ntoa(ipAddr->sin_addr);
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
return s;
|
||||
}
|
||||
|
||||
case kINET6: {
|
||||
char strAddr[INET6_ADDRSTRLEN];
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
ARCH->lockMutex(m_mutex);
|
||||
inet_ntop(AF_INET6, &ipAddr->sin6_addr, strAddr, INET6_ADDRSTRLEN);
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
return strAddr;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0 && "unknown address family");
|
||||
return "";
|
||||
|
@ -778,9 +778,11 @@ ArchNetworkBSD::getAddrFamily(ArchNetAddress addr)
|
|||
{
|
||||
assert(addr != NULL);
|
||||
|
||||
switch (addr->m_addr.sa_family) {
|
||||
switch (addr->m_addr.ss_family) {
|
||||
case AF_INET:
|
||||
return kINET;
|
||||
case AF_INET6:
|
||||
return kINET6;
|
||||
|
||||
default:
|
||||
return kUNKNOWN;
|
||||
|
@ -794,12 +796,17 @@ ArchNetworkBSD::setAddrPort(ArchNetAddress addr, int port)
|
|||
|
||||
switch (getAddrFamily(addr)) {
|
||||
case kINET: {
|
||||
auto* ipAddr =
|
||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
||||
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||
ipAddr->sin_port = htons(port);
|
||||
break;
|
||||
}
|
||||
|
||||
case kINET6: {
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
ipAddr->sin6_port = htons(port);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0 && "unknown address family");
|
||||
break;
|
||||
|
@ -813,11 +820,15 @@ ArchNetworkBSD::getAddrPort(ArchNetAddress addr)
|
|||
|
||||
switch (getAddrFamily(addr)) {
|
||||
case kINET: {
|
||||
auto* ipAddr =
|
||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
||||
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||
return ntohs(ipAddr->sin_port);
|
||||
}
|
||||
|
||||
case kINET6: {
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
return ntohs(ipAddr->sin6_port);
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0 && "unknown address family");
|
||||
return 0;
|
||||
|
@ -831,12 +842,17 @@ ArchNetworkBSD::isAnyAddr(ArchNetAddress addr)
|
|||
|
||||
switch (getAddrFamily(addr)) {
|
||||
case kINET: {
|
||||
auto* ipAddr =
|
||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
||||
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||
return (ipAddr->sin_addr.s_addr == INADDR_ANY &&
|
||||
addr->m_len == static_cast<socklen_t>(sizeof(struct sockaddr_in)));
|
||||
}
|
||||
|
||||
case kINET6: {
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
return (memcmp(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
|
||||
addr->m_len == (socklen_t)sizeof(struct sockaddr_in6));
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0 && "unknown address family");
|
||||
return true;
|
||||
|
|
|
@ -38,6 +38,7 @@ typedef int socklen_t;
|
|||
typedef char optval_t;
|
||||
|
||||
#define ARCH_NETWORK ArchNetworkBSD
|
||||
#define TYPED_ADDR(type_, addr_) (reinterpret_cast<type_*>(&addr_->m_addr))
|
||||
|
||||
class ArchSocketImpl {
|
||||
public:
|
||||
|
@ -50,7 +51,7 @@ public:
|
|||
ArchNetAddressImpl() : m_len(sizeof(m_addr)) { }
|
||||
|
||||
public:
|
||||
struct sockaddr m_addr;
|
||||
struct sockaddr_storage m_addr;
|
||||
socklen_t m_len;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
|
||||
static const int s_family[] = {
|
||||
PF_UNSPEC,
|
||||
PF_INET
|
||||
PF_INET,
|
||||
PF_INET6,
|
||||
};
|
||||
static const int s_type[] = {
|
||||
SOCK_DGRAM,
|
||||
|
@ -156,7 +157,7 @@ ArchNetworkWinsock::initModule(HMODULE module)
|
|||
setfunc(startup, WSAStartup, int(PASCAL FAR*)(WORD, LPWSADATA));
|
||||
|
||||
// startup network library
|
||||
WORD version = MAKEWORD(2 /*major*/, 0 /*minor*/);
|
||||
WORD version = MAKEWORD(2 /*major*/, 2 /*minor*/);
|
||||
WSADATA data;
|
||||
int err = startup(version, &data);
|
||||
if (data.wVersion != version) {
|
||||
|
@ -212,6 +213,11 @@ ArchNetworkWinsock::newSocket(EAddressFamily family, ESocketType type)
|
|||
}
|
||||
try {
|
||||
setBlockingOnSocket(fd, false);
|
||||
BOOL flag = 0;
|
||||
int size = sizeof(flag);
|
||||
if (setsockopt_winsock(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, size) == SOCKET_ERROR) {
|
||||
throwError(getsockerror_winsock());
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
close_winsock(fd);
|
||||
|
@ -294,7 +300,7 @@ ArchNetworkWinsock::bindSocket(ArchSocket s, ArchNetAddress addr)
|
|||
assert(s != NULL);
|
||||
assert(addr != NULL);
|
||||
|
||||
if (bind_winsock(s->m_socket, &addr->m_addr, addr->m_len) == SOCKET_ERROR) {
|
||||
if (bind_winsock(s->m_socket, TYPED_ADDR(struct sockaddr, addr), addr->m_len) == SOCKET_ERROR) {
|
||||
throwError(getsockerror_winsock());
|
||||
}
|
||||
}
|
||||
|
@ -317,10 +323,10 @@ ArchNetworkWinsock::acceptSocket(ArchSocket s, ArchNetAddress* const addr)
|
|||
|
||||
// create new socket and temporary address
|
||||
ArchSocketImpl* socket = new ArchSocketImpl;
|
||||
ArchNetAddress tmp = ArchNetAddressImpl::alloc(sizeof(struct sockaddr));
|
||||
ArchNetAddress tmp = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in6));
|
||||
|
||||
// accept on socket
|
||||
SOCKET fd = accept_winsock(s->m_socket, &tmp->m_addr, &tmp->m_len);
|
||||
SOCKET fd = accept_winsock(s->m_socket, TYPED_ADDR(struct sockaddr, tmp), &tmp->m_len);
|
||||
if (fd == INVALID_SOCKET) {
|
||||
int err = getsockerror_winsock();
|
||||
delete socket;
|
||||
|
@ -368,7 +374,7 @@ ArchNetworkWinsock::connectSocket(ArchSocket s, ArchNetAddress addr)
|
|||
assert(s != NULL);
|
||||
assert(addr != NULL);
|
||||
|
||||
if (connect_winsock(s->m_socket, &addr->m_addr,
|
||||
if (connect_winsock(s->m_socket, TYPED_ADDR(struct sockaddr, addr),
|
||||
addr->m_len) == SOCKET_ERROR) {
|
||||
if (getsockerror_winsock() == WSAEISCONN) {
|
||||
return true;
|
||||
|
@ -685,6 +691,15 @@ ArchNetworkWinsock::newAnyAddr(EAddressFamily family)
|
|||
break;
|
||||
}
|
||||
|
||||
case kINET6: {
|
||||
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in6));
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
ipAddr->sin6_family = AF_INET6;
|
||||
ipAddr->sin6_port = 0;
|
||||
memcpy(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0 && "invalid family");
|
||||
}
|
||||
|
@ -705,41 +720,31 @@ ArchNetAddress
|
|||
ArchNetworkWinsock::nameToAddr(const std::string& name)
|
||||
{
|
||||
// allocate address
|
||||
ArchNetAddressImpl* addr = NULL;
|
||||
|
||||
// try to convert assuming an IPv4 dot notation address
|
||||
struct sockaddr_in inaddr;
|
||||
memset(&inaddr, 0, sizeof(inaddr));
|
||||
inaddr.sin_family = AF_INET;
|
||||
inaddr.sin_port = 0;
|
||||
inaddr.sin_addr.s_addr = inet_addr_winsock(name.c_str());
|
||||
if (inaddr.sin_addr.s_addr != INADDR_NONE) {
|
||||
// it's a dot notation address
|
||||
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in));
|
||||
memcpy(TYPED_ADDR(void, addr), &inaddr, addr->m_len);
|
||||
ArchNetAddressImpl* addr = new ArchNetAddressImpl;
|
||||
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *p;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
int ret = -1;
|
||||
|
||||
ARCH->lockMutex(m_mutex);
|
||||
if ((ret = getaddrinfo(name.c_str(), NULL, &hints, &p)) != 0) {
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
delete addr;
|
||||
throwNameError(ret);
|
||||
}
|
||||
|
||||
else {
|
||||
// address lookup
|
||||
struct hostent* info = gethostbyname_winsock(name.c_str());
|
||||
if (info == NULL) {
|
||||
throwNameError(getsockerror_winsock());
|
||||
}
|
||||
|
||||
// copy over address (only IPv4 currently supported)
|
||||
if (info->h_addrtype == AF_INET) {
|
||||
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in));
|
||||
memcpy(&inaddr.sin_addr, info->h_addr_list[0],
|
||||
sizeof(inaddr.sin_addr));
|
||||
memcpy(TYPED_ADDR(void, addr), &inaddr, addr->m_len);
|
||||
}
|
||||
else {
|
||||
throw XArchNetworkNameUnsupported(
|
||||
"The requested name is valid but "
|
||||
"does not have a supported address family");
|
||||
}
|
||||
if (p->ai_family == AF_INET) {
|
||||
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
|
||||
} else {
|
||||
addr->m_len = (socklen_t)sizeof(struct sockaddr_in6);
|
||||
}
|
||||
|
||||
memcpy(&addr->m_addr, p->ai_addr, addr->m_len);
|
||||
freeaddrinfo(p);
|
||||
ARCH->unlockMutex(m_mutex);
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
@ -756,16 +761,17 @@ ArchNetworkWinsock::addrToName(ArchNetAddress addr)
|
|||
{
|
||||
assert(addr != NULL);
|
||||
|
||||
// name lookup
|
||||
struct hostent* info = gethostbyaddr_winsock(
|
||||
reinterpret_cast<const char FAR*>(&addr->m_addr),
|
||||
addr->m_len, addr->m_addr.sa_family);
|
||||
if (info == NULL) {
|
||||
throwNameError(getsockerror_winsock());
|
||||
char host[1024];
|
||||
char service[20];
|
||||
int ret = getnameinfo(TYPED_ADDR(struct sockaddr, addr), addr->m_len, host, sizeof(host), service, sizeof(service), 0);
|
||||
|
||||
if (ret != NULL) {
|
||||
throwNameError(ret);
|
||||
}
|
||||
|
||||
// return (primary) name
|
||||
return info->h_name;
|
||||
std::string name = host;
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string
|
||||
|
@ -775,11 +781,17 @@ ArchNetworkWinsock::addrToString(ArchNetAddress addr)
|
|||
|
||||
switch (getAddrFamily(addr)) {
|
||||
case kINET: {
|
||||
struct sockaddr_in* ipAddr =
|
||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
||||
struct sockaddr_in* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||
return inet_ntoa_winsock(ipAddr->sin_addr);
|
||||
}
|
||||
|
||||
case kINET6: {
|
||||
char strAddr[INET6_ADDRSTRLEN];
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
inet_ntop(AF_INET6, &ipAddr->sin6_addr, strAddr, INET6_ADDRSTRLEN);
|
||||
return strAddr;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0 && "unknown address family");
|
||||
return "";
|
||||
|
@ -791,10 +803,13 @@ ArchNetworkWinsock::getAddrFamily(ArchNetAddress addr)
|
|||
{
|
||||
assert(addr != NULL);
|
||||
|
||||
switch (addr->m_addr.sa_family) {
|
||||
switch (addr->m_addr.ss_family) {
|
||||
case AF_INET:
|
||||
return kINET;
|
||||
|
||||
case AF_INET6:
|
||||
return kINET6;
|
||||
|
||||
default:
|
||||
return kUNKNOWN;
|
||||
}
|
||||
|
@ -807,9 +822,14 @@ ArchNetworkWinsock::setAddrPort(ArchNetAddress addr, int port)
|
|||
|
||||
switch (getAddrFamily(addr)) {
|
||||
case kINET: {
|
||||
struct sockaddr_in* ipAddr =
|
||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
||||
ipAddr->sin_port = htons_winsock(port);
|
||||
struct sockaddr_in* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||
ipAddr->sin_port = htons_winsock(static_cast<u_short>(port));
|
||||
break;
|
||||
}
|
||||
|
||||
case kINET6: {
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
ipAddr->sin6_port = htons_winsock(static_cast<u_short>(port));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -826,11 +846,15 @@ ArchNetworkWinsock::getAddrPort(ArchNetAddress addr)
|
|||
|
||||
switch (getAddrFamily(addr)) {
|
||||
case kINET: {
|
||||
struct sockaddr_in* ipAddr =
|
||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
||||
struct sockaddr_in* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||
return ntohs_winsock(ipAddr->sin_port);
|
||||
}
|
||||
|
||||
case kINET6: {
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
return ntohs_winsock(ipAddr->sin6_port);
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0 && "unknown address family");
|
||||
return 0;
|
||||
|
@ -844,12 +868,17 @@ ArchNetworkWinsock::isAnyAddr(ArchNetAddress addr)
|
|||
|
||||
switch (getAddrFamily(addr)) {
|
||||
case kINET: {
|
||||
struct sockaddr_in* ipAddr =
|
||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
||||
struct sockaddr_in* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||
return (addr->m_len == sizeof(struct sockaddr_in) &&
|
||||
ipAddr->sin_addr.s_addr == INADDR_ANY);
|
||||
}
|
||||
|
||||
case kINET6: {
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
return (addr->m_len == sizeof(struct sockaddr_in) &&
|
||||
memcmp(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any))== 0);
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0 && "unknown address family");
|
||||
return true;
|
||||
|
|
|
@ -18,8 +18,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <ws2tcpip.h>
|
||||
// declare no functions in winsock2
|
||||
#ifndef INCL_WINSOCK_API_PROTOTYPES
|
||||
#define INCL_WINSOCK_API_PROTOTYPES 0
|
||||
#endif
|
||||
#define INCL_WINSOCK_API_TYPEDEFS 0
|
||||
|
||||
#include "arch/IArchNetwork.h"
|
||||
|
@ -30,6 +33,8 @@
|
|||
#include <Windows.h>
|
||||
#include <list>
|
||||
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
#define ARCH_NETWORK ArchNetworkWinsock
|
||||
|
||||
class ArchSocketImpl {
|
||||
|
@ -46,7 +51,7 @@ public:
|
|||
|
||||
public:
|
||||
int m_len;
|
||||
struct sockaddr m_addr;
|
||||
struct sockaddr_storage m_addr;
|
||||
};
|
||||
#define ADDR_HDR_SIZE offsetof(ArchNetAddressImpl, m_addr)
|
||||
#define TYPED_ADDR(type_, addr_) (reinterpret_cast<type_*>(&addr_->m_addr))
|
||||
|
|
|
@ -146,7 +146,7 @@ Client::connect()
|
|||
}
|
||||
|
||||
// create the socket
|
||||
IDataSocket* socket = m_socketFactory->create();
|
||||
IDataSocket* socket = m_socketFactory->create(ARCH->getAddrFamily(m_serverAddress.getAddress()));
|
||||
m_socket = dynamic_cast<TCPSocket*>(socket);
|
||||
|
||||
// filter socket messages, including a packetizing filter
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "common/IInterface.h"
|
||||
#include "arch/IArchNetwork.h"
|
||||
|
||||
class IDataSocket;
|
||||
class IListenSocket;
|
||||
|
@ -34,10 +35,10 @@ public:
|
|||
//@{
|
||||
|
||||
//! Create data socket
|
||||
virtual IDataSocket* create() const = 0;
|
||||
virtual IDataSocket* create(IArchNetwork::EAddressFamily family = IArchNetwork::kINET) const = 0;
|
||||
|
||||
//! Create listen socket
|
||||
virtual IListenSocket* createListen() const = 0;
|
||||
virtual IListenSocket* createListen(IArchNetwork::EAddressFamily family = IArchNetwork::kINET) const = 0;
|
||||
|
||||
//@}
|
||||
};
|
||||
|
|
|
@ -86,7 +86,7 @@ NetworkAddress::NetworkAddress(String hostname, int port) :
|
|||
// notation. in that case we assume it's not a port suffix.
|
||||
// the user can replace the double colon with zeros to
|
||||
// disambiguate.
|
||||
if ((!doubleColon || dotNotation) || !colonNotation) {
|
||||
if ((!doubleColon || dotNotation) && !colonNotation) {
|
||||
// parse port from hostname
|
||||
char* end;
|
||||
const char* chostname = m_hostname.c_str();
|
||||
|
|
|
@ -34,13 +34,13 @@
|
|||
// TCPListenSocket
|
||||
//
|
||||
|
||||
TCPListenSocket::TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer) :
|
||||
TCPListenSocket::TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family) :
|
||||
m_events(events),
|
||||
m_socketMultiplexer(socketMultiplexer)
|
||||
{
|
||||
m_mutex = new Mutex;
|
||||
try {
|
||||
m_socket = ARCH->newSocket(IArchNetwork::kINET, IArchNetwork::kSTREAM);
|
||||
m_socket = ARCH->newSocket(family, IArchNetwork::kSTREAM);
|
||||
}
|
||||
catch (XArchNetwork& e) {
|
||||
throw XSocketCreate(e.what());
|
||||
|
|
|
@ -32,7 +32,7 @@ A listen socket using TCP.
|
|||
*/
|
||||
class TCPListenSocket : public IListenSocket {
|
||||
public:
|
||||
TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer);
|
||||
TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family);
|
||||
virtual ~TCPListenSocket();
|
||||
|
||||
// ISocket overrides
|
||||
|
|
|
@ -37,14 +37,14 @@
|
|||
// TCPSocket
|
||||
//
|
||||
|
||||
TCPSocket::TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer) :
|
||||
TCPSocket::TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family) :
|
||||
IDataSocket(events),
|
||||
m_events(events),
|
||||
m_flushed(&m_mutex, true),
|
||||
m_socketMultiplexer(socketMultiplexer)
|
||||
{
|
||||
try {
|
||||
m_socket = ARCH->newSocket(IArchNetwork::kINET, IArchNetwork::kSTREAM);
|
||||
m_socket = ARCH->newSocket(family, IArchNetwork::kSTREAM);
|
||||
}
|
||||
catch (XArchNetwork& e) {
|
||||
throw XSocketCreate(e.what());
|
||||
|
|
|
@ -36,7 +36,7 @@ A data socket using TCP.
|
|||
*/
|
||||
class TCPSocket : public IDataSocket {
|
||||
public:
|
||||
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer);
|
||||
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family = IArchNetwork::kINET);
|
||||
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, ArchSocket socket);
|
||||
virtual ~TCPSocket();
|
||||
|
||||
|
|
|
@ -39,13 +39,13 @@ TCPSocketFactory::~TCPSocketFactory()
|
|||
}
|
||||
|
||||
IDataSocket*
|
||||
TCPSocketFactory::create() const
|
||||
TCPSocketFactory::create(IArchNetwork::EAddressFamily family) const
|
||||
{
|
||||
return new TCPSocket(m_events, m_socketMultiplexer);
|
||||
return new TCPSocket(m_events, m_socketMultiplexer, family);
|
||||
}
|
||||
|
||||
IListenSocket*
|
||||
TCPSocketFactory::createListen() const
|
||||
TCPSocketFactory::createListen(IArchNetwork::EAddressFamily family) const
|
||||
{
|
||||
return new TCPListenSocket(m_events, m_socketMultiplexer);
|
||||
return new TCPListenSocket(m_events, m_socketMultiplexer, family);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "net/ISocketFactory.h"
|
||||
#include "arch/IArchNetwork.h
|
||||
|
||||
class IEventQueue;
|
||||
class SocketMultiplexer;
|
||||
|
@ -31,9 +32,9 @@ public:
|
|||
|
||||
// ISocketFactory overrides
|
||||
virtual IDataSocket*
|
||||
create() const;
|
||||
create(IArchNetwork::EAddressFamily family = IArchNetwork::kINET) const;
|
||||
virtual IListenSocket*
|
||||
createListen() const;
|
||||
createListen(IArchNetwork::EAddressFamily family = IArchNetwork::kINET) const;
|
||||
|
||||
private:
|
||||
IEventQueue* m_events;
|
||||
|
|
|
@ -43,7 +43,7 @@ ClientListener::ClientListener(const NetworkAddress& address,
|
|||
assert(m_socketFactory != NULL);
|
||||
|
||||
try {
|
||||
m_listen = m_socketFactory->createListen();
|
||||
m_listen = m_socketFactory->createListen(ARCH->getAddrFamily(address.getAddress()));
|
||||
|
||||
// setup event handler
|
||||
m_events->adoptHandler(m_events->forIListenSocket().connecting(),
|
||||
|
|
Loading…
Reference in New Issue