Net-SockAddr

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

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

MANIFEST  view on Meta::CPAN

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)

t/base.t  view on Meta::CPAN

        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";

t/inet6.t  view on Meta::CPAN

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 )