From a93338e90fc7f815351f19e55c5eac25ee7fb0da Mon Sep 17 00:00:00 2001 From: "William L. Thomson Jr" Date: Fri, 20 Oct 2017 18:04:52 -0400 Subject: [PATCH] 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 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 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 --- src/lib/arch/IArchNetwork.h | 1 + src/lib/arch/unix/ArchNetworkBSD.cpp | 132 +++++++++++---------- src/lib/arch/unix/ArchNetworkBSD.h | 5 +- src/lib/arch/win32/ArchNetworkWinsock.cpp | 135 +++++++++++++--------- src/lib/arch/win32/ArchNetworkWinsock.h | 9 +- src/lib/client/Client.cpp | 2 +- src/lib/net/ISocketFactory.h | 5 +- src/lib/net/NetworkAddress.cpp | 2 +- src/lib/net/TCPListenSocket.cpp | 4 +- src/lib/net/TCPListenSocket.h | 2 +- src/lib/net/TCPSocket.cpp | 4 +- src/lib/net/TCPSocket.h | 2 +- src/lib/net/TCPSocketFactory.cpp | 8 +- src/lib/net/TCPSocketFactory.h | 5 +- src/lib/server/ClientListener.cpp | 2 +- 15 files changed, 186 insertions(+), 132 deletions(-) diff --git a/src/lib/arch/IArchNetwork.h b/src/lib/arch/IArchNetwork.h index d71f8d88..0d58dc85 100644 --- a/src/lib/arch/IArchNetwork.h +++ b/src/lib/arch/IArchNetwork.h @@ -64,6 +64,7 @@ public: enum EAddressFamily { kUNKNOWN, kINET, + kINET6, }; //! Supported socket types diff --git a/src/lib/arch/unix/ArchNetworkBSD.cpp b/src/lib/arch/unix/ArchNetworkBSD.cpp index a00df41f..7a8a7d5a 100644 --- a/src/lib/arch/unix/ArchNetworkBSD.cpp +++ b/src/lib/arch/unix/ArchNetworkBSD.cpp @@ -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(&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(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); - } + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; - // copy over address (only IPv4 currently supported) - if (info->h_addrtype == AF_INET) { - addr->m_len = static_cast(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 + // 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) { - ARCH->unlockMutex(m_mutex); - throwNameError(h_errno); + 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(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(&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(&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(&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(&addr->m_addr); + auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr); return (ipAddr->sin_addr.s_addr == INADDR_ANY && addr->m_len == static_cast(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; diff --git a/src/lib/arch/unix/ArchNetworkBSD.h b/src/lib/arch/unix/ArchNetworkBSD.h index 7426baf0..a2492b2d 100644 --- a/src/lib/arch/unix/ArchNetworkBSD.h +++ b/src/lib/arch/unix/ArchNetworkBSD.h @@ -38,6 +38,7 @@ typedef int socklen_t; typedef char optval_t; #define ARCH_NETWORK ArchNetworkBSD +#define TYPED_ADDR(type_, addr_) (reinterpret_cast(&addr_->m_addr)) class ArchSocketImpl { public: @@ -50,8 +51,8 @@ public: ArchNetAddressImpl() : m_len(sizeof(m_addr)) { } public: - struct sockaddr m_addr; - socklen_t m_len; + struct sockaddr_storage m_addr; + socklen_t m_len; }; //! Berkeley (BSD) sockets implementation of IArchNetwork diff --git a/src/lib/arch/win32/ArchNetworkWinsock.cpp b/src/lib/arch/win32/ArchNetworkWinsock.cpp index 65a5b320..64750acc 100644 --- a/src/lib/arch/win32/ArchNetworkWinsock.cpp +++ b/src/lib/arch/win32/ArchNetworkWinsock.cpp @@ -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(&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(&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(&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(port)); + break; + } + + case kINET6: { + struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr); + ipAddr->sin6_port = htons_winsock(static_cast(port)); break; } @@ -826,11 +846,15 @@ ArchNetworkWinsock::getAddrPort(ArchNetAddress addr) switch (getAddrFamily(addr)) { case kINET: { - struct sockaddr_in* ipAddr = - reinterpret_cast(&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(&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; diff --git a/src/lib/arch/win32/ArchNetworkWinsock.h b/src/lib/arch/win32/ArchNetworkWinsock.h index 4c2e8573..cb60d51f 100644 --- a/src/lib/arch/win32/ArchNetworkWinsock.h +++ b/src/lib/arch/win32/ArchNetworkWinsock.h @@ -18,8 +18,11 @@ #pragma once +#include // 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 #include +#pragma comment(lib, "ws2_32.lib") + #define ARCH_NETWORK ArchNetworkWinsock class ArchSocketImpl { @@ -45,8 +50,8 @@ public: static ArchNetAddressImpl* alloc(size_t); public: - int m_len; - struct sockaddr m_addr; + int m_len; + struct sockaddr_storage m_addr; }; #define ADDR_HDR_SIZE offsetof(ArchNetAddressImpl, m_addr) #define TYPED_ADDR(type_, addr_) (reinterpret_cast(&addr_->m_addr)) diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index 422e9556..96611bc5 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -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(socket); // filter socket messages, including a packetizing filter diff --git a/src/lib/net/ISocketFactory.h b/src/lib/net/ISocketFactory.h index 8f1b3838..0bb8a74c 100644 --- a/src/lib/net/ISocketFactory.h +++ b/src/lib/net/ISocketFactory.h @@ -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; //@} }; diff --git a/src/lib/net/NetworkAddress.cpp b/src/lib/net/NetworkAddress.cpp index 2be4fdc1..9e9ae41b 100644 --- a/src/lib/net/NetworkAddress.cpp +++ b/src/lib/net/NetworkAddress.cpp @@ -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(); diff --git a/src/lib/net/TCPListenSocket.cpp b/src/lib/net/TCPListenSocket.cpp index 83bf7861..91322d66 100644 --- a/src/lib/net/TCPListenSocket.cpp +++ b/src/lib/net/TCPListenSocket.cpp @@ -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()); diff --git a/src/lib/net/TCPListenSocket.h b/src/lib/net/TCPListenSocket.h index 4abd752c..0d38eddd 100644 --- a/src/lib/net/TCPListenSocket.h +++ b/src/lib/net/TCPListenSocket.h @@ -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 diff --git a/src/lib/net/TCPSocket.cpp b/src/lib/net/TCPSocket.cpp index 2d189fd7..5a64cef4 100644 --- a/src/lib/net/TCPSocket.cpp +++ b/src/lib/net/TCPSocket.cpp @@ -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()); diff --git a/src/lib/net/TCPSocket.h b/src/lib/net/TCPSocket.h index 42c717cc..b01ded57 100644 --- a/src/lib/net/TCPSocket.h +++ b/src/lib/net/TCPSocket.h @@ -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(); diff --git a/src/lib/net/TCPSocketFactory.cpp b/src/lib/net/TCPSocketFactory.cpp index 6795e73c..c7b871c9 100644 --- a/src/lib/net/TCPSocketFactory.cpp +++ b/src/lib/net/TCPSocketFactory.cpp @@ -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); } diff --git a/src/lib/net/TCPSocketFactory.h b/src/lib/net/TCPSocketFactory.h index ffc29164..b8a25f2d 100644 --- a/src/lib/net/TCPSocketFactory.h +++ b/src/lib/net/TCPSocketFactory.h @@ -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; diff --git a/src/lib/server/ClientListener.cpp b/src/lib/server/ClientListener.cpp index a7e835b7..e534383b 100644 --- a/src/lib/server/ClientListener.cpp +++ b/src/lib/server/ClientListener.cpp @@ -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(),