support for AF_UNIX socket address

This commit is contained in:
Guenter Obiltschnig
2015-09-07 17:53:25 +02:00
parent dba1d44b15
commit 843f251487
9 changed files with 333 additions and 82 deletions

View File

@@ -20,7 +20,6 @@
#include "Poco/Net/DNS.h"
#include "Poco/RefCountedObject.h"
#include "Poco/NumberParser.h"
#include "Poco/NumberFormatter.h"
#include "Poco/BinaryReader.h"
#include "Poco/BinaryWriter.h"
#include <algorithm>
@@ -29,12 +28,16 @@
using Poco::RefCountedObject;
using Poco::NumberParser;
using Poco::NumberFormatter;
using Poco::UInt16;
using Poco::InvalidArgumentException;
using Poco::Net::Impl::SocketAddressImpl;
using Poco::Net::Impl::IPv4SocketAddressImpl;
#ifdef POCO_HAVE_IPv6
using Poco::Net::Impl::IPv6SocketAddressImpl;
#endif
#ifdef POCO_OS_FAMILY_UNIX
using Poco::Net::Impl::LocalSocketAddressImpl;
#endif
namespace Poco {
@@ -85,41 +88,30 @@ SocketAddress::SocketAddress(const std::string& hostAddress, const std::string&
}
SocketAddress::SocketAddress(Family family, const std::string& addr)
{
init(family, addr);
}
SocketAddress::SocketAddress(const std::string& hostAndPort)
{
poco_assert (!hostAndPort.empty());
std::string host;
std::string port;
std::string::const_iterator it = hostAndPort.begin();
std::string::const_iterator end = hostAndPort.end();
if (*it == '[')
{
++it;
while (it != end && *it != ']') host += *it++;
if (it == end) throw InvalidArgumentException("Malformed IPv6 address");
++it;
}
else
{
while (it != end && *it != ':') host += *it++;
}
if (it != end && *it == ':')
{
++it;
while (it != end) port += *it++;
}
else throw InvalidArgumentException("Missing port number");
init(host, resolveService(port));
init(hostAndPort);
}
SocketAddress::SocketAddress(const SocketAddress& socketAddress)
{
if (socketAddress.family() == IPAddress::IPv4)
if (socketAddress.family() == IPv4)
newIPv4(reinterpret_cast<const sockaddr_in*>(socketAddress.addr()));
else
#if defined(POCO_HAVE_IPv6)
else if (socketAddress.family() == IPv6)
newIPv6(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
#endif
#if defined(POCO_OS_FAMILY_UNIX)
else if (socketAddress.family() == UNIX_LOCAL)
newLocal(reinterpret_cast<const sockaddr_un*>(socketAddress.addr()));
#endif
}
@@ -130,6 +122,10 @@ SocketAddress::SocketAddress(const struct sockaddr* sockAddr, poco_socklen_t len
#if defined(POCO_HAVE_IPv6)
else if (length == sizeof(struct sockaddr_in6))
newIPv6(reinterpret_cast<const struct sockaddr_in6*>(sockAddr));
#endif
#if defined(POCO_OS_FAMILY_UNIX)
else if (length > 0 && length <= sizeof(struct sockaddr_un) && sockAddr->sa_family == AF_UNIX)
newLocal(reinterpret_cast<const sockaddr_un*>(sockAddr));
#endif
else throw Poco::InvalidArgumentException("Invalid address length passed to SocketAddress()");
}
@@ -145,6 +141,9 @@ bool SocketAddress::operator < (const SocketAddress& socketAddress) const
{
if (family() < socketAddress.family()) return true;
if (family() > socketAddress.family()) return false;
#if defined(POCO_OS_FAMILY_UNIX)
if (family() == UNIX_LOCAL) return toString() < socketAddress.toString();
#endif
if (host() < socketAddress.host()) return true;
if (host() > socketAddress.host()) return false;
return (port() < socketAddress.port());
@@ -156,10 +155,16 @@ SocketAddress& SocketAddress::operator = (const SocketAddress& socketAddress)
if (&socketAddress != this)
{
destruct();
if (socketAddress.family() == IPAddress::IPv4)
if (socketAddress.family() == IPv4)
newIPv4(reinterpret_cast<const sockaddr_in*>(socketAddress.addr()));
else
#if defined(POCO_HAVE_IPv6)
else if (socketAddress.family() == IPv6)
newIPv6(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
#endif
#if defined(POCO_OS_FAMILY_UNIX)
else if (socketAddress.family() == UNIX_LOCAL)
newLocal(reinterpret_cast<const sockaddr_un*>(socketAddress.addr()));
#endif
}
return *this;
}
@@ -195,19 +200,15 @@ int SocketAddress::af() const
}
SocketAddress::Family SocketAddress::family() const
{
return static_cast<Family>(pImpl()->family());
}
std::string SocketAddress::toString() const
{
std::string result;
#if defined(POCO_HAVE_IPv6)
if (host().family() == IPAddress::IPv6)
result.append("[");
result.append(host().toString());
if (host().family() == IPAddress::IPv6)
result.append("]");
#endif
result.append(":");
NumberFormatter::append(result, port());
return result;
return pImpl()->toString();
}
@@ -247,6 +248,46 @@ void SocketAddress::init(const std::string& hostAddress, Poco::UInt16 portNumber
}
void SocketAddress::init(Family family, const std::string& address)
{
if (family == UNIX_LOCAL)
{
newLocal(address);
}
else
{
init(address);
}
}
void SocketAddress::init(const std::string& hostAndPort)
{
std::string host;
std::string port;
std::string::const_iterator it = hostAndPort.begin();
std::string::const_iterator end = hostAndPort.end();
if (*it == '[')
{
++it;
while (it != end && *it != ']') host += *it++;
if (it == end) throw InvalidArgumentException("Malformed IPv6 address");
++it;
}
else
{
while (it != end && *it != ':') host += *it++;
}
if (it != end && *it == ':')
{
++it;
while (it != end) port += *it++;
}
else throw InvalidArgumentException("Missing port number");
init(host, resolveService(port));
}
Poco::UInt16 SocketAddress::resolveService(const std::string& service)
{
unsigned port;