#6178 Merge IPv6 PR
This commit is contained in:
parent
1e8e48d65b
commit
8446fe5395
|
@ -64,6 +64,7 @@ public:
|
||||||
enum EAddressFamily {
|
enum EAddressFamily {
|
||||||
kUNKNOWN,
|
kUNKNOWN,
|
||||||
kINET,
|
kINET,
|
||||||
|
kINET6,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Supported socket types
|
//! Supported socket types
|
||||||
|
|
|
@ -18,22 +18,22 @@
|
||||||
|
|
||||||
#include "arch/unix/ArchNetworkBSD.h"
|
#include "arch/unix/ArchNetworkBSD.h"
|
||||||
|
|
||||||
|
#include "arch/Arch.h"
|
||||||
#include "arch/unix/ArchMultithreadPosix.h"
|
#include "arch/unix/ArchMultithreadPosix.h"
|
||||||
#include "arch/unix/XArchUnix.h"
|
#include "arch/unix/XArchUnix.h"
|
||||||
#include "arch/Arch.h"
|
|
||||||
|
|
||||||
#if HAVE_UNISTD_H
|
#if HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
#if !defined(TCP_NODELAY)
|
#if !defined(TCP_NODELAY)
|
||||||
# include <netinet/tcp.h>
|
# include <netinet/tcp.h>
|
||||||
#endif
|
#endif
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <fcntl.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#if HAVE_POLL
|
#if HAVE_POLL
|
||||||
# include <poll.h>
|
# include <poll.h>
|
||||||
|
@ -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,
|
||||||
|
@ -87,8 +88,7 @@ inet_aton(const char* cp, struct in_addr* inp)
|
||||||
//
|
//
|
||||||
|
|
||||||
ArchNetworkBSD::ArchNetworkBSD()
|
ArchNetworkBSD::ArchNetworkBSD()
|
||||||
{
|
= default;
|
||||||
}
|
|
||||||
|
|
||||||
ArchNetworkBSD::~ArchNetworkBSD()
|
ArchNetworkBSD::~ArchNetworkBSD()
|
||||||
{
|
{
|
||||||
|
@ -119,7 +119,7 @@ ArchNetworkBSD::newSocket(EAddressFamily family, ESocketType type)
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate socket object
|
// allocate socket object
|
||||||
ArchSocketImpl* newSocket = new ArchSocketImpl;
|
auto* newSocket = new ArchSocketImpl;
|
||||||
newSocket->m_fd = fd;
|
newSocket->m_fd = fd;
|
||||||
newSocket->m_refCount = 1;
|
newSocket->m_refCount = 1;
|
||||||
return newSocket;
|
return newSocket;
|
||||||
|
@ -191,7 +191,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,25 +214,25 @@ ArchNetworkBSD::acceptSocket(ArchSocket s, ArchNetAddress* addr)
|
||||||
|
|
||||||
// if user passed NULL in addr then use scratch space
|
// if user passed NULL in addr then use scratch space
|
||||||
ArchNetAddress dummy;
|
ArchNetAddress dummy;
|
||||||
if (addr == NULL) {
|
if (addr == nullptr) {
|
||||||
addr = &dummy;
|
addr = &dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create new socket and address
|
// create new socket and address
|
||||||
ArchSocketImpl* newSocket = new ArchSocketImpl;
|
auto* newSocket = new ArchSocketImpl;
|
||||||
*addr = new ArchNetAddressImpl;
|
*addr = new ArchNetAddressImpl;
|
||||||
|
|
||||||
// accept on socket
|
// accept on socket
|
||||||
ACCEPT_TYPE_ARG3 len = (ACCEPT_TYPE_ARG3)((*addr)->m_len);
|
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 = (socklen_t)len;
|
(*addr)->m_len = len;
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
int err = errno;
|
int err = errno;
|
||||||
delete newSocket;
|
delete newSocket;
|
||||||
delete *addr;
|
delete *addr;
|
||||||
*addr = NULL;
|
*addr = nullptr;
|
||||||
if (err == EAGAIN) {
|
if (err == EAGAIN) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
throwError(err);
|
throwError(err);
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ ArchNetworkBSD::acceptSocket(ArchSocket s, ArchNetAddress* addr)
|
||||||
close(fd);
|
close(fd);
|
||||||
delete newSocket;
|
delete newSocket;
|
||||||
delete *addr;
|
delete *addr;
|
||||||
*addr = NULL;
|
*addr = nullptr;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +266,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;
|
||||||
}
|
}
|
||||||
|
@ -294,11 +294,11 @@ ArchNetworkBSD::pollSocket(PollEntry pe[], int num, double timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate space for translated query
|
// allocate space for translated query
|
||||||
struct pollfd* pfd = new struct pollfd[1 + num];
|
auto* pfd = new struct pollfd[1 + num];
|
||||||
|
|
||||||
// translate query
|
// translate query
|
||||||
for (int i = 0; i < num; ++i) {
|
for (int i = 0; i < num; ++i) {
|
||||||
pfd[i].fd = (pe[i].m_socket == NULL) ? -1 : pe[i].m_socket->m_fd;
|
pfd[i].fd = (pe[i].m_socket == nullptr) ? -1 : pe[i].m_socket->m_fd;
|
||||||
pfd[i].events = 0;
|
pfd[i].events = 0;
|
||||||
if ((pe[i].m_events & kPOLLIN) != 0) {
|
if ((pe[i].m_events & kPOLLIN) != 0) {
|
||||||
pfd[i].events |= POLLIN;
|
pfd[i].events |= POLLIN;
|
||||||
|
@ -311,7 +311,7 @@ ArchNetworkBSD::pollSocket(PollEntry pe[], int num, double timeout)
|
||||||
|
|
||||||
// add the unblock pipe
|
// add the unblock pipe
|
||||||
const int* unblockPipe = getUnblockPipe();
|
const int* unblockPipe = getUnblockPipe();
|
||||||
if (unblockPipe != NULL) {
|
if (unblockPipe != nullptr) {
|
||||||
pfd[n].fd = unblockPipe[0];
|
pfd[n].fd = unblockPipe[0];
|
||||||
pfd[n].events = POLLIN;
|
pfd[n].events = POLLIN;
|
||||||
++n;
|
++n;
|
||||||
|
@ -324,7 +324,7 @@ ArchNetworkBSD::pollSocket(PollEntry pe[], int num, double timeout)
|
||||||
n = poll(pfd, n, t);
|
n = poll(pfd, n, t);
|
||||||
|
|
||||||
// reset the unblock pipe
|
// reset the unblock pipe
|
||||||
if (n > 0 && unblockPipe != NULL && (pfd[num].revents & POLLIN) != 0) {
|
if (n > 0 && unblockPipe != nullptr && (pfd[num].revents & POLLIN) != 0) {
|
||||||
// the unblock event was signalled. flush the pipe.
|
// the unblock event was signalled. flush the pipe.
|
||||||
char dummy[100];
|
char dummy[100];
|
||||||
int ignore;
|
int ignore;
|
||||||
|
@ -500,7 +500,7 @@ void
|
||||||
ArchNetworkBSD::unblockPollSocket(ArchThread thread)
|
ArchNetworkBSD::unblockPollSocket(ArchThread thread)
|
||||||
{
|
{
|
||||||
const int* unblockPipe = getUnblockPipeForThread(thread);
|
const int* unblockPipe = getUnblockPipeForThread(thread);
|
||||||
if (unblockPipe != NULL) {
|
if (unblockPipe != nullptr) {
|
||||||
char dummy = 0;
|
char dummy = 0;
|
||||||
int ignore;
|
int ignore;
|
||||||
|
|
||||||
|
@ -545,9 +545,9 @@ ArchNetworkBSD::throwErrorOnSocket(ArchSocket s)
|
||||||
|
|
||||||
// get the error from the socket layer
|
// get the error from the socket layer
|
||||||
int err = 0;
|
int err = 0;
|
||||||
socklen_t size = (socklen_t)sizeof(err);
|
auto size = static_cast<socklen_t>(sizeof(err));
|
||||||
if (getsockopt(s->m_fd, SOL_SOCKET, SO_ERROR,
|
if (getsockopt(s->m_fd, SOL_SOCKET, SO_ERROR,
|
||||||
(optval_t*)&err, &size) == -1) {
|
reinterpret_cast<optval_t*>(&err), &size) == -1) {
|
||||||
err = errno;
|
err = errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,16 +584,16 @@ ArchNetworkBSD::setNoDelayOnSocket(ArchSocket s, bool noDelay)
|
||||||
|
|
||||||
// get old state
|
// get old state
|
||||||
int oflag;
|
int oflag;
|
||||||
socklen_t size = (socklen_t)sizeof(oflag);
|
auto size = static_cast<socklen_t>(sizeof(oflag));
|
||||||
if (getsockopt(s->m_fd, IPPROTO_TCP, TCP_NODELAY,
|
if (getsockopt(s->m_fd, IPPROTO_TCP, TCP_NODELAY,
|
||||||
(optval_t*)&oflag, &size) == -1) {
|
reinterpret_cast<optval_t*>(&oflag), &size) == -1) {
|
||||||
throwError(errno);
|
throwError(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
int flag = noDelay ? 1 : 0;
|
int flag = noDelay ? 1 : 0;
|
||||||
size = (socklen_t)sizeof(flag);
|
size = static_cast<socklen_t>(sizeof(flag));
|
||||||
if (setsockopt(s->m_fd, IPPROTO_TCP, TCP_NODELAY,
|
if (setsockopt(s->m_fd, IPPROTO_TCP, TCP_NODELAY,
|
||||||
(optval_t*)&flag, size) == -1) {
|
reinterpret_cast<optval_t*>(&flag), size) == -1) {
|
||||||
throwError(errno);
|
throwError(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,16 +607,16 @@ ArchNetworkBSD::setReuseAddrOnSocket(ArchSocket s, bool reuse)
|
||||||
|
|
||||||
// get old state
|
// get old state
|
||||||
int oflag;
|
int oflag;
|
||||||
socklen_t size = (socklen_t)sizeof(oflag);
|
auto size = static_cast<socklen_t>(sizeof(oflag));
|
||||||
if (getsockopt(s->m_fd, SOL_SOCKET, SO_REUSEADDR,
|
if (getsockopt(s->m_fd, SOL_SOCKET, SO_REUSEADDR,
|
||||||
(optval_t*)&oflag, &size) == -1) {
|
reinterpret_cast<optval_t*>(&oflag), &size) == -1) {
|
||||||
throwError(errno);
|
throwError(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
int flag = reuse ? 1 : 0;
|
int flag = reuse ? 1 : 0;
|
||||||
size = (socklen_t)sizeof(flag);
|
size = static_cast<socklen_t>(sizeof(flag));
|
||||||
if (setsockopt(s->m_fd, SOL_SOCKET, SO_REUSEADDR,
|
if (setsockopt(s->m_fd, SOL_SOCKET, SO_REUSEADDR,
|
||||||
(optval_t*)&flag, size) == -1) {
|
reinterpret_cast<optval_t*>(&flag), size) == -1) {
|
||||||
throwError(errno);
|
throwError(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,20 +640,27 @@ ArchNetAddress
|
||||||
ArchNetworkBSD::newAnyAddr(EAddressFamily family)
|
ArchNetworkBSD::newAnyAddr(EAddressFamily family)
|
||||||
{
|
{
|
||||||
// allocate address
|
// allocate address
|
||||||
ArchNetAddressImpl* addr = new ArchNetAddressImpl;
|
auto* addr = new ArchNetAddressImpl;
|
||||||
|
|
||||||
// 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;
|
||||||
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
|
addr->m_len = static_cast<socklen_t>(sizeof(struct sockaddr_in));
|
||||||
break;
|
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:
|
default:
|
||||||
delete addr;
|
delete addr;
|
||||||
assert(0 && "invalid family");
|
assert(0 && "invalid family");
|
||||||
|
@ -675,50 +682,33 @@ ArchNetAddress
|
||||||
ArchNetworkBSD::nameToAddr(const std::string& name)
|
ArchNetworkBSD::nameToAddr(const std::string& name)
|
||||||
{
|
{
|
||||||
// allocate address
|
// allocate address
|
||||||
ArchNetAddressImpl* addr = new ArchNetAddressImpl;
|
auto* 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)
|
// done with static buffer
|
||||||
if (info->h_addrtype == AF_INET) {
|
ARCH->lockMutex(m_mutex);
|
||||||
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
|
if ((ret = getaddrinfo(name.c_str(), NULL, &hints, &p)) != 0) {
|
||||||
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 +727,16 @@ 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);
|
||||||
ARCH->unlockMutex(m_mutex);
|
if (ret != 0) {
|
||||||
throwNameError(h_errno);
|
ARCH->unlockMutex(m_mutex);
|
||||||
|
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 +751,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];
|
||||||
|
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:
|
default:
|
||||||
assert(0 && "unknown address family");
|
assert(0 && "unknown address family");
|
||||||
return "";
|
return "";
|
||||||
|
@ -779,9 +778,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 +796,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: {
|
||||||
|
struct sockaddr_in6* 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 +820,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: {
|
||||||
|
struct sockaddr_in6* 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,10 +842,15 @@ 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 == 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:
|
default:
|
||||||
|
@ -865,8 +880,8 @@ const int*
|
||||||
ArchNetworkBSD::getUnblockPipeForThread(ArchThread thread)
|
ArchNetworkBSD::getUnblockPipeForThread(ArchThread thread)
|
||||||
{
|
{
|
||||||
ArchMultithreadPosix* mt = ArchMultithreadPosix::getInstance();
|
ArchMultithreadPosix* mt = ArchMultithreadPosix::getInstance();
|
||||||
int* unblockPipe = (int*)mt->getNetworkDataForThread(thread);
|
auto* unblockPipe = static_cast<int*>(mt->getNetworkDataForThread(thread));
|
||||||
if (unblockPipe == NULL) {
|
if (unblockPipe == nullptr) {
|
||||||
unblockPipe = new int[2];
|
unblockPipe = new int[2];
|
||||||
if (pipe(unblockPipe) != -1) {
|
if (pipe(unblockPipe) != -1) {
|
||||||
try {
|
try {
|
||||||
|
@ -875,12 +890,12 @@ ArchNetworkBSD::getUnblockPipeForThread(ArchThread thread)
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
delete[] unblockPipe;
|
delete[] unblockPipe;
|
||||||
unblockPipe = NULL;
|
unblockPipe = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
delete[] unblockPipe;
|
delete[] unblockPipe;
|
||||||
unblockPipe = NULL;
|
unblockPipe = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return unblockPipe;
|
return unblockPipe;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -685,6 +691,15 @@ ArchNetworkWinsock::newAnyAddr(EAddressFamily family)
|
||||||
break;
|
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:
|
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 =
|
struct sockaddr_in* 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];
|
||||||
|
struct sockaddr_in6* 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 =
|
struct sockaddr_in* 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: {
|
||||||
|
struct sockaddr_in6* 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 =
|
struct sockaddr_in* 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: {
|
||||||
|
struct sockaddr_in6* 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 =
|
struct sockaddr_in* 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: {
|
||||||
|
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:
|
default:
|
||||||
assert(0 && "unknown address family");
|
assert(0 && "unknown address family");
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -147,7 +147,7 @@ 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_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
|
||||||
|
|
|
@ -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,10 @@ public:
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
//! Create data socket
|
//! Create data socket
|
||||||
virtual IDataSocket* create(bool secure) const = 0;
|
virtual IDataSocket* create(IArchNetwork::EAddressFamily family = IArchNetwork::kINET) const = 0;
|
||||||
|
|
||||||
//! Create listen socket
|
//! Create listen socket
|
||||||
virtual IListenSocket* createListen(bool secure) const = 0;
|
virtual IListenSocket* createListen(IArchNetwork::EAddressFamily family = IArchNetwork::kINET) const = 0;
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -32,8 +32,9 @@ static const char s_certificateFilename[] = { "Synergy.pem" };
|
||||||
|
|
||||||
SecureListenSocket::SecureListenSocket(
|
SecureListenSocket::SecureListenSocket(
|
||||||
IEventQueue* events,
|
IEventQueue* events,
|
||||||
SocketMultiplexer* socketMultiplexer) :
|
SocketMultiplexer* socketMultiplexer,
|
||||||
TCPListenSocket(events, socketMultiplexer)
|
IArchNetwork::EAddressFamily family) :
|
||||||
|
TCPListenSocket(events, socketMultiplexer, family)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ 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);
|
||||||
~SecureListenSocket();
|
~SecureListenSocket();
|
||||||
|
|
||||||
// IListenSocket overrides
|
// IListenSocket overrides
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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 = IArchNetwork::kINET);
|
||||||
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, ArchSocket socket);
|
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, ArchSocket socket);
|
||||||
virtual ~TCPSocket();
|
virtual ~TCPSocket();
|
||||||
|
|
||||||
|
|
|
@ -41,27 +41,27 @@ TCPSocketFactory::~TCPSocketFactory()
|
||||||
}
|
}
|
||||||
|
|
||||||
IDataSocket*
|
IDataSocket*
|
||||||
TCPSocketFactory::create(bool secure) const
|
TCPSocketFactory::create(IArchNetwork::EAddressFamily family) 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) 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;
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -31,9 +32,9 @@ public:
|
||||||
|
|
||||||
// ISocketFactory overrides
|
// ISocketFactory overrides
|
||||||
virtual IDataSocket*
|
virtual IDataSocket*
|
||||||
create(bool secure) const;
|
create(IArchNetwork::EAddressFamily family = IArchNetwork::kINET) const;
|
||||||
virtual IListenSocket*
|
virtual IListenSocket*
|
||||||
createListen(bool secure) const;
|
createListen(IArchNetwork::EAddressFamily family = IArchNetwork::kINET) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IEventQueue* m_events;
|
IEventQueue* m_events;
|
||||||
|
|
|
@ -45,7 +45,7 @@ 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()));
|
||||||
|
|
||||||
// setup event handler
|
// setup event handler
|
||||||
m_events->adoptHandler(m_events->forIListenSocket().connecting(),
|
m_events->adoptHandler(m_events->forIListenSocket().connecting(),
|
||||||
|
|
|
@ -22,19 +22,6 @@
|
||||||
|
|
||||||
TEST(ClipboardChunkTests, start_formatStartChunk)
|
TEST(ClipboardChunkTests, start_formatStartChunk)
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
ClipboardID id = 0;
|
|
||||||
UInt32 sequence = 0;
|
|
||||||
String mockDataSize("10");
|
|
||||||
ClipboardChunk* chunk = ClipboardChunk::start(id, sequence, mockDataSize);
|
|
||||||
|
|
||||||
EXPECT_EQ(id, chunk->m_chunk[0]);
|
|
||||||
EXPECT_EQ(sequence, (UInt32)chunk->m_chunk[1]);
|
|
||||||
EXPECT_EQ(kDataStart, chunk->m_chunk[5]);
|
|
||||||
EXPECT_EQ('1', chunk->m_chunk[6]);
|
|
||||||
EXPECT_EQ('0', chunk->m_chunk[7]);
|
|
||||||
EXPECT_EQ('\0', chunk->m_chunk[8]);
|
|
||||||
=======
|
|
||||||
ClipboardID id = 0;
|
ClipboardID id = 0;
|
||||||
UInt32 sequence = 0;
|
UInt32 sequence = 0;
|
||||||
String mockDataSize("10");
|
String mockDataSize("10");
|
||||||
|
@ -48,14 +35,12 @@ TEST(ClipboardChunkTests, start_formatStartChunk)
|
||||||
EXPECT_EQ('1', chunk->m_chunk[6]);
|
EXPECT_EQ('1', chunk->m_chunk[6]);
|
||||||
EXPECT_EQ('0', chunk->m_chunk[7]);
|
EXPECT_EQ('0', chunk->m_chunk[7]);
|
||||||
EXPECT_EQ('\0', chunk->m_chunk[8]);
|
EXPECT_EQ('\0', chunk->m_chunk[8]);
|
||||||
>>>>>>> master
|
|
||||||
|
|
||||||
delete chunk;
|
delete chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ClipboardChunkTests, data_formatDataChunk)
|
TEST(ClipboardChunkTests, data_formatDataChunk)
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
ClipboardID id = 0;
|
ClipboardID id = 0;
|
||||||
UInt32 sequence = 1;
|
UInt32 sequence = 1;
|
||||||
String mockData("mock data");
|
String mockData("mock data");
|
||||||
|
@ -74,35 +59,12 @@ TEST(ClipboardChunkTests, data_formatDataChunk)
|
||||||
EXPECT_EQ('t', chunk->m_chunk[13]);
|
EXPECT_EQ('t', chunk->m_chunk[13]);
|
||||||
EXPECT_EQ('a', chunk->m_chunk[14]);
|
EXPECT_EQ('a', chunk->m_chunk[14]);
|
||||||
EXPECT_EQ('\0', chunk->m_chunk[15]);
|
EXPECT_EQ('\0', chunk->m_chunk[15]);
|
||||||
=======
|
|
||||||
ClipboardID id = 0;
|
|
||||||
UInt32 sequence = 1;
|
|
||||||
String mockData("mock data");
|
|
||||||
ClipboardChunk* chunk = ClipboardChunk::data(id, sequence, mockData);
|
|
||||||
UInt32 temp_m_chunk;
|
|
||||||
memcpy(&temp_m_chunk, &(chunk->m_chunk[1]), 4);
|
|
||||||
|
|
||||||
EXPECT_EQ(id, chunk->m_chunk[0]);
|
|
||||||
EXPECT_EQ(sequence, temp_m_chunk);
|
|
||||||
EXPECT_EQ(kDataChunk, chunk->m_chunk[5]);
|
|
||||||
EXPECT_EQ('m', chunk->m_chunk[6]);
|
|
||||||
EXPECT_EQ('o', chunk->m_chunk[7]);
|
|
||||||
EXPECT_EQ('c', chunk->m_chunk[8]);
|
|
||||||
EXPECT_EQ('k', chunk->m_chunk[9]);
|
|
||||||
EXPECT_EQ(' ', chunk->m_chunk[10]);
|
|
||||||
EXPECT_EQ('d', chunk->m_chunk[11]);
|
|
||||||
EXPECT_EQ('a', chunk->m_chunk[12]);
|
|
||||||
EXPECT_EQ('t', chunk->m_chunk[13]);
|
|
||||||
EXPECT_EQ('a', chunk->m_chunk[14]);
|
|
||||||
EXPECT_EQ('\0', chunk->m_chunk[15]);
|
|
||||||
>>>>>>> master
|
|
||||||
|
|
||||||
delete chunk;
|
delete chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ClipboardChunkTests, end_formatDataChunk)
|
TEST(ClipboardChunkTests, end_formatDataChunk)
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
ClipboardID id = 1;
|
ClipboardID id = 1;
|
||||||
UInt32 sequence = 1;
|
UInt32 sequence = 1;
|
||||||
ClipboardChunk* chunk = ClipboardChunk::end(id, sequence);
|
ClipboardChunk* chunk = ClipboardChunk::end(id, sequence);
|
||||||
|
@ -111,18 +73,6 @@ TEST(ClipboardChunkTests, end_formatDataChunk)
|
||||||
EXPECT_EQ(sequence, (UInt32)chunk->m_chunk[1]);
|
EXPECT_EQ(sequence, (UInt32)chunk->m_chunk[1]);
|
||||||
EXPECT_EQ(kDataEnd, chunk->m_chunk[5]);
|
EXPECT_EQ(kDataEnd, chunk->m_chunk[5]);
|
||||||
EXPECT_EQ('\0', chunk->m_chunk[6]);
|
EXPECT_EQ('\0', chunk->m_chunk[6]);
|
||||||
=======
|
|
||||||
ClipboardID id = 1;
|
|
||||||
UInt32 sequence = 1;
|
|
||||||
ClipboardChunk* chunk = ClipboardChunk::end(id, sequence);
|
|
||||||
UInt32 temp_m_chunk;
|
|
||||||
memcpy(&temp_m_chunk, &(chunk->m_chunk[1]), 4);
|
|
||||||
|
|
||||||
EXPECT_EQ(id, chunk->m_chunk[0]);
|
|
||||||
EXPECT_EQ(sequence, temp_m_chunk);
|
|
||||||
EXPECT_EQ(kDataEnd, chunk->m_chunk[5]);
|
|
||||||
EXPECT_EQ('\0', chunk->m_chunk[6]);
|
|
||||||
>>>>>>> master
|
|
||||||
|
|
||||||
delete chunk;
|
delete chunk;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue