Merge pull request #19 from debauchee/ipv6

Add ipv6 support
This commit is contained in:
walker0643 2018-03-24 15:09:20 -04:00 committed by GitHub
commit 9a2d61cbb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 213 additions and 145 deletions

View File

@ -64,6 +64,7 @@ public:
enum EAddressFamily { enum EAddressFamily {
kUNKNOWN, kUNKNOWN,
kINET, kINET,
kINET6,
}; };
//! Supported socket types //! Supported socket types

View File

@ -52,7 +52,8 @@
static const int s_family[] = { static const int s_family[] = {
PF_UNSPEC, PF_UNSPEC,
PF_INET PF_INET,
PF_INET6,
}; };
static const int s_type[] = { static const int s_type[] = {
SOCK_DGRAM, SOCK_DGRAM,
@ -191,7 +192,7 @@ ArchNetworkBSD::bindSocket(ArchSocket s, ArchNetAddress addr)
assert(s != NULL); assert(s != NULL);
assert(addr != 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); throwError(errno);
} }
} }
@ -224,7 +225,7 @@ ArchNetworkBSD::acceptSocket(ArchSocket s, ArchNetAddress* addr)
// accept on socket // accept on socket
ACCEPT_TYPE_ARG3 len = (ACCEPT_TYPE_ARG3)((*addr)->m_len); ACCEPT_TYPE_ARG3 len = (ACCEPT_TYPE_ARG3)((*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 = (socklen_t)len; (*addr)->m_len = (socklen_t)len;
if (fd == -1) { if (fd == -1) {
int err = errno; int err = errno;
@ -266,7 +267,7 @@ ArchNetworkBSD::connectSocket(ArchSocket s, ArchNetAddress addr)
assert(s != NULL); assert(s != NULL);
assert(addr != 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) { if (errno == EISCONN) {
return true; return true;
} }
@ -645,8 +646,7 @@ ArchNetworkBSD::newAnyAddr(EAddressFamily family)
// fill it in // fill it in
switch (family) { switch (family) {
case kINET: { case kINET: {
struct sockaddr_in* ipAddr = auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
ipAddr->sin_family = AF_INET; ipAddr->sin_family = AF_INET;
ipAddr->sin_port = 0; ipAddr->sin_port = 0;
ipAddr->sin_addr.s_addr = INADDR_ANY; ipAddr->sin_addr.s_addr = INADDR_ANY;
@ -654,6 +654,14 @@ ArchNetworkBSD::newAnyAddr(EAddressFamily family)
break; break;
} }
case kINET6: {
auto* 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: default:
delete addr; delete addr;
assert(0 && "invalid family"); assert(0 && "invalid family");
@ -677,48 +685,31 @@ ArchNetworkBSD::nameToAddr(const std::string& name)
// allocate address // allocate address
ArchNetAddressImpl* addr = new ArchNetAddressImpl; ArchNetAddressImpl* addr = new ArchNetAddressImpl;
// try to convert assuming an IPv4 dot notation address char ipstr[INET6_ADDRSTRLEN];
struct sockaddr_in inaddr; struct addrinfo hints;
memset(&inaddr, 0, sizeof(inaddr)); struct addrinfo *p;
if (inet_aton(name.c_str(), &inaddr.sin_addr) != 0) { int ret;
// it's a dot notation address
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
inaddr.sin_family = AF_INET;
inaddr.sin_port = 0;
memcpy(&addr->m_addr, &inaddr, addr->m_len);
}
else { memset(&hints, 0, sizeof(hints));
// mutexed address lookup (ugh) hints.ai_family = AF_UNSPEC;
ARCH->lockMutex(m_mutex);
struct hostent* info = gethostbyname(name.c_str());
if (info == NULL) {
ARCH->unlockMutex(m_mutex);
delete addr;
throwNameError(h_errno);
}
// copy over address (only IPv4 currently supported) ARCH->lockMutex(m_mutex);
if (info->h_addrtype == AF_INET) { if ((ret = getaddrinfo(name.c_str(), NULL, &hints, &p)) != 0) {
addr->m_len = (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");
}
// done with static buffer
ARCH->unlockMutex(m_mutex); 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; return addr;
} }
@ -737,15 +728,17 @@ ArchNetworkBSD::addrToName(ArchNetAddress addr)
// mutexed name lookup (ugh) // mutexed name lookup (ugh)
ARCH->lockMutex(m_mutex); ARCH->lockMutex(m_mutex);
struct hostent* info = gethostbyaddr(&addr->m_addr, char host[1024];
addr->m_len, addr->m_addr.sa_family); char service[20];
if (info == NULL) { 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); ARCH->unlockMutex(m_mutex);
throwNameError(h_errno); throwNameError(ret);
} }
// save (primary) name // save (primary) name
std::string name = info->h_name; std::string name = host;
// done with static buffer // done with static buffer
ARCH->unlockMutex(m_mutex); ARCH->unlockMutex(m_mutex);
@ -760,14 +753,22 @@ ArchNetworkBSD::addrToString(ArchNetAddress addr)
switch (getAddrFamily(addr)) { switch (getAddrFamily(addr)) {
case kINET: { case kINET: {
struct sockaddr_in* ipAddr = auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
ARCH->lockMutex(m_mutex); ARCH->lockMutex(m_mutex);
std::string s = inet_ntoa(ipAddr->sin_addr); std::string s = inet_ntoa(ipAddr->sin_addr);
ARCH->unlockMutex(m_mutex); ARCH->unlockMutex(m_mutex);
return s; return s;
} }
case kINET6: {
char strAddr[INET6_ADDRSTRLEN];
auto* 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: default:
assert(0 && "unknown address family"); assert(0 && "unknown address family");
return ""; return "";
@ -779,9 +780,11 @@ ArchNetworkBSD::getAddrFamily(ArchNetAddress addr)
{ {
assert(addr != NULL); assert(addr != NULL);
switch (addr->m_addr.sa_family) { switch (addr->m_addr.ss_family) {
case AF_INET: case AF_INET:
return kINET; return kINET;
case AF_INET6:
return kINET6;
default: default:
return kUNKNOWN; return kUNKNOWN;
@ -795,12 +798,17 @@ ArchNetworkBSD::setAddrPort(ArchNetAddress addr, int port)
switch (getAddrFamily(addr)) { switch (getAddrFamily(addr)) {
case kINET: { case kINET: {
struct sockaddr_in* ipAddr = auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
ipAddr->sin_port = htons(port); ipAddr->sin_port = htons(port);
break; break;
} }
case kINET6: {
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
ipAddr->sin6_port = htons(port);
break;
}
default: default:
assert(0 && "unknown address family"); assert(0 && "unknown address family");
break; break;
@ -814,11 +822,15 @@ ArchNetworkBSD::getAddrPort(ArchNetAddress addr)
switch (getAddrFamily(addr)) { switch (getAddrFamily(addr)) {
case kINET: { case kINET: {
struct sockaddr_in* ipAddr = auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
return ntohs(ipAddr->sin_port); return ntohs(ipAddr->sin_port);
} }
case kINET6: {
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
return ntohs(ipAddr->sin6_port);
}
default: default:
assert(0 && "unknown address family"); assert(0 && "unknown address family");
return 0; return 0;
@ -832,12 +844,17 @@ ArchNetworkBSD::isAnyAddr(ArchNetAddress addr)
switch (getAddrFamily(addr)) { switch (getAddrFamily(addr)) {
case kINET: { case kINET: {
struct sockaddr_in* ipAddr = auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
return (ipAddr->sin_addr.s_addr == INADDR_ANY && return (ipAddr->sin_addr.s_addr == INADDR_ANY &&
addr->m_len == (socklen_t)sizeof(struct sockaddr_in)); addr->m_len == (socklen_t)sizeof(struct sockaddr_in));
} }
case kINET6: {
auto* 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: default:
assert(0 && "unknown address family"); assert(0 && "unknown address family");
return true; return true;

View File

@ -38,6 +38,7 @@ typedef int socklen_t;
typedef char optval_t; typedef char optval_t;
#define ARCH_NETWORK ArchNetworkBSD #define ARCH_NETWORK ArchNetworkBSD
#define TYPED_ADDR(type_, addr_) (reinterpret_cast<type_*>(&addr_->m_addr))
class ArchSocketImpl { class ArchSocketImpl {
public: public:
@ -50,8 +51,8 @@ public:
ArchNetAddressImpl() : m_len(sizeof(m_addr)) { } ArchNetAddressImpl() : m_len(sizeof(m_addr)) { }
public: public:
struct sockaddr m_addr; struct sockaddr_storage m_addr;
socklen_t m_len; socklen_t m_len;
}; };
//! Berkeley (BSD) sockets implementation of IArchNetwork //! Berkeley (BSD) sockets implementation of IArchNetwork

View File

@ -26,7 +26,8 @@
static const int s_family[] = { static const int s_family[] = {
PF_UNSPEC, PF_UNSPEC,
PF_INET PF_INET,
PF_INET6,
}; };
static const int s_type[] = { static const int s_type[] = {
SOCK_DGRAM, SOCK_DGRAM,
@ -156,7 +157,7 @@ ArchNetworkWinsock::initModule(HMODULE module)
setfunc(startup, WSAStartup, int(PASCAL FAR*)(WORD, LPWSADATA)); setfunc(startup, WSAStartup, int(PASCAL FAR*)(WORD, LPWSADATA));
// startup network library // startup network library
WORD version = MAKEWORD(2 /*major*/, 0 /*minor*/); WORD version = MAKEWORD(2 /*major*/, 2 /*minor*/);
WSADATA data; WSADATA data;
int err = startup(version, &data); int err = startup(version, &data);
if (data.wVersion != version) { if (data.wVersion != version) {
@ -212,6 +213,11 @@ ArchNetworkWinsock::newSocket(EAddressFamily family, ESocketType type)
} }
try { try {
setBlockingOnSocket(fd, false); 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 (...) { catch (...) {
close_winsock(fd); close_winsock(fd);
@ -294,7 +300,7 @@ ArchNetworkWinsock::bindSocket(ArchSocket s, ArchNetAddress addr)
assert(s != NULL); assert(s != NULL);
assert(addr != 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()); throwError(getsockerror_winsock());
} }
} }
@ -317,10 +323,10 @@ ArchNetworkWinsock::acceptSocket(ArchSocket s, ArchNetAddress* const addr)
// create new socket and temporary address // create new socket and temporary address
ArchSocketImpl* socket = new ArchSocketImpl; ArchSocketImpl* socket = new ArchSocketImpl;
ArchNetAddress tmp = ArchNetAddressImpl::alloc(sizeof(struct sockaddr)); ArchNetAddress tmp = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in6));
// accept on socket // 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) { if (fd == INVALID_SOCKET) {
int err = getsockerror_winsock(); int err = getsockerror_winsock();
delete socket; delete socket;
@ -368,7 +374,7 @@ ArchNetworkWinsock::connectSocket(ArchSocket s, ArchNetAddress addr)
assert(s != NULL); assert(s != NULL);
assert(addr != 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) { addr->m_len) == SOCKET_ERROR) {
if (getsockerror_winsock() == WSAEISCONN) { if (getsockerror_winsock() == WSAEISCONN) {
return true; return true;
@ -678,13 +684,22 @@ ArchNetworkWinsock::newAnyAddr(EAddressFamily family)
switch (family) { switch (family) {
case kINET: { case kINET: {
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in)); addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in));
struct sockaddr_in* ipAddr = TYPED_ADDR(struct sockaddr_in, addr); auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
ipAddr->sin_family = AF_INET; ipAddr->sin_family = AF_INET;
ipAddr->sin_port = 0; ipAddr->sin_port = 0;
ipAddr->sin_addr.s_addr = INADDR_ANY; ipAddr->sin_addr.s_addr = INADDR_ANY;
break; break;
} }
case kINET6: {
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in6));
auto* 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: default:
assert(0 && "invalid family"); assert(0 && "invalid family");
} }
@ -705,41 +720,31 @@ ArchNetAddress
ArchNetworkWinsock::nameToAddr(const std::string& name) ArchNetworkWinsock::nameToAddr(const std::string& name)
{ {
// allocate address // allocate address
ArchNetAddressImpl* addr = NULL;
// try to convert assuming an IPv4 dot notation address ArchNetAddressImpl* addr = new ArchNetAddressImpl;
struct sockaddr_in inaddr;
memset(&inaddr, 0, sizeof(inaddr)); struct addrinfo hints;
inaddr.sin_family = AF_INET; struct addrinfo *p;
inaddr.sin_port = 0; memset(&hints, 0, sizeof(hints));
inaddr.sin_addr.s_addr = inet_addr_winsock(name.c_str()); hints.ai_family = AF_UNSPEC;
if (inaddr.sin_addr.s_addr != INADDR_NONE) { int ret = -1;
// it's a dot notation address
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in)); ARCH->lockMutex(m_mutex);
memcpy(TYPED_ADDR(void, addr), &inaddr, addr->m_len); if ((ret = getaddrinfo(name.c_str(), NULL, &hints, &p)) != 0) {
ARCH->unlockMutex(m_mutex);
delete addr;
throwNameError(ret);
} }
else { if (p->ai_family == AF_INET) {
// address lookup addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
struct hostent* info = gethostbyname_winsock(name.c_str()); } else {
if (info == NULL) { addr->m_len = (socklen_t)sizeof(struct sockaddr_in6);
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");
}
} }
memcpy(&addr->m_addr, p->ai_addr, addr->m_len);
freeaddrinfo(p);
ARCH->unlockMutex(m_mutex);
return addr; return addr;
} }
@ -756,16 +761,17 @@ ArchNetworkWinsock::addrToName(ArchNetAddress addr)
{ {
assert(addr != NULL); assert(addr != NULL);
// name lookup char host[1024];
struct hostent* info = gethostbyaddr_winsock( char service[20];
reinterpret_cast<const char FAR*>(&addr->m_addr), int ret = getnameinfo(TYPED_ADDR(struct sockaddr, addr), addr->m_len, host, sizeof(host), service, sizeof(service), 0);
addr->m_len, addr->m_addr.sa_family);
if (info == NULL) { if (ret != NULL) {
throwNameError(getsockerror_winsock()); throwNameError(ret);
} }
// return (primary) name // return (primary) name
return info->h_name; std::string name = host;
return name;
} }
std::string std::string
@ -775,11 +781,17 @@ ArchNetworkWinsock::addrToString(ArchNetAddress addr)
switch (getAddrFamily(addr)) { switch (getAddrFamily(addr)) {
case kINET: { case kINET: {
struct sockaddr_in* ipAddr = auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
return inet_ntoa_winsock(ipAddr->sin_addr); return inet_ntoa_winsock(ipAddr->sin_addr);
} }
case kINET6: {
char strAddr[INET6_ADDRSTRLEN];
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
inet_ntop(AF_INET6, &ipAddr->sin6_addr, strAddr, INET6_ADDRSTRLEN);
return strAddr;
}
default: default:
assert(0 && "unknown address family"); assert(0 && "unknown address family");
return ""; return "";
@ -791,10 +803,13 @@ ArchNetworkWinsock::getAddrFamily(ArchNetAddress addr)
{ {
assert(addr != NULL); assert(addr != NULL);
switch (addr->m_addr.sa_family) { switch (addr->m_addr.ss_family) {
case AF_INET: case AF_INET:
return kINET; return kINET;
case AF_INET6:
return kINET6;
default: default:
return kUNKNOWN; return kUNKNOWN;
} }
@ -807,9 +822,14 @@ ArchNetworkWinsock::setAddrPort(ArchNetAddress addr, int port)
switch (getAddrFamily(addr)) { switch (getAddrFamily(addr)) {
case kINET: { case kINET: {
struct sockaddr_in* ipAddr = auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr); ipAddr->sin_port = htons_winsock(static_cast<u_short>(port));
ipAddr->sin_port = htons_winsock(port); break;
}
case kINET6: {
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
ipAddr->sin6_port = htons_winsock(static_cast<u_short>(port));
break; break;
} }
@ -826,11 +846,15 @@ ArchNetworkWinsock::getAddrPort(ArchNetAddress addr)
switch (getAddrFamily(addr)) { switch (getAddrFamily(addr)) {
case kINET: { case kINET: {
struct sockaddr_in* ipAddr = auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
return ntohs_winsock(ipAddr->sin_port); return ntohs_winsock(ipAddr->sin_port);
} }
case kINET6: {
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
return ntohs_winsock(ipAddr->sin6_port);
}
default: default:
assert(0 && "unknown address family"); assert(0 && "unknown address family");
return 0; return 0;
@ -844,12 +868,17 @@ ArchNetworkWinsock::isAnyAddr(ArchNetAddress addr)
switch (getAddrFamily(addr)) { switch (getAddrFamily(addr)) {
case kINET: { case kINET: {
struct sockaddr_in* ipAddr = auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
return (addr->m_len == sizeof(struct sockaddr_in) && return (addr->m_len == sizeof(struct sockaddr_in) &&
ipAddr->sin_addr.s_addr == INADDR_ANY); ipAddr->sin_addr.s_addr == INADDR_ANY);
} }
case kINET6: {
auto* 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: default:
assert(0 && "unknown address family"); assert(0 && "unknown address family");
return true; return true;

View File

@ -18,8 +18,11 @@
#pragma once #pragma once
#include <ws2tcpip.h>
// declare no functions in winsock2 // declare no functions in winsock2
#ifndef INCL_WINSOCK_API_PROTOTYPES
#define INCL_WINSOCK_API_PROTOTYPES 0 #define INCL_WINSOCK_API_PROTOTYPES 0
#endif
#define INCL_WINSOCK_API_TYPEDEFS 0 #define INCL_WINSOCK_API_TYPEDEFS 0
#include "arch/IArchNetwork.h" #include "arch/IArchNetwork.h"
@ -30,6 +33,8 @@
#include <Windows.h> #include <Windows.h>
#include <list> #include <list>
#pragma comment(lib, "ws2_32.lib")
#define ARCH_NETWORK ArchNetworkWinsock #define ARCH_NETWORK ArchNetworkWinsock
class ArchSocketImpl { class ArchSocketImpl {
@ -45,8 +50,8 @@ public:
static ArchNetAddressImpl* alloc(size_t); static ArchNetAddressImpl* alloc(size_t);
public: public:
int m_len; int m_len;
struct sockaddr m_addr; struct sockaddr_storage m_addr;
}; };
#define ADDR_HDR_SIZE offsetof(ArchNetAddressImpl, m_addr) #define ADDR_HDR_SIZE offsetof(ArchNetAddressImpl, m_addr)
#define TYPED_ADDR(type_, addr_) (reinterpret_cast<type_*>(&addr_->m_addr)) #define TYPED_ADDR(type_, addr_) (reinterpret_cast<type_*>(&addr_->m_addr))

View File

@ -147,7 +147,9 @@ Client::connect()
} }
// create the socket // create the socket
IDataSocket* socket = m_socketFactory->create(m_useSecureNetwork); IDataSocket* socket = m_socketFactory->create(
ARCH->getAddrFamily(m_serverAddress.getAddress()),
m_useSecureNetwork);
m_socket = dynamic_cast<TCPSocket*>(socket); m_socket = dynamic_cast<TCPSocket*>(socket);
// filter socket messages, including a packetizing filter // filter socket messages, including a packetizing filter

View File

@ -28,7 +28,7 @@
IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer) : IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer) :
m_serverAddress(NetworkAddress(IPC_HOST, IPC_PORT)), m_serverAddress(NetworkAddress(IPC_HOST, IPC_PORT)),
m_socket(events, socketMultiplexer), m_socket(events, socketMultiplexer, IArchNetwork::kINET),
m_server(nullptr), m_server(nullptr),
m_events(events) m_events(events)
{ {
@ -37,7 +37,7 @@ IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer)
IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer, int port) : IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer, int port) :
m_serverAddress(NetworkAddress(IPC_HOST, port)), m_serverAddress(NetworkAddress(IPC_HOST, port)),
m_socket(events, socketMultiplexer), m_socket(events, socketMultiplexer, IArchNetwork::kINET),
m_server(nullptr), m_server(nullptr),
m_events(events) m_events(events)
{ {

View File

@ -54,7 +54,7 @@ IpcServer::IpcServer(IEventQueue* events, SocketMultiplexer* socketMultiplexer,
void void
IpcServer::init() IpcServer::init()
{ {
m_socket = new TCPListenSocket(m_events, m_socketMultiplexer); m_socket = new TCPListenSocket(m_events, m_socketMultiplexer, IArchNetwork::kINET);
m_clientsMutex = ARCH->newMutex(); m_clientsMutex = ARCH->newMutex();
m_address.resolve(); m_address.resolve();

View File

@ -19,6 +19,7 @@
#pragma once #pragma once
#include "common/IInterface.h" #include "common/IInterface.h"
#include "arch/IArchNetwork.h"
class IDataSocket; class IDataSocket;
class IListenSocket; class IListenSocket;
@ -34,10 +35,14 @@ public:
//@{ //@{
//! Create data socket //! Create data socket
virtual IDataSocket* create(bool secure) const = 0; virtual IDataSocket* create(
IArchNetwork::EAddressFamily family,
bool secure) const = 0;
//! Create listen socket //! Create listen socket
virtual IListenSocket* createListen(bool secure) const = 0; virtual IListenSocket* createListen(
IArchNetwork::EAddressFamily family,
bool secure) const = 0;
//@} //@}
}; };

View File

@ -87,7 +87,7 @@ NetworkAddress::NetworkAddress(const String& hostname, int port) :
// notation. in that case we assume it's not a port suffix. // notation. in that case we assume it's not a port suffix.
// the user can replace the double colon with zeros to // the user can replace the double colon with zeros to
// disambiguate. // disambiguate.
if ((!doubleColon || dotNotation) || !colonNotation) { if ((!doubleColon || dotNotation) && !colonNotation) {
// parse port from hostname // parse port from hostname
char* end; char* end;
const char* chostname = m_hostname.c_str(); const char* chostname = m_hostname.c_str();

View File

@ -32,8 +32,9 @@ static const char s_certificateFilename[] = { "Barrier.pem" };
SecureListenSocket::SecureListenSocket( SecureListenSocket::SecureListenSocket(
IEventQueue* events, IEventQueue* events,
SocketMultiplexer* socketMultiplexer) : SocketMultiplexer* socketMultiplexer,
TCPListenSocket(events, socketMultiplexer) IArchNetwork::EAddressFamily family) :
TCPListenSocket(events, socketMultiplexer, family)
{ {
} }

View File

@ -27,7 +27,8 @@ class IDataSocket;
class SecureListenSocket : public TCPListenSocket{ class SecureListenSocket : public TCPListenSocket{
public: public:
SecureListenSocket(IEventQueue* events, SecureListenSocket(IEventQueue* events,
SocketMultiplexer* socketMultiplexer); SocketMultiplexer* socketMultiplexer,
IArchNetwork::EAddressFamily family);
// IListenSocket overrides // IListenSocket overrides
virtual IDataSocket* virtual IDataSocket*

View File

@ -56,8 +56,9 @@ struct Ssl {
SecureSocket::SecureSocket( SecureSocket::SecureSocket(
IEventQueue* events, IEventQueue* events,
SocketMultiplexer* socketMultiplexer) : SocketMultiplexer* socketMultiplexer,
TCPSocket(events, socketMultiplexer), IArchNetwork::EAddressFamily family) :
TCPSocket(events, socketMultiplexer, family),
m_ssl(nullptr), m_ssl(nullptr),
m_secureReady(false), m_secureReady(false),
m_fatal(false) m_fatal(false)

View File

@ -32,7 +32,7 @@ A secure socket using SSL.
*/ */
class SecureSocket : public TCPSocket { class SecureSocket : public TCPSocket {
public: public:
SecureSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer); SecureSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family);
SecureSocket(IEventQueue* events, SecureSocket(IEventQueue* events,
SocketMultiplexer* socketMultiplexer, SocketMultiplexer* socketMultiplexer,
ArchSocket socket); ArchSocket socket);

View File

@ -34,13 +34,13 @@
// TCPListenSocket // TCPListenSocket
// //
TCPListenSocket::TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer) : TCPListenSocket::TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family) :
m_events(events), m_events(events),
m_socketMultiplexer(socketMultiplexer) m_socketMultiplexer(socketMultiplexer)
{ {
m_mutex = new Mutex; m_mutex = new Mutex;
try { try {
m_socket = ARCH->newSocket(IArchNetwork::kINET, IArchNetwork::kSTREAM); m_socket = ARCH->newSocket(family, IArchNetwork::kSTREAM);
} }
catch (XArchNetwork& e) { catch (XArchNetwork& e) {
throw XSocketCreate(e.what()); throw XSocketCreate(e.what());

View File

@ -32,7 +32,7 @@ A listen socket using TCP.
*/ */
class TCPListenSocket : public IListenSocket { class TCPListenSocket : public IListenSocket {
public: public:
TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer); TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family);
virtual ~TCPListenSocket(); virtual ~TCPListenSocket();
// ISocket overrides // ISocket overrides

View File

@ -37,7 +37,7 @@
// TCPSocket // TCPSocket
// //
TCPSocket::TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer) : TCPSocket::TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family) :
IDataSocket(events), IDataSocket(events),
m_events(events), m_events(events),
m_mutex(), m_mutex(),
@ -45,7 +45,7 @@ TCPSocket::TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer)
m_socketMultiplexer(socketMultiplexer) m_socketMultiplexer(socketMultiplexer)
{ {
try { try {
m_socket = ARCH->newSocket(IArchNetwork::kINET, IArchNetwork::kSTREAM); m_socket = ARCH->newSocket(family, IArchNetwork::kSTREAM);
} }
catch (XArchNetwork& e) { catch (XArchNetwork& e) {
throw XSocketCreate(e.what()); throw XSocketCreate(e.what());

View File

@ -36,7 +36,7 @@ A data socket using TCP.
*/ */
class TCPSocket : public IDataSocket { class TCPSocket : public IDataSocket {
public: public:
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer); TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family);
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, ArchSocket socket); TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, ArchSocket socket);
virtual ~TCPSocket(); virtual ~TCPSocket();

View File

@ -41,27 +41,27 @@ TCPSocketFactory::~TCPSocketFactory()
} }
IDataSocket* IDataSocket*
TCPSocketFactory::create(bool secure) const TCPSocketFactory::create(IArchNetwork::EAddressFamily family, bool secure) const
{ {
if (secure) { if (secure) {
SecureSocket* secureSocket = new SecureSocket(m_events, m_socketMultiplexer); SecureSocket* secureSocket = new SecureSocket(m_events, m_socketMultiplexer, family);
secureSocket->initSsl (false); secureSocket->initSsl (false);
return secureSocket; return secureSocket;
} }
else { else {
return new TCPSocket(m_events, m_socketMultiplexer); return new TCPSocket(m_events, m_socketMultiplexer, family);
} }
} }
IListenSocket* IListenSocket*
TCPSocketFactory::createListen(bool secure) const TCPSocketFactory::createListen(IArchNetwork::EAddressFamily family, bool secure) const
{ {
IListenSocket* socket = NULL; IListenSocket* socket = NULL;
if (secure) { if (secure) {
socket = new SecureListenSocket(m_events, m_socketMultiplexer); socket = new SecureListenSocket(m_events, m_socketMultiplexer, family);
} }
else { else {
socket = new TCPListenSocket(m_events, m_socketMultiplexer); socket = new TCPListenSocket(m_events, m_socketMultiplexer, family);
} }
return socket; return socket;

View File

@ -19,6 +19,7 @@
#pragma once #pragma once
#include "net/ISocketFactory.h" #include "net/ISocketFactory.h"
#include "arch/IArchNetwork.h"
class IEventQueue; class IEventQueue;
class SocketMultiplexer; class SocketMultiplexer;
@ -30,10 +31,12 @@ public:
virtual ~TCPSocketFactory(); virtual ~TCPSocketFactory();
// ISocketFactory overrides // ISocketFactory overrides
virtual IDataSocket* virtual IDataSocket* create(
create(bool secure) const; IArchNetwork::EAddressFamily family,
virtual IListenSocket* bool secure) const;
createListen(bool secure) const; virtual IListenSocket* createListen(
IArchNetwork::EAddressFamily family,
bool secure) const;
private: private:
IEventQueue* m_events; IEventQueue* m_events;

View File

@ -45,7 +45,9 @@ ClientListener::ClientListener(const NetworkAddress& address,
assert(m_socketFactory != NULL); assert(m_socketFactory != NULL);
try { try {
m_listen = m_socketFactory->createListen(m_useSecureNetwork); m_listen = m_socketFactory->createListen(
ARCH->getAddrFamily(address.getAddress()),
m_useSecureNetwork);
// setup event handler // setup event handler
m_events->adoptHandler(m_events->forIListenSocket().connecting(), m_events->adoptHandler(m_events->forIListenSocket().connecting(),