Net-SockAddr
view release on metacpan or search on metacpan
clib/src/panda/net/sockaddr.h view on Meta::CPAN
#pragma once
#include <panda/string.h>
#include <panda/string_view.h>
#include <utility>
#ifdef _WIN32
#include <winsock2.h>
#include <Ws2tcpip.h>
#else
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/un.h>
#endif
namespace panda { namespace net {
using sa_family_t = decltype(std::declval<sockaddr>().sa_family);
struct SockAddr {
struct Inet4;
struct Inet6;
static const size_t IP4_MAX_ADDRSTRLEN = 16;
static const size_t IP6_MAX_ADDRSTRLEN = 46;
static const size_t BASE_LEN = offsetof(sockaddr, sa_data);
SockAddr () { sa.sa_family = AF_UNSPEC; }
SockAddr (const sockaddr* sa, size_t length);
SockAddr (const sockaddr_in* sa) : sa4(*sa) {}
SockAddr (const sockaddr_in6* sa) : sa6(*sa) {}
SockAddr (const SockAddr& oth) { operator=(oth); }
SockAddr& operator= (const SockAddr& oth);
sa_family_t family () const { return sa.sa_family; }
bool is_inet4 () const { return family() == AF_INET; }
bool is_inet6 () const { return family() == AF_INET6; }
const Inet4& as_inet4 () const { return *((const Inet4*)this); }
const Inet6& as_inet6 () const { return *((const Inet6*)this); }
Inet4& as_inet4 () { return *((Inet4*)this); }
Inet6& as_inet6 () { return *((Inet6*)this); }
const sockaddr* get () const { return &sa; }
sockaddr* get () { return &sa; }
bool operator== (const SockAddr& oth) const;
bool operator!= (const SockAddr& oth) const { return !operator==(oth); }
explicit
operator bool () const { return sa.sa_family != AF_UNSPEC; }
string ip () const;
uint16_t port () const;
size_t length () const;
template <typename Function>
void assign_foreign (Function&& fn) {
size_t length = sizeof(SockAddr); // max size
bool success = fn(&sa, &length);
if (success) {
// length is the actual size
validate(&sa, length);
#ifndef _WIN32
if (sa.sa_family == AF_UNIX) fix_unix_path(length);
#endif
}
}
#ifndef _WIN32
static const size_t PATH_OFFSET = offsetof(sockaddr_un, sun_path);
struct Unix;
SockAddr (const sockaddr_un* sa, size_t length) : SockAddr((const sockaddr*)sa, length) {}
bool is_unix () const { return family() == AF_UNIX; }
Unix& as_unix () const { return *((Unix*)this); }
#endif
protected:
union {
sockaddr sa;
sockaddr_in sa4;
sockaddr_in6 sa6;
#ifndef _WIN32
sockaddr_un sau;
#endif
};
private:
void validate (const sockaddr*, size_t len);
#ifndef _WIN32
void fix_unix_path (size_t length) noexcept;
#endif
};
std::ostream& operator<< (std::ostream&, const SockAddr&);
struct SockAddr::Inet4 : SockAddr {
static const in_addr addr_any;
( run in 0.636 second using v1.01-cache-2.11-cpan-39bf76dae61 )