Net-SockAddr
view release on metacpan or search on metacpan
Changes
clib/CMakeLists.txt
clib/FetchDeps.cmake
clib/panda-net-sockaddr-config.cmake
clib/README.md
clib/src/panda/net/pton.impl
clib/src/panda/net/sockaddr.cc
clib/src/panda/net/sockaddr.h
clib/tests/base.cc
clib/tests/inet4.cc
clib/tests/inet6.cc
clib/tests/lib/test.cc
clib/tests/lib/test.h
clib/tests/main.cc
clib/tests/unix.cc
INSTALL.SKIP
lib/Net/SockAddr.pm
lib/Net/SockAddr.pod
lib/Net/SockAddr/Inet4.pm
lib/Net/SockAddr/Inet4.pod
lib/Net/SockAddr/Inet6.pm
lib/Net/SockAddr/Unix.pod
Makefile.PL
MANIFEST This list of files
MANIFEST.SKIP
SockAddr.xs
src/xs/net/sockaddr.cc
src/xs/net/sockaddr.h
t/base.t
t/constants.t
t/inet4.t
t/inet6.t
t/lib/MyTest.pm
t/unix.t
META.yml Module YAML meta-data (added by MakeMaker)
META.json Module JSON meta-data (added by MakeMaker)
SockAddr.xs view on Meta::CPAN
}
SockAddr SockAddr::new (SockAddr oth) {
RETVAL = oth;
}
sa_family_t SockAddr::family ()
bool SockAddr::is_inet4 ()
bool SockAddr::is_inet6 ()
#ifndef _WIN32
bool SockAddr::is_unix ()
#endif
string_view SockAddr::get () {
if (THIS->family() == AF_UNSPEC) XSRETURN_UNDEF;
RETVAL = string_view((const char*)THIS->get(), THIS->length());
SockAddr.xs view on Meta::CPAN
SockAddr from_addr (string_view addr, uint16_t port, uint32_t scope_id = 0, uint32_t flow_info = 0) {
if (addr.length() != sizeof(in6_addr)) throw "invalid ip6 addr";
RETVAL = SockAddr::Inet6(*(const in6_addr*)addr.data(), port, scope_id, flow_info);
}
SockAddr new (SV*, string_view ip, uint16_t port, uint32_t scope_id = 0, uint32_t flow_info = 0) {
RETVAL = SockAddr::Inet6(ip, port, scope_id, flow_info);
}
string SockAddr::ip () {
RETVAL = THIS->as_inet6().ip();
}
uint16_t SockAddr::port () {
RETVAL = THIS->as_inet6().port();
}
uint32_t SockAddr::scope_id () {
RETVAL = THIS->as_inet6().scope_id();
}
uint32_t SockAddr::flowinfo () {
RETVAL = THIS->as_inet6().flowinfo();
}
string_view SockAddr::addr () {
RETVAL = addr2sv(THIS->as_inet6().addr());
}
MODULE = Net::SockAddr PACKAGE = Net::SockAddr::Unix
PROTOTYPES: DISABLE
#ifndef _WIN32
SockAddr new (SV*, string_view path) {
RETVAL = SockAddr::Unix(path);
clib/src/panda/net/sockaddr.cc view on Meta::CPAN
case AF_UNIX : return !strcmp(sau.sun_path, oth.sau.sun_path);
#endif
default : throw _not_supported();
}
}
string SockAddr::ip () const {
switch (sa.sa_family) {
case AF_UNSPEC: return {};
case AF_INET: return as_inet4().ip();
case AF_INET6: return as_inet6().ip();
default: throw _not_supported();
}
}
uint16_t SockAddr::port () const {
switch (sa.sa_family) {
case AF_UNSPEC: return 0;
case AF_INET: return as_inet4().port();
case AF_INET6: return as_inet6().port();
default: throw _not_supported();
}
}
size_t SockAddr::length () const {
switch (sa.sa_family) {
case AF_UNSPEC: return BASE_LEN;
case AF_INET: return sizeof(sockaddr_in);
case AF_INET6: return sizeof(sockaddr_in6);
#ifndef _WIN32
clib/src/panda/net/sockaddr.cc view on Meta::CPAN
if (length <= BASE_LEN) sau.sun_path[0] = 0;
else sau.sun_path[length - BASE_LEN - 1] = 0;
}
#endif
std::ostream& operator<< (std::ostream& os, const SockAddr& sa) {
switch (sa.family()) {
case AF_UNSPEC : os << "<empty>"; break;
case AF_INET : os << sa.as_inet4().ip() << ':' << sa.as_inet4().port(); break;
case AF_INET6 :
os << '[' << sa.as_inet6().ip();
if (sa.as_inet6().scope_id()) os << '%' << sa.as_inet6().scope_id();
os << "]:" << sa.as_inet6().port();
break;
#ifndef _WIN32
case AF_UNIX : os << sa.as_unix().path(); break;
#endif
default : throw _not_supported();
}
return os;
}
SockAddr::Inet4::Inet4 (const string_view& ip, uint16_t port) {
clib/src/panda/net/sockaddr.h view on Meta::CPAN
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; }
clib/tests/base.cc view on Meta::CPAN
SockAddr tmp;
CHECK(tmp.length() > 0);
SockAddr sa = tmp;
CHECK(sa.family() == AF_UNSPEC);
}
SECTION("from inet4") {
SockAddr sa = (SockAddr)SockAddr::Inet4("10.10.10.2", 1234);
CHECK(sa.is_inet4());
CHECK(sa.as_inet4().ip() == "10.10.10.2");
}
SECTION("from inet6") {
SockAddr sa = (SockAddr)SockAddr::Inet6("::1", 1234);
CHECK(sa.is_inet6());
CHECK(sa.as_inet6().ip() == "::1");
}
#ifndef _WIN32
SECTION("from unix") {
SockAddr sa = (SockAddr)SockAddr::Unix("/path");
CHECK(sa.is_unix());
CHECK(sa.as_unix().path() == "/path");
}
#endif
}
clib/tests/inet6.cc view on Meta::CPAN
#include "lib/test.h"
#define CHECK_SA(sa, _port, ...) { \
CHECK(sa.is_inet6()); \
CHECK(sa.port() == _port); \
unsigned char tmp[16] = __VA_ARGS__; \
CHECK(memcmp(&sa.addr(), tmp, 16) == 0); \
}
TEST_CASE("inet6") {
SECTION("from ip") {
SockAddr::Inet6 sa("0:0:0:0:0:ffff:808:808", 80, 1, 2);
CHECK_SA(sa, 80, {0,0,0,0,0,0,0,0,0,0,255,255,8,8,8,8});
CHECK(sa.ip() == "::ffff:8.8.8.8");
CHECK(sa.scope_id() == 1);
CHECK(sa.flowinfo() == 2);
}
SECTION("from addr") {
SockAddr::Inet6 tmp("::ffff:127.0.0.1", 443);
clib/tests/inet6.cc view on Meta::CPAN
CHECK_SA(sa, 65535, {255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255});
CHECK(sa.ip() == "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
}
#if 0
/* this is real data, we seems coming from resolver; it seems resolver is buggy,
* but we decided to assume it correct*/
SECTION("from bytes") {
char data[] = "\n\000\000\000\000\000\000\000";
SockAddr sa((sockaddr*) data, 8);
CHECK(sa.is_inet6());
}
#endif
SECTION("localhost") {
SockAddr::Inet6 sa("::1", 0);
CHECK(sa.ip() == "::1");
CHECK_SA(sa, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1});
CHECK(sa.scope_id() == 0);
CHECK(sa.flowinfo() == 0);
lib/Net/SockAddr.pod view on Meta::CPAN
=head1 SYNOPSIS
use Net::SockAddr;
$sa = Net::SockAddr::Inet4->new("1.2.3.4", 80);
$sa = Net::SockAddr::Inet6->new("2001:db8::ae21:ad12", 80);
$sa = Net::SockAddr::Unix->new("/tmp/mysock");
connect($sock, $sa->get);
$sa = Net::SockAddr->new($connection->getpeername());
if ($sa->is_inet4 or $sa->is_inet6) {
say $sa->ip;
say $sa->port;
} else { # UNIX socket
say $sa->path;
}
=head1 C SYNOPSIS
lib/Net/SockAddr.pod view on Meta::CPAN
Classes L<Net::SockAddr::Inet4>, L<Net::SockAddr::Inet6> and L<Net::SockAddr::Unix> contains more specialised constructors from ip/port or path.
=head4 family()
Returns AF_INET / AF_INET6 / AF_UNIX
=head4 is_inet4()
Returns true if C<family == AF_INET>
=head4 is_inet6()
Returns true if C<family == AF_INET6>
=head4 is_unix()
Returns true if C<family == AF_UNIX>
=head4 get()
Returns binary string suitable for passing to Perl's C<connect()> functions (representing struct sockaddr_in/in6/un, like what Socket::sockaddr_in returns)
my $_sa = sockaddr_in(1234, $addr);
my $sa = Net::SockAddr->new($_sa);
isa_ok $sa, "Net::SockAddr::Inet4";
ok $sa->is_inet4, "is_inet4";
is $sa->family, AF_INET, "family";
is $sa->port, 1234, "port";
is $sa->ip, $ip, "ip";
is $sa->addr, $addr, "addr";
is $sa->get, $_sa, "sockaddr";
};
subtest "inet6" => sub {
my $ip = "fe80::71a3:2b00:ddd3:753f";
my $addr = inet_pton(AF_INET6, $ip);
my $_sa = sockaddr_in6(123, $addr, 456, 789);
my $sa = Net::SockAddr->new($_sa);
isa_ok $sa, "Net::SockAddr::Inet6";
ok $sa->is_inet6, "is_inet6";
is $sa->family, AF_INET6, "family";
is $sa->port, 123, "port";
is $sa->ip, $ip, "ip";
is $sa->get, $_sa, "sockaddr";
is $sa->scope_id, 456, "scope id";
is $sa->flowinfo, 789, "flow info";
};
subtest "unix" => sub {
plan skip_all => 'AF_UNIX not supported on Windows' if $^O eq 'MSWin32';
my $path = "/epta/huyli";
use 5.012;
use warnings;
use lib 't/lib';
use MyTest;
use Socket qw/AF_INET6 inet_pton/;
catch_run('inet6');
my $ip = "12:34:56:78:90:ab:cd:ef";
my $addr = inet_pton(AF_INET6, $ip);
subtest "from ip" => sub {
my $sa = Net::SockAddr::Inet6->new($ip, 80, 10, 20);
is $sa->port, 80, "port";
is $sa->ip, $ip, "ip";
is $sa, "[$ip%10]:80", "stringify";
is length($sa->addr), 16, "addr";
( run in 0.401 second using v1.01-cache-2.11-cpan-5f2e87ce722 )