fixed NetworkInterface for WinCE

code cleanup in NetworkInterface class
IPAddress: do not format IPv6 loopback address as IPv4 compatible
workaround for WEC2013 getsockname() issue
testsuite fixes for WEC2013
This commit is contained in:
Günter Obiltschnig
2014-09-15 19:17:09 +02:00
parent 67b206f663
commit 63f4bfa54b
8 changed files with 120 additions and 35 deletions

View File

@@ -159,16 +159,19 @@ IPAddress::IPAddress(unsigned prefix, Family family)
{ {
if (prefix <= 32) if (prefix <= 32)
newIPv4(prefix); newIPv4(prefix);
else
throw Poco::InvalidArgumentException("Invalid prefix length passed to IPAddress()");
} }
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
else if (family == IPv6) else if (family == IPv6)
{ {
if (prefix <= 128) if (prefix <= 128)
newIPv6(prefix); newIPv6(prefix);
else
throw Poco::InvalidArgumentException("Invalid prefix length passed to IPAddress()");
} }
#endif #endif
else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()"); else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
if (!pImpl()) throw Poco::InvalidArgumentException("Invalid prefix length passed to IPAddress()");
} }

View File

@@ -56,6 +56,7 @@ namespace Poco {
namespace Net { namespace Net {
namespace Impl { namespace Impl {
// //
// IPAddressImpl // IPAddressImpl
// //
@@ -75,6 +76,7 @@ IPAddressImpl::~IPAddressImpl()
// IPv4AddressImpl // IPv4AddressImpl
// //
IPv4AddressImpl::IPv4AddressImpl() IPv4AddressImpl::IPv4AddressImpl()
{ {
std::memset(&_addr, 0, sizeof(_addr)); std::memset(&_addr, 0, sizeof(_addr));
@@ -348,11 +350,13 @@ IPv6AddressImpl::IPv6AddressImpl(): _scope(0)
std::memset(&_addr, 0, sizeof(_addr)); std::memset(&_addr, 0, sizeof(_addr));
} }
IPv6AddressImpl::IPv6AddressImpl(const void* addr): _scope(0) IPv6AddressImpl::IPv6AddressImpl(const void* addr): _scope(0)
{ {
std::memcpy(&_addr, addr, sizeof(_addr)); std::memcpy(&_addr, addr, sizeof(_addr));
} }
IPv6AddressImpl::IPv6AddressImpl(const void* addr, Poco::UInt32 scope): _scope(scope) IPv6AddressImpl::IPv6AddressImpl(const void* addr, Poco::UInt32 scope): _scope(scope)
{ {
std::memcpy(&_addr, addr, sizeof(_addr)); std::memcpy(&_addr, addr, sizeof(_addr));
@@ -396,10 +400,11 @@ IPv6AddressImpl::IPv6AddressImpl(unsigned prefix):
#endif #endif
} }
std::string IPv6AddressImpl::toString() const std::string IPv6AddressImpl::toString() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
if (isIPv4Compatible() || isIPv4Mapped()) if ((isIPv4Compatible() && !isLoopback()) || isIPv4Mapped())
{ {
std::string result; std::string result;
result.reserve(24); result.reserve(24);
@@ -460,26 +465,31 @@ std::string IPv6AddressImpl::toString() const
} }
} }
poco_socklen_t IPv6AddressImpl::length() const poco_socklen_t IPv6AddressImpl::length() const
{ {
return sizeof(_addr); return sizeof(_addr);
} }
const void* IPv6AddressImpl::addr() const const void* IPv6AddressImpl::addr() const
{ {
return &_addr; return &_addr;
} }
IPAddressImpl::Family IPv6AddressImpl::family() const IPAddressImpl::Family IPv6AddressImpl::family() const
{ {
return IPAddressImpl::IPv6; return IPAddressImpl::IPv6;
} }
int IPv6AddressImpl::af() const int IPv6AddressImpl::af() const
{ {
return AF_INET6; return AF_INET6;
} }
unsigned IPv6AddressImpl::prefixLength() const unsigned IPv6AddressImpl::prefixLength() const
{ {
unsigned bits = 0; unsigned bits = 0;
@@ -510,6 +520,7 @@ Poco::UInt32 IPv6AddressImpl::scope() const
return _scope; return _scope;
} }
bool IPv6AddressImpl::isWildcard() const bool IPv6AddressImpl::isWildcard() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
@@ -517,11 +528,13 @@ bool IPv6AddressImpl::isWildcard() const
words[4] == 0 && words[5] == 0 && words[6] == 0 && words[7] == 0; words[4] == 0 && words[5] == 0 && words[6] == 0 && words[7] == 0;
} }
bool IPv6AddressImpl::isBroadcast() const bool IPv6AddressImpl::isBroadcast() const
{ {
return false; return false;
} }
bool IPv6AddressImpl::isLoopback() const bool IPv6AddressImpl::isLoopback() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
@@ -529,72 +542,84 @@ bool IPv6AddressImpl::isLoopback() const
words[4] == 0 && words[5] == 0 && words[6] == 0 && ntohs(words[7]) == 0x0001; words[4] == 0 && words[5] == 0 && words[6] == 0 && ntohs(words[7]) == 0x0001;
} }
bool IPv6AddressImpl::isMulticast() const bool IPv6AddressImpl::isMulticast() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (ntohs(words[0]) & 0xFFE0) == 0xFF00; return (ntohs(words[0]) & 0xFFE0) == 0xFF00;
} }
bool IPv6AddressImpl::isLinkLocal() const bool IPv6AddressImpl::isLinkLocal() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (ntohs(words[0]) & 0xFFE0) == 0xFE80; return (ntohs(words[0]) & 0xFFE0) == 0xFE80;
} }
bool IPv6AddressImpl::isSiteLocal() const bool IPv6AddressImpl::isSiteLocal() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return ((ntohs(words[0]) & 0xFFE0) == 0xFEC0) || ((ntohs(words[0]) & 0xFF00) == 0xFC00); return ((ntohs(words[0]) & 0xFFE0) == 0xFEC0) || ((ntohs(words[0]) & 0xFF00) == 0xFC00);
} }
bool IPv6AddressImpl::isIPv4Compatible() const bool IPv6AddressImpl::isIPv4Compatible() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && words[5] == 0; return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && words[5] == 0;
} }
bool IPv6AddressImpl::isIPv4Mapped() const bool IPv6AddressImpl::isIPv4Mapped() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && ntohs(words[5]) == 0xFFFF; return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && ntohs(words[5]) == 0xFFFF;
} }
bool IPv6AddressImpl::isWellKnownMC() const bool IPv6AddressImpl::isWellKnownMC() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (ntohs(words[0]) & 0xFFF0) == 0xFF00; return (ntohs(words[0]) & 0xFFF0) == 0xFF00;
} }
bool IPv6AddressImpl::isNodeLocalMC() const bool IPv6AddressImpl::isNodeLocalMC() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (ntohs(words[0]) & 0xFFEF) == 0xFF01; return (ntohs(words[0]) & 0xFFEF) == 0xFF01;
} }
bool IPv6AddressImpl::isLinkLocalMC() const bool IPv6AddressImpl::isLinkLocalMC() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (ntohs(words[0]) & 0xFFEF) == 0xFF02; return (ntohs(words[0]) & 0xFFEF) == 0xFF02;
} }
bool IPv6AddressImpl::isSiteLocalMC() const bool IPv6AddressImpl::isSiteLocalMC() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (ntohs(words[0]) & 0xFFEF) == 0xFF05; return (ntohs(words[0]) & 0xFFEF) == 0xFF05;
} }
bool IPv6AddressImpl::isOrgLocalMC() const bool IPv6AddressImpl::isOrgLocalMC() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (ntohs(words[0]) & 0xFFEF) == 0xFF08; return (ntohs(words[0]) & 0xFFEF) == 0xFF08;
} }
bool IPv6AddressImpl::isGlobalMC() const bool IPv6AddressImpl::isGlobalMC() const
{ {
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr); const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
return (ntohs(words[0]) & 0xFFEF) == 0xFF0F; return (ntohs(words[0]) & 0xFFEF) == 0xFF0F;
} }
IPv6AddressImpl IPv6AddressImpl::parse(const std::string& addr) IPv6AddressImpl IPv6AddressImpl::parse(const std::string& addr)
{ {
if (addr.empty()) return IPv6AddressImpl(); if (addr.empty()) return IPv6AddressImpl();
@@ -637,16 +662,19 @@ IPv6AddressImpl IPv6AddressImpl::parse(const std::string& addr)
#endif #endif
} }
void IPv6AddressImpl::mask(const IPAddressImpl* pMask, const IPAddressImpl* pSet) void IPv6AddressImpl::mask(const IPAddressImpl* pMask, const IPAddressImpl* pSet)
{ {
throw Poco::NotImplementedException("mask() is only supported for IPv4 addresses"); throw Poco::NotImplementedException("mask() is only supported for IPv4 addresses");
} }
IPAddressImpl* IPv6AddressImpl::clone() const IPAddressImpl* IPv6AddressImpl::clone() const
{ {
return new IPv6AddressImpl(&_addr, _scope); return new IPv6AddressImpl(&_addr, _scope);
} }
IPv6AddressImpl IPv6AddressImpl::operator & (const IPv6AddressImpl& addr) const IPv6AddressImpl IPv6AddressImpl::operator & (const IPv6AddressImpl& addr) const
{ {
IPv6AddressImpl result(&_addr); IPv6AddressImpl result(&_addr);
@@ -668,6 +696,7 @@ IPv6AddressImpl IPv6AddressImpl::operator & (const IPv6AddressImpl& addr) const
return result; return result;
} }
IPv6AddressImpl IPv6AddressImpl::operator | (const IPv6AddressImpl& addr) const IPv6AddressImpl IPv6AddressImpl::operator | (const IPv6AddressImpl& addr) const
{ {
IPv6AddressImpl result(&_addr); IPv6AddressImpl result(&_addr);
@@ -689,6 +718,7 @@ IPv6AddressImpl IPv6AddressImpl::operator | (const IPv6AddressImpl& addr) const
return result; return result;
} }
IPv6AddressImpl IPv6AddressImpl::operator ^ (const IPv6AddressImpl& addr) const IPv6AddressImpl IPv6AddressImpl::operator ^ (const IPv6AddressImpl& addr) const
{ {
IPv6AddressImpl result(&_addr); IPv6AddressImpl result(&_addr);
@@ -710,6 +740,7 @@ IPv6AddressImpl IPv6AddressImpl::operator ^ (const IPv6AddressImpl& addr) const
return result; return result;
} }
IPv6AddressImpl IPv6AddressImpl::operator ~ () const IPv6AddressImpl IPv6AddressImpl::operator ~ () const
{ {
IPv6AddressImpl result(&_addr); IPv6AddressImpl result(&_addr);

View File

@@ -151,13 +151,20 @@ private:
NetworkInterface::MACAddress _macAddress; NetworkInterface::MACAddress _macAddress;
friend NetworkInterface::Map NetworkInterface::map(bool, bool); friend class NetworkInterface;
}; };
NetworkInterfaceImpl::NetworkInterfaceImpl(unsigned index): NetworkInterfaceImpl::NetworkInterfaceImpl(unsigned index):
_index(index), _index(index),
_mtu(0) _broadcast(false),
_loopback(false),
_multicast(false),
_pointToPoint(false),
_up(false),
_running(false),
_mtu(0),
_type(NetworkInterface::NI_TYPE_OTHER)
{ {
} }
@@ -173,7 +180,8 @@ NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const std::s
_pointToPoint(false), _pointToPoint(false),
_up(false), _up(false),
_running(false), _running(false),
_mtu(0) _mtu(0),
_type(NetworkInterface::NI_TYPE_OTHER)
{ {
_addressList.push_back(AddressTuple(address, IPAddress(), IPAddress())); _addressList.push_back(AddressTuple(address, IPAddress(), IPAddress()));
setPhyParams(); setPhyParams();
@@ -192,7 +200,8 @@ NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const std::s
_pointToPoint(false), _pointToPoint(false),
_up(false), _up(false),
_running(false), _running(false),
_mtu(0) _mtu(0),
_type(NetworkInterface::NI_TYPE_OTHER)
{ {
setPhyParams(); setPhyParams();
if (pMACAddress) setMACAddress(*pMACAddress); if (pMACAddress) setMACAddress(*pMACAddress);
@@ -430,6 +439,7 @@ inline bool NetworkInterfaceImpl::up() const
#if defined(POCO_OS_FAMILY_WINDOWS) #if defined(POCO_OS_FAMILY_WINDOWS)
void NetworkInterfaceImpl::setFlags(DWORD flags, DWORD iftype) void NetworkInterfaceImpl::setFlags(DWORD flags, DWORD iftype)
{ {
_running = _up = false; _running = _up = false;
@@ -453,13 +463,16 @@ void NetworkInterfaceImpl::setFlags(DWORD flags, DWORD iftype)
_multicast = true; _multicast = true;
} }
void NetworkInterfaceImpl::setRunning(bool running) void NetworkInterfaceImpl::setRunning(bool running)
{ {
_running = running; _running = running;
} }
#else #else
void NetworkInterfaceImpl::setFlags(short flags) void NetworkInterfaceImpl::setFlags(short flags)
{ {
#ifdef POCO_OS_FAMILY_UNIX #ifdef POCO_OS_FAMILY_UNIX
@@ -472,6 +485,7 @@ void NetworkInterfaceImpl::setFlags(short flags)
#endif #endif
} }
#endif #endif
@@ -525,8 +539,6 @@ inline void NetworkInterfaceImpl::addAddress(const IPAddress& addr)
inline void NetworkInterfaceImpl::setMACAddress(const NetworkInterface::MACAddress& addr) inline void NetworkInterfaceImpl::setMACAddress(const NetworkInterface::MACAddress& addr)
{ {
_macAddress = addr; _macAddress = addr;
} }
@@ -534,8 +546,7 @@ inline void NetworkInterfaceImpl::setMACAddress(const NetworkInterface::MACAddre
inline void NetworkInterfaceImpl::setMACAddress(const void *addr, std::size_t len) inline void NetworkInterfaceImpl::setMACAddress(const void *addr, std::size_t len)
{ {
_macAddress.clear(); _macAddress.clear();
for (unsigned i = 0; i < len; ++i) _macAddress.insert(_macAddress.end(), static_cast<const unsigned char*>(addr), static_cast<const unsigned char*>(addr) + len);
_macAddress.push_back(((unsigned char *)addr)[i]);
} }
@@ -719,11 +730,13 @@ unsigned NetworkInterface::mtu() const
return _pImpl->mtu(); return _pImpl->mtu();
} }
NetworkInterface::Type NetworkInterface::type() const NetworkInterface::Type NetworkInterface::type() const
{ {
return _pImpl->type(); return _pImpl->type();
} }
bool NetworkInterface::supportsIP() const bool NetworkInterface::supportsIP() const
{ {
return _pImpl->supportsIPv4() || _pImpl->supportsIPv6(); return _pImpl->supportsIPv4() || _pImpl->supportsIPv6();
@@ -760,7 +773,6 @@ bool NetworkInterface::isLoopback() const
} }
bool NetworkInterface::isPointToPoint() const bool NetworkInterface::isPointToPoint() const
{ {
return _pImpl->pointToPoint(); return _pImpl->pointToPoint();
@@ -874,13 +886,24 @@ NetworkInterface::List NetworkInterface::list(bool ipOnly, bool upOnly)
IPAddress mask = ipIt->get<NetworkInterface::SUBNET_MASK>(); IPAddress mask = ipIt->get<NetworkInterface::SUBNET_MASK>();
NetworkInterface ni; NetworkInterface ni;
if (mask.isWildcard()) if (mask.isWildcard())
{
ni = NetworkInterface(name, displayName, adapterName, addr, index, &mac); ni = NetworkInterface(name, displayName, adapterName, addr, index, &mac);
}
else else
{ {
IPAddress broadcast = ipIt->get<NetworkInterface::BROADCAST_ADDRESS>(); IPAddress broadcast = ipIt->get<NetworkInterface::BROADCAST_ADDRESS>();
ni = NetworkInterface(name, displayName, adapterName, addr, mask, broadcast, index, &mac); ni = NetworkInterface(name, displayName, adapterName, addr, mask, broadcast, index, &mac);
} }
ni._pImpl->_broadcast = it->second._pImpl->_broadcast;
ni._pImpl->_loopback = it->second._pImpl->_loopback;
ni._pImpl->_multicast = it->second._pImpl->_multicast;
ni._pImpl->_pointToPoint = it->second._pImpl->_pointToPoint;
ni._pImpl->_up = it->second._pImpl->_up;
ni._pImpl->_running = it->second._pImpl->_running;
ni._pImpl->_mtu = it->second._pImpl->_mtu;
ni._pImpl->_type = it->second._pImpl->_type;
list.push_back(ni); list.push_back(ni);
} }
} }
@@ -975,6 +998,7 @@ IPAddress subnetMaskForInterface(const std::string& name, bool isLoopback)
} }
else else
{ {
#if !defined(_WIN32_WCE)
std::string subKey("SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces\\"); std::string subKey("SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces\\");
subKey += name; subKey += name;
std::string netmask; std::string netmask;
@@ -1012,6 +1036,9 @@ IPAddress subnetMaskForInterface(const std::string& name, bool isLoopback)
#endif #endif
RegCloseKey(hKey); RegCloseKey(hKey);
return IPAddress::parse(netmask); return IPAddress::parse(netmask);
#else
return IPAddress();
#endif // !defined(_WIN32_WCE)
} }
} }
@@ -1054,7 +1081,8 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
throw SystemException(format("An error occurred while trying to obtain list of network interfaces: [%s]", Error::getMessage(dwRetVal))); throw SystemException(format("An error occurred while trying to obtain list of network interfaces: [%s]", Error::getMessage(dwRetVal)));
else else
break; break;
} while ((ERROR_BUFFER_OVERFLOW == dwRetVal) && (++iterations <= 2)); }
while ((ERROR_BUFFER_OVERFLOW == dwRetVal) && (++iterations <= 2));
poco_assert (NO_ERROR == dwRetVal); poco_assert (NO_ERROR == dwRetVal);
for (; pAddress; pAddress = pAddress->Next) for (; pAddress; pAddress = pAddress->Next)
@@ -1158,36 +1186,41 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
// we reflect the actual values held by system and protect against misconfiguration (e.g. bad DHCP config entry) // we reflect the actual values held by system and protect against misconfiguration (e.g. bad DHCP config entry)
#if defined(_WIN32_WCE) #if defined(_WIN32_WCE)
ULONG prefixLength = 0; ULONG prefixLength = 0;
#if _WIN32_WCE >= 0x0800
prefixLength = pUniAddr->OnLinkPrefixLength;
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address);
#else
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address, &prefixLength); broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address, &prefixLength);
#endif
// if previous call did not do it, make last-ditch attempt for prefix and broadcast // if previous call did not do it, make last-ditch attempt for prefix and broadcast
if (prefixLength == 0 && pAddress->FirstPrefix) if (prefixLength == 0 && pAddress->FirstPrefix)
prefixLength = pAddress->FirstPrefix->PrefixLength; prefixLength = pAddress->FirstPrefix->PrefixLength;
poco_assert (prefixLength <= 32); poco_assert (prefixLength <= 32);
if (broadcastAddress.isWildcard()) if (broadcastAddress.isWildcard())
{ {
IPAddress mask ((unsigned) prefixLength, IPAddress::IPv4); IPAddress mask(static_cast<unsigned>(prefixLength), IPAddress::IPv4);
IPAddress host(mask & address); IPAddress host(mask & address);
broadcastAddress = host | ~mask; broadcastAddress = host | ~mask;
} }
#elif (_WIN32_WINNT >= 0x0501) && (NTDDI_VERSION >= 0x05010100) // Win XP SP1 #elif (_WIN32_WINNT >= 0x0501) && (NTDDI_VERSION >= 0x05010100) // Win XP SP1
#if (_WIN32_WINNT >= 0x0600) // Vista and newer
UINT8 prefixLength = pUniAddr->OnLinkPrefixLength;
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address);
#else // _WIN32_WINNT < 0x0600
ULONG prefixLength = 0; ULONG prefixLength = 0;
#if (_WIN32_WINNT >= 0x0600) // Vista and newer
prefixLength = pUniAddr->OnLinkPrefixLength;
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address);
#else
broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address, &prefixLength); broadcastAddress = getBroadcastAddress(pAddress->FirstPrefix, address, &prefixLength);
#endif
poco_assert (prefixLength <= 32); poco_assert (prefixLength <= 32);
if (broadcastAddress.isWildcard()) if (broadcastAddress.isWildcard())
{ {
IPAddress mask ((unsigned) prefixLength, IPAddress::IPv4); IPAddress mask(static_cast<unsigned>(prefixLength), IPAddress::IPv4);
IPAddress host(mask & address); IPAddress host(mask & address);
broadcastAddress = host | ~mask; broadcastAddress = host | ~mask;
} }
#endif // _WIN32_WINNT >= 0x0600
#endif // (_WIN32_WINNT >= 0x0501) && (NTDDI_VERSION >= 0x05010100) #endif // (_WIN32_WINNT >= 0x0501) && (NTDDI_VERSION >= 0x05010100)
if (prefixLength) if (prefixLength)
{ {
subnetMask = IPAddress(prefixLength, IPAddress::IPv4); subnetMask = IPAddress(static_cast<unsigned>(prefixLength), IPAddress::IPv4);
} }
else // if all of the above fails, look up the subnet mask in the registry else // if all of the above fails, look up the subnet mask in the registry
{ {
@@ -1202,8 +1235,11 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
ifIt->second.addAddress(address, subnetMask, broadcastAddress); ifIt->second.addAddress(address, subnetMask, broadcastAddress);
} }
else else
{
ifIt->second.addAddress(address); ifIt->second.addAddress(address);
} break; }
}
break;
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
case AF_INET6: case AF_INET6:
ifIt->second.addAddress(address); ifIt->second.addAddress(address);

View File

@@ -177,9 +177,18 @@ int TCPServer::refusedConnections() const
std::string TCPServer::threadName(const ServerSocket& socket) std::string TCPServer::threadName(const ServerSocket& socket)
{ {
#if _WIN32_WCE == 0x0800
// Workaround for WEC2013: only the first call to getsockname()
// succeeds. To mitigate the impact of this bug, do not call
// socket.address(), which calls getsockname(), here.
std::string name("TCPServer");
#pragma message("Using WEC2013 getsockname() workaround in TCPServer::threadName(). Remove when no longer needed.")
#else
std::string name("TCPServer: "); std::string name("TCPServer: ");
name.append(socket.address().toString()); name.append(socket.address().toString());
#endif
return name; return name;
} }

View File

@@ -124,7 +124,8 @@ void FTPClientSessionTest::testLogin2()
server.addResponse("331 Password required"); server.addResponse("331 Password required");
server.addResponse("230 Welcome"); server.addResponse("230 Welcome");
server.addResponse("200 Type set to I"); server.addResponse("200 Type set to I");
FTPClientSession session("localhost", server.port(), "user", "password"); Poco::UInt16 serverPort = server.port();
FTPClientSession session("localhost", serverPort, "user", "password");
assert (session.isOpen()); assert (session.isOpen());
assert (session.isLoggedIn()); assert (session.isLoggedIn());
server.addResponse("221 Good Bye"); server.addResponse("221 Good Bye");
@@ -138,7 +139,7 @@ void FTPClientSessionTest::testLogin2()
server.addResponse("331 Password required"); server.addResponse("331 Password required");
server.addResponse("230 Welcome"); server.addResponse("230 Welcome");
server.addResponse("200 Type set to I"); server.addResponse("200 Type set to I");
session.open("localhost", server.port(), "user", "password"); session.open("localhost", serverPort, "user", "password");
assert (session.isOpen()); assert (session.isOpen());
assert (session.isLoggedIn()); assert (session.isLoggedIn());
server.addResponse("221 Good Bye"); server.addResponse("221 Good Bye");
@@ -451,9 +452,10 @@ void FTPClientSessionTest::testDownloadPASV()
server.addResponse("500 EPSV not understood"); server.addResponse("500 EPSV not understood");
DialogServer dataServer(false); DialogServer dataServer(false);
Poco::UInt16 dataServerPort = dataServer.port();
dataServer.addResponse("This is some data"); dataServer.addResponse("This is some data");
std::ostringstream pasv; std::ostringstream pasv;
pasv << "227 Entering Passive Mode (127,0,0,1," << (dataServer.port()/256) << "," << (dataServer.port() % 256) << ")"; pasv << "227 Entering Passive Mode (127,0,0,1," << (dataServerPort/256) << "," << (dataServerPort % 256) << ")";
server.addResponse(pasv.str()); server.addResponse(pasv.str());
server.addResponse("150 sending data\r\n226 Transfer complete"); server.addResponse("150 sending data\r\n226 Transfer complete");

View File

@@ -58,6 +58,10 @@ void IPAddressTest::testStringConv()
void IPAddressTest::testStringConv6() void IPAddressTest::testStringConv6()
{ {
#ifdef POCO_HAVE_IPv6 #ifdef POCO_HAVE_IPv6
IPAddress ia0("::1");
assert (ia0.family() == IPAddress::IPv6);
assert (ia0.toString() == "::1");
IPAddress ia1("1080:0:0:0:8:600:200a:425c"); IPAddress ia1("1080:0:0:0:8:600:200a:425c");
assert (ia1.family() == IPAddress::IPv6); assert (ia1.family() == IPAddress::IPv6);
assert (ia1.toString() == "1080::8:600:200a:425c"); assert (ia1.toString() == "1080::8:600:200a:425c");

View File

@@ -50,7 +50,7 @@ void NetworkInterfaceTest::testMap()
std::cout << "Index: " << it->second.index() << std::endl; std::cout << "Index: " << it->second.index() << std::endl;
std::cout << "Name: " << it->second.name() << std::endl; std::cout << "Name: " << it->second.name() << std::endl;
std::cout << "DisplayName: " << it->second.displayName() << std::endl; std::cout << "DisplayName: " << it->second.displayName() << std::endl;
std::cout << "Status: " << (it->second.isUp() ? "Up" : "Down") << std::endl; std::cout << "Status: " << (it->second.isUp() ? "Up" : "Down") << std::endl;
NetworkInterface::MACAddress mac(it->second.macAddress()); NetworkInterface::MACAddress mac(it->second.macAddress());
if (!mac.empty() && (it->second.type() != NetworkInterface::NI_TYPE_SOFTWARE_LOOPBACK)) if (!mac.empty() && (it->second.type() != NetworkInterface::NI_TYPE_SOFTWARE_LOOPBACK))
@@ -88,7 +88,7 @@ void NetworkInterfaceTest::testList()
std::cout << "Index: " << it->index() << std::endl; std::cout << "Index: " << it->index() << std::endl;
std::cout << "Name: " << it->name() << std::endl; std::cout << "Name: " << it->name() << std::endl;
std::cout << "DisplayName: " << it->displayName() << std::endl; std::cout << "DisplayName: " << it->displayName() << std::endl;
std::cout << "Status: " << (it->isUp() ? "Up" : "Down") << std::endl; std::cout << "Status: " << (it->isUp() ? "Up" : "Down") << std::endl;
NetworkInterface::MACAddress mac(it->macAddress()); NetworkInterface::MACAddress mac(it->macAddress());
if (!mac.empty() && (it->type() != NetworkInterface::NI_TYPE_SOFTWARE_LOOPBACK)) if (!mac.empty() && (it->type() != NetworkInterface::NI_TYPE_SOFTWARE_LOOPBACK))

View File

@@ -97,7 +97,7 @@ void TCPServerTest::testOneConnection()
assert (srv.queuedConnections() == 0); assert (srv.queuedConnections() == 0);
assert (srv.totalConnections() == 1); assert (srv.totalConnections() == 1);
ss1.close(); ss1.close();
Thread::sleep(300); Thread::sleep(1000);
assert (srv.currentConnections() == 0); assert (srv.currentConnections() == 0);
} }
@@ -132,14 +132,14 @@ void TCPServerTest::testTwoConnections()
assert (srv.queuedConnections() == 0); assert (srv.queuedConnections() == 0);
assert (srv.totalConnections() == 2); assert (srv.totalConnections() == 2);
ss1.close(); ss1.close();
Thread::sleep(300); Thread::sleep(1000);
assert (srv.currentConnections() == 1); assert (srv.currentConnections() == 1);
assert (srv.currentThreads() == 1); assert (srv.currentThreads() == 1);
assert (srv.queuedConnections() == 0); assert (srv.queuedConnections() == 0);
assert (srv.totalConnections() == 2); assert (srv.totalConnections() == 2);
ss2.close(); ss2.close();
Thread::sleep(300); Thread::sleep(1000);
assert (srv.currentConnections() == 0); assert (srv.currentConnections() == 0);
} }
@@ -200,28 +200,28 @@ void TCPServerTest::testMultiConnections()
assert (srv.queuedConnections() == 2); assert (srv.queuedConnections() == 2);
ss1.close(); ss1.close();
Thread::sleep(300); Thread::sleep(2000);
assert (srv.currentConnections() == 4); assert (srv.currentConnections() == 4);
assert (srv.currentThreads() == 4); assert (srv.currentThreads() == 4);
assert (srv.queuedConnections() == 1); assert (srv.queuedConnections() == 1);
assert (srv.totalConnections() == 5); assert (srv.totalConnections() == 5);
ss2.close(); ss2.close();
Thread::sleep(300); Thread::sleep(1000);
assert (srv.currentConnections() == 4); assert (srv.currentConnections() == 4);
assert (srv.currentThreads() == 4); assert (srv.currentThreads() == 4);
assert (srv.queuedConnections() == 0); assert (srv.queuedConnections() == 0);
assert (srv.totalConnections() == 6); assert (srv.totalConnections() == 6);
ss3.close(); ss3.close();
Thread::sleep(300); Thread::sleep(1000);
assert (srv.currentConnections() == 3); assert (srv.currentConnections() == 3);
assert (srv.currentThreads() == 3); assert (srv.currentThreads() == 3);
assert (srv.queuedConnections() == 0); assert (srv.queuedConnections() == 0);
assert (srv.totalConnections() == 6); assert (srv.totalConnections() == 6);
ss4.close(); ss4.close();
Thread::sleep(300); Thread::sleep(1000);
assert (srv.currentConnections() == 2); assert (srv.currentConnections() == 2);
assert (srv.currentThreads() == 2); assert (srv.currentThreads() == 2);
assert (srv.queuedConnections() == 0); assert (srv.queuedConnections() == 0);
@@ -229,7 +229,7 @@ void TCPServerTest::testMultiConnections()
ss5.close(); ss5.close();
ss6.close(); ss6.close();
Thread::sleep(300); Thread::sleep(1000);
assert (srv.currentConnections() == 0); assert (srv.currentConnections() == 0);
} }