Blame lib/IO/Socket/INET6.pm

Packit a83d8b
# IO::Socket::INET6.pm
Packit a83d8b
#
Packit a83d8b
# Copyright (c) 1997-8 Graham Barr <gbarr@pobox.com>. All rights reserved.
Packit a83d8b
# This program is free software; you can redistribute it and/or
Packit a83d8b
# modify it under the same terms as Perl itself.
Packit a83d8b
#
Packit a83d8b
# Modified by Rafael Martinez-Torres <rafael.martinez@novagnet.com>
Packit a83d8b
# Euro6IX project (www.euro6ix.org) 2003.
Packit a83d8b
Packit a83d8b
package IO::Socket::INET6;
Packit a83d8b
Packit a83d8b
use strict;
Packit a83d8b
use warnings;
Packit a83d8b
Packit a83d8b
use 5.008;
Packit a83d8b
Packit a83d8b
our(@ISA, $VERSION);
Packit a83d8b
Packit a83d8b
# Do it so we won't import any symbols from IO::Socket which it does export
Packit a83d8b
# by default:
Packit a83d8b
#
Packit a83d8b
# <LeoNerd> IO::Socket is stupidstupidstupid beyond belief. Despite being an
Packit a83d8b
# object class, it has an import method
Packit a83d8b
# <LeoNerd> So you have to use IO::Socket ();
Packit a83d8b
# <LeoNerd> Having done that, this test is now clean
Packit a83d8b
use IO::Socket ();
Packit a83d8b
Packit a83d8b
use Socket (qw(
Packit a83d8b
    AF_INET6 PF_INET6 SOCK_RAW SOCK_STREAM INADDR_ANY SOCK_DGRAM
Packit a83d8b
    AF_INET SO_REUSEADDR SO_REUSEPORT AF_UNSPEC SO_BROADCAST
Packit a83d8b
    sockaddr_in
Packit a83d8b
    )
Packit a83d8b
);
Packit a83d8b
Packit a83d8b
# IO::Socket and Socket already import stuff here - possibly AF_INET6
Packit a83d8b
# and PF_INET6 so selectively import things from Socket6.
Packit a83d8b
use Socket6 (
Packit a83d8b
    qw(AI_PASSIVE getaddrinfo
Packit a83d8b
    sockaddr_in6 unpack_sockaddr_in6_all pack_sockaddr_in6_all in6addr_any)
Packit a83d8b
);
Packit a83d8b
Packit a83d8b
use Carp;
Packit a83d8b
use Errno;
Packit a83d8b
Packit a83d8b
@ISA = qw(IO::Socket);
Packit a83d8b
$VERSION = "2.72";
Packit a83d8b
#Purpose: allow protocol independent protocol and original interface.
Packit a83d8b
Packit a83d8b
my $EINVAL = exists(&Errno::EINVAL) ? Errno::EINVAL() : 1;
Packit a83d8b
Packit a83d8b
IO::Socket::INET6->register_domain( AF_INET6 );
Packit a83d8b
Packit a83d8b
Packit a83d8b
my %socket_type = ( tcp  => SOCK_STREAM,
Packit a83d8b
		    udp  => SOCK_DGRAM,
Packit a83d8b
		    icmp => SOCK_RAW
Packit a83d8b
		  );
Packit a83d8b
Packit a83d8b
sub new {
Packit a83d8b
    my $class = shift;
Packit a83d8b
    unshift(@_, "PeerAddr") if @_ == 1;
Packit a83d8b
    return $class->SUPER::new(@_);
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
# Parsing analysis:
Packit a83d8b
# addr,port,and proto may be syntactically related...
Packit a83d8b
sub _sock_info {
Packit a83d8b
  my($addr,$port,$proto) = @_;
Packit a83d8b
  my $origport = $port;
Packit a83d8b
  my @proto = ();
Packit a83d8b
  my @serv = ();
Packit a83d8b
Packit a83d8b
  if (defined $addr) {
Packit a83d8b
	if (!Socket6::inet_pton(AF_INET6,$addr)) {
Packit a83d8b
         if($addr =~ s,^\[([\da-fA-F:]+)\]:([\w\(\)/]+)$,$1,) {
Packit a83d8b
   	     $port = $2;
Packit a83d8b
         } elsif($addr =~ s,^\[(::[\da-fA-F.:]+)\]:([\w\(\)/]+)$,$1,) {
Packit a83d8b
             $port = $2;
Packit a83d8b
         } elsif($addr =~ s,^\[([\da-fA-F:]+)\],$1,) {
Packit a83d8b
             $port = $origport;
Packit a83d8b
         } elsif($addr =~ s,:([\w\(\)/]+)$,,) {
Packit a83d8b
             $port = $1
Packit a83d8b
         }
Packit a83d8b
	}
Packit a83d8b
  }
Packit a83d8b
Packit a83d8b
  # $proto as "string".
Packit a83d8b
  if(defined $proto  && $proto =~ /\D/) {
Packit a83d8b
    if(@proto = getprotobyname($proto)) {
Packit a83d8b
      $proto = $proto[2] || undef;
Packit a83d8b
    }
Packit a83d8b
    else {
Packit a83d8b
      $@ = "Bad protocol '$proto'";
Packit a83d8b
      return;
Packit a83d8b
    }
Packit a83d8b
  }
Packit a83d8b
Packit a83d8b
  if(defined $port) {
Packit a83d8b
    my $defport = ($port =~ s,\((\d+)\)$,,) ? $1 : undef;
Packit a83d8b
    my $pnum = ($port =~ m,^(\d+)$,)[0];
Packit a83d8b
Packit a83d8b
    @serv = getservbyname($port, $proto[0] || "")
Packit a83d8b
	if ($port =~ m,\D,);
Packit a83d8b
Packit a83d8b
    $port = $serv[2] || $defport || $pnum;
Packit a83d8b
    unless (defined $port) {
Packit a83d8b
	$@ = "Bad service '$origport'";
Packit a83d8b
	return;
Packit a83d8b
    }
Packit a83d8b
Packit a83d8b
    $proto = (getprotobyname($serv[3]))[2] || undef
Packit a83d8b
	if @serv && !$proto;
Packit a83d8b
  }
Packit a83d8b
 #printf "Selected port  is $port and proto is $proto \n";
Packit a83d8b
Packit a83d8b
 return ($addr || undef,
Packit a83d8b
	 $port || undef,
Packit a83d8b
	 $proto || undef,
Packit a83d8b
	);
Packit a83d8b
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub _error {
Packit a83d8b
    my $sock = shift;
Packit a83d8b
    my $err = shift;
Packit a83d8b
    {
Packit a83d8b
      local($!);
Packit a83d8b
      my $title = ref($sock).": ";
Packit a83d8b
      $@ = join("", $_[0] =~ /^$title/ ? "" : $title, @_);
Packit a83d8b
      close($sock)
Packit a83d8b
	if(defined fileno($sock));
Packit a83d8b
    }
Packit a83d8b
    $! = $err;
Packit a83d8b
    return undef;
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub configure {
Packit a83d8b
    my($sock,$arg) = @_;
Packit a83d8b
Packit a83d8b
    $arg->{LocalAddr} = $arg->{LocalHost}
Packit a83d8b
        if exists $arg->{LocalHost} && !exists $arg->{LocalAddr};
Packit a83d8b
    $arg->{PeerAddr} = $arg->{PeerHost}
Packit a83d8b
        if exists $arg->{PeerHost} && !exists $arg->{PeerAddr};
Packit a83d8b
Packit a83d8b
    my $family = $arg->{Domain};
Packit a83d8b
    # in case no local and peer is given we prefer AF_INET6
Packit a83d8b
    # because we are IO::Socket::INET6
Packit a83d8b
    $family ||= ! $arg->{LocalAddr} && ! $arg->{PeerAddr} && AF_INET6
Packit a83d8b
        || AF_UNSPEC;
Packit a83d8b
Packit a83d8b
    # parse Local*
Packit a83d8b
    my ($laddr,$lport,$proto) = _sock_info(
Packit a83d8b
        $arg->{LocalAddr},
Packit a83d8b
        $arg->{LocalPort},
Packit a83d8b
        $arg->{Proto}
Packit a83d8b
    ) or return _error($sock, $!, "sock_info: $@");
Packit a83d8b
    $laddr ||= '';
Packit a83d8b
    $lport ||= 0;
Packit a83d8b
    $proto ||= (getprotobyname('tcp'))[2];
Packit a83d8b
Packit a83d8b
Packit a83d8b
    # MSWin32 expects at least one of $laddr or $lport to be specified
Packit a83d8b
    # and does not accept 0 for $lport if $laddr is specified.
Packit a83d8b
    if ($^O eq 'MSWin32') {
Packit a83d8b
        if ((!$laddr) && (!$lport)) {
Packit a83d8b
            $laddr = ($family == AF_INET) ? '0.0.0.0' : '::';
Packit a83d8b
            $lport = '';
Packit a83d8b
        } elsif (!$lport) {
Packit a83d8b
            $lport = '';
Packit a83d8b
        }
Packit a83d8b
    }
Packit a83d8b
Packit a83d8b
    my $type = $arg->{Type} || $socket_type{(getprotobynumber($proto))[0]};
Packit a83d8b
Packit a83d8b
    # parse Peer*
Packit a83d8b
    my($rport,$raddr);
Packit a83d8b
    unless(exists $arg->{Listen}) {
Packit a83d8b
        ($raddr,$rport) = _sock_info(
Packit a83d8b
            $arg->{PeerAddr},
Packit a83d8b
            $arg->{PeerPort},
Packit a83d8b
            $proto
Packit a83d8b
        ) or return _error($sock, $!, "sock_info: $@");
Packit a83d8b
    }
Packit a83d8b
Packit a83d8b
    # find out all combinations of local and remote addr with
Packit a83d8b
    # the same family
Packit a83d8b
    my @lres = getaddrinfo($laddr,$lport,$family,$type,$proto,AI_PASSIVE);
Packit a83d8b
    return _error($sock, $EINVAL, "getaddrinfo: $lres[0]") if @lres<5;
Packit a83d8b
    my @rres;
Packit a83d8b
    if ( defined $raddr ) {
Packit a83d8b
        @rres = getaddrinfo($raddr,$rport,$family,$type,$proto);
Packit a83d8b
        return _error($sock, $EINVAL, "getaddrinfo: $rres[0]") if @rres<5;
Packit a83d8b
    }
Packit a83d8b
Packit a83d8b
    my @flr;
Packit a83d8b
    if (@rres) {
Packit a83d8b
        # Collect all combinations with the same family in lres and rres
Packit a83d8b
        # the order we search should be defined by the order of @rres,
Packit a83d8b
        # not @lres!
Packit a83d8b
        for( my $r=0;$r<@rres;$r+=5 ) {
Packit a83d8b
            for( my $l=0;$l<@lres;$l+=5) {
Packit a83d8b
                my $fam_listen = $lres[$l];
Packit a83d8b
                next if $rres[$r] != $fam_listen; # must be same family
Packit a83d8b
                push @flr,[ $fam_listen,$lres[$l+3],$rres[$r+3] ];
Packit a83d8b
            }
Packit a83d8b
        }
Packit a83d8b
    } else {
Packit a83d8b
        for( my $l=0;$l<@lres;$l+=5) {
Packit a83d8b
            my $fam_listen = $lres[$l];
Packit a83d8b
            my $lsockaddr = $lres[$l+3];
Packit a83d8b
            # collect only the binding side
Packit a83d8b
            push @flr,[ $fam_listen,$lsockaddr ];
Packit a83d8b
        }
Packit a83d8b
    }
Packit a83d8b
Packit a83d8b
    # try to bind and maybe connect
Packit a83d8b
    # if multihomed try all combinations until success
Packit a83d8b
    for my $flr (@flr) {
Packit a83d8b
        my ($family,$lres,$rres) = @$flr;
Packit a83d8b
Packit a83d8b
        if ( $family == AF_INET6) {
Packit a83d8b
            if ($arg->{LocalFlow} || $arg->{LocalScope}) {
Packit a83d8b
                my @sa_in6 = unpack_sockaddr_in6_all($lres);
Packit a83d8b
                $sa_in6[1] = $arg->{LocalFlow}  || 0;
Packit a83d8b
                $sa_in6[3] = _scope_ntohl($arg->{LocalScope}) || 0;
Packit a83d8b
                $lres = pack_sockaddr_in6_all(@sa_in6);
Packit a83d8b
            }
Packit a83d8b
        }
Packit a83d8b
Packit a83d8b
        $sock->socket($family, $type, $proto) or
Packit a83d8b
            return _error($sock, $!, "socket: $!");
Packit a83d8b
Packit a83d8b
        if (defined $arg->{Blocking}) {
Packit a83d8b
            defined $sock->blocking($arg->{Blocking}) or
Packit a83d8b
                return _error($sock, $!, "sockopt: $!");
Packit a83d8b
        }
Packit a83d8b
Packit a83d8b
        if ($arg->{Reuse} || $arg->{ReuseAddr}) {
Packit a83d8b
            $sock->sockopt(SO_REUSEADDR,1) or
Packit a83d8b
                return _error($sock, $!, "sockopt: $!");
Packit a83d8b
        }
Packit a83d8b
Packit a83d8b
        if ($arg->{ReusePort}) {
Packit a83d8b
            $sock->sockopt(SO_REUSEPORT,1) or
Packit a83d8b
                return _error($sock, $!, "sockopt: $!");
Packit a83d8b
        }
Packit a83d8b
Packit a83d8b
        if ($arg->{Broadcast}) {
Packit a83d8b
            $sock->sockopt(SO_BROADCAST,1) or
Packit a83d8b
                return _error($sock, $!, "sockopt: $!");
Packit a83d8b
        }
Packit a83d8b
Packit a83d8b
        if ( $family == AF_INET ) {
Packit a83d8b
            my ($p,$a) = sockaddr_in($lres);
Packit a83d8b
            $sock->bind($lres) or return _error($sock, $!, "bind: $!")
Packit a83d8b
                if ($a ne INADDR_ANY  or $p!=0);
Packit a83d8b
        } else {
Packit a83d8b
            my ($p,$a) = sockaddr_in6($lres);
Packit a83d8b
            $sock->bind($lres) or return _error($sock, $!, "bind: $!")
Packit a83d8b
                if ($a ne in6addr_any  or $p!=0);
Packit a83d8b
        }
Packit a83d8b
Packit a83d8b
        if(exists $arg->{Listen}) {
Packit a83d8b
            $sock->listen($arg->{Listen} || 5) or
Packit a83d8b
                return _error($sock, $!, "listen: $!");
Packit a83d8b
        }
Packit a83d8b
Packit a83d8b
        # connect only if PeerAddr and thus $rres is given
Packit a83d8b
        last if ! $rres;
Packit a83d8b
Packit a83d8b
        if ( $family == AF_INET6) {
Packit a83d8b
            if ($arg->{PeerFlow} || $arg->{PeerScope}) {
Packit a83d8b
                my @sa_in6 = unpack_sockaddr_in6_all($rres);
Packit a83d8b
                $sa_in6[1] = $arg->{PeerFlow}  || 0;
Packit a83d8b
                $sa_in6[3] = _scope_ntohl($arg->{PeerScope}) || 0;
Packit a83d8b
                $rres = pack_sockaddr_in6_all(@sa_in6);
Packit a83d8b
            }
Packit a83d8b
        }
Packit a83d8b
Packit a83d8b
        undef $@;
Packit a83d8b
        last if $sock->connect($rres);
Packit a83d8b
Packit a83d8b
        return _error($sock, $!, $@ || "Timeout")
Packit a83d8b
            if ! $arg->{MultiHomed};
Packit a83d8b
Packit a83d8b
    }
Packit a83d8b
Packit a83d8b
    return $sock;
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub _scope_ntohl($)
Packit a83d8b
{
Packit a83d8b
    # As of Socket6 0.17 the scope field is incorrectly put into
Packit a83d8b
    # network byte order when it should be in host byte order
Packit a83d8b
    # in the sockaddr_in6 structure.  We correct for that here.
Packit a83d8b
Packit a83d8b
    if ((Socket6->VERSION <= 0.17) && (pack('s', 0x1234) ne pack('n', 0x1234)))
Packit a83d8b
    {
Packit a83d8b
        unpack('N', pack('V', $_[0]));
Packit a83d8b
    } else {
Packit a83d8b
        $_[0];
Packit a83d8b
    }
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub sockdomain
Packit a83d8b
{
Packit a83d8b
   my $sock = shift;
Packit a83d8b
   $sock->SUPER::sockdomain(@_) || AF_INET6;
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub accept
Packit a83d8b
{
Packit a83d8b
    my $sock = shift;
Packit a83d8b
Packit a83d8b
    my ($new, $peer) = $sock->SUPER::accept(@_);
Packit a83d8b
Packit a83d8b
    return unless defined($new);
Packit a83d8b
Packit a83d8b
    ${*$new}{io_socket_domain} = ${*$sock}{io_socket_domain};
Packit a83d8b
    ${*$new}{io_socket_type}   = ${*$sock}{io_socket_type};
Packit a83d8b
    ${*$new}{io_socket_proto}  = ${*$sock}{io_socket_proto};
Packit a83d8b
Packit a83d8b
    return wantarray ? ($new, $peer) : $new;
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub bind {
Packit a83d8b
    @_ == 2 or
Packit a83d8b
       croak 'usage: $sock->bind(NAME) ';
Packit a83d8b
    my $sock = shift;
Packit a83d8b
    return $sock->SUPER::bind( shift );
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub connect {
Packit a83d8b
    @_ == 2 or
Packit a83d8b
       croak 'usage: $sock->connect(NAME) ';
Packit a83d8b
    my $sock = shift;
Packit a83d8b
    return $sock->SUPER::connect( shift );
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub sockaddr {
Packit a83d8b
    @_ == 1 or croak 'usage: $sock->sockaddr()';
Packit a83d8b
    my ($sock) = @_;
Packit a83d8b
    return undef unless (my $name = $sock->sockname);
Packit a83d8b
    ($sock->sockdomain == AF_INET) ? (sockaddr_in($name))[1] : (sockaddr_in6($name))[1];
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub sockport {
Packit a83d8b
    @_ == 1 or croak 'usage: $sock->sockport()';
Packit a83d8b
    my($sock) = @_;
Packit a83d8b
    return undef unless (my $name = $sock->sockname);
Packit a83d8b
    ($sock->sockdomain == AF_INET) ? (sockaddr_in($name))[0] : (sockaddr_in6($name))[0];
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub sockhost {
Packit a83d8b
    @_ == 1 or croak 'usage: $sock->sockhost()';
Packit a83d8b
    my ($sock) = @_;
Packit a83d8b
    return undef unless (my $addr = $sock->sockaddr);
Packit a83d8b
    Socket6::inet_ntop($sock->sockdomain, $addr);
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub sockflow
Packit a83d8b
{
Packit a83d8b
    @_ == 1 or croak 'usage: $sock->sockflow()';
Packit a83d8b
    my ($sock) = @_;
Packit a83d8b
    return undef unless (my $name = $sock->sockname);
Packit a83d8b
    ($sock->sockdomain == AF_INET6) ? (unpack_sockaddr_in6_all($name))[1] : 0;
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub sockscope
Packit a83d8b
{
Packit a83d8b
    @_ == 1 or croak 'usage: $sock->sockscope()';
Packit a83d8b
    my ($sock) = @_;
Packit a83d8b
    return undef unless (my $name = $sock->sockname);
Packit a83d8b
    _scope_ntohl(($sock->sockdomain == AF_INET6) ? (unpack_sockaddr_in6_all($name))[3] : 0);
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub peeraddr {
Packit a83d8b
    @_ == 1 or croak 'usage: $sock->peeraddr()';
Packit a83d8b
    my ($sock) = @_;
Packit a83d8b
    return undef unless (my $name = $sock->peername);
Packit a83d8b
    ($sock->sockdomain == AF_INET) ? (sockaddr_in($name))[1] : (sockaddr_in6($name))[1];
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub peerport {
Packit a83d8b
    @_ == 1 or croak 'usage: $sock->peerport()';
Packit a83d8b
    my($sock) = @_;
Packit a83d8b
    return undef unless (my $name = $sock->peername);
Packit a83d8b
    ($sock->sockdomain == AF_INET) ? (sockaddr_in($name))[0] : (sockaddr_in6($name))[0];
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub peerhost {
Packit a83d8b
    @_ == 1 or croak 'usage: $sock->peerhost()';
Packit a83d8b
    my ($sock) = @_;
Packit a83d8b
    return undef unless (my $addr = $sock->peeraddr);
Packit a83d8b
    Socket6::inet_ntop($sock->sockdomain, $addr);
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub peerflow
Packit a83d8b
{
Packit a83d8b
    @_ == 1 or croak 'usage: $sock->peerflow()';
Packit a83d8b
    my ($sock) = @_;
Packit a83d8b
    return undef unless (my $name = $sock->peername);
Packit a83d8b
    _scope_ntohl(($sock->sockdomain == AF_INET6) ? (unpack_sockaddr_in6_all($name))[1] : 0);
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
sub peerscope
Packit a83d8b
{
Packit a83d8b
    @_ == 1 or croak 'usage: $sock->peerscope()';
Packit a83d8b
    my ($sock) = @_;
Packit a83d8b
    return undef unless (my $name = $sock->peername);
Packit a83d8b
    ($sock->sockdomain == AF_INET6) ? (unpack_sockaddr_in6_all($name))[3] : 0;
Packit a83d8b
}
Packit a83d8b
Packit a83d8b
1;
Packit a83d8b
Packit a83d8b
__END__
Packit a83d8b
Packit a83d8b
=head1 NAME
Packit a83d8b
Packit a83d8b
IO::Socket::INET6 - Object interface for AF_INET/AF_INET6 domain sockets
Packit a83d8b
Packit a83d8b
=head1 SYNOPSIS
Packit a83d8b
Packit a83d8b
    use IO::Socket::INET6;
Packit a83d8b
Packit a83d8b
=head1 DESCRIPTION
Packit a83d8b
Packit a83d8b
C<IO::Socket::INET6> provides an object interface to creating and using sockets
Packit a83d8b
in either AF_INET or AF_INET6 domains. It is built upon the L<IO::Socket> interface and
Packit a83d8b
inherits all the methods defined by L<IO::Socket>.
Packit a83d8b
Packit a83d8b
=head1 CONSTRUCTOR
Packit a83d8b
Packit a83d8b
=over 4
Packit a83d8b
Packit a83d8b
=item new ( [ARGS] )
Packit a83d8b
Packit a83d8b
Creates an C<IO::Socket::INET6> object, which is a reference to a
Packit a83d8b
newly created symbol (see the C<Symbol> package). C<new>
Packit a83d8b
optionally takes arguments, these arguments are in key-value pairs.
Packit a83d8b
Packit a83d8b
In addition to the key-value pairs accepted by L<IO::Socket>,
Packit a83d8b
C<IO::Socket::INET6> provides.
Packit a83d8b
Packit a83d8b
Packit a83d8b
    Domain	Address family               AF_INET | AF_INET6 | AF_UNSPEC (default)
Packit a83d8b
    PeerAddr	Remote host address          <hostname>[:<port>]
Packit a83d8b
    PeerHost	Synonym for PeerAddr
Packit a83d8b
    PeerPort	Remote port or service       <service>[(<no>)] | <no>
Packit a83d8b
    PeerFlow    Remote flow information
Packit a83d8b
    PeerScope   Remote address scope
Packit a83d8b
    LocalAddr	Local host bind	address      hostname[:port]
Packit a83d8b
    LocalHost	Synonym for LocalAddr
Packit a83d8b
    LocalPort	Local host bind	port         <service>[(<no>)] | <no>
Packit a83d8b
    LocalFlow   Local host flow information
Packit a83d8b
    LocalScope  Local host address scope
Packit a83d8b
    Proto	Protocol name (or number)    "tcp" | "udp" | ...
Packit a83d8b
    Type	Socket type                  SOCK_STREAM | SOCK_DGRAM | ...
Packit a83d8b
    Listen	Queue size for listen
Packit a83d8b
    ReuseAddr	Set SO_REUSEADDR before binding
Packit a83d8b
    Reuse	Set SO_REUSEADDR before binding (deprecated, prefer ReuseAddr)
Packit a83d8b
    ReusePort	Set SO_REUSEPORT before binding
Packit a83d8b
    Broadcast	Set SO_BROADCAST before binding
Packit a83d8b
    Timeout	Timeout	value for various operations
Packit a83d8b
    MultiHomed  Try all addresses for multi-homed hosts
Packit a83d8b
    Blocking    Determine if connection will be blocking mode
Packit a83d8b
Packit a83d8b
If C<Listen> is defined then a listen socket is created, else if the
Packit a83d8b
socket type, which is derived from the protocol, is SOCK_STREAM then
Packit a83d8b
connect() is called.
Packit a83d8b
Packit a83d8b
Although it is not illegal, the use of C<MultiHomed> on a socket
Packit a83d8b
which is in non-blocking mode is of little use. This is because the
Packit a83d8b
first connect will never fail with a timeout as the connect call
Packit a83d8b
will not block.
Packit a83d8b
Packit a83d8b
The C<PeerAddr> can be a hostname,  the IPv6-address on the
Packit a83d8b
"2001:800:40:2a05::10" form , or the IPv4-address on the "213.34.234.245" form.
Packit a83d8b
The C<PeerPort> can be a number or a symbolic
Packit a83d8b
service name.  The service name might be followed by a number in
Packit a83d8b
parenthesis which is used if the service is not known by the system.
Packit a83d8b
The C<PeerPort> specification can also be embedded in the C<PeerAddr>
Packit a83d8b
by preceding it with a ":", and closing the IPv6 address on brackets "[]" if
Packit a83d8b
necessary: "124.678.12.34:23","[2a05:345f::10]:23","any.server.com:23".
Packit a83d8b
Packit a83d8b
If C<Domain> is not given, AF_UNSPEC is assumed, that is, both AF_INET and AF_INET6 will
Packit a83d8b
be both considered when resolving DNS names. AF_INET6 has priority.
Packit a83d8b
If you guess you are in trouble not reaching the peer,(the service is not available via
Packit a83d8b
AF_INET6 but AF_INET) you can either try Multihomed (try any address/family until reach)
Packit a83d8b
or concrete your address C<family> (AF_INET, AF_INET6).
Packit a83d8b
Packit a83d8b
If C<Proto> is not given and you specify a symbolic C<PeerPort> port,
Packit a83d8b
then the constructor will try to derive C<Proto> from the service
Packit a83d8b
name.  As a last resort C<Proto> "tcp" is assumed.  The C<Type>
Packit a83d8b
parameter will be deduced from C<Proto> if not specified.
Packit a83d8b
Packit a83d8b
If the constructor is only passed a single argument, it is assumed to
Packit a83d8b
be a C<PeerAddr> specification.
Packit a83d8b
Packit a83d8b
If C<Blocking> is set to 0, the connection will be in nonblocking mode.
Packit a83d8b
If not specified it defaults to 1 (blocking mode).
Packit a83d8b
Packit a83d8b
Examples:
Packit a83d8b
Packit a83d8b
   $sock = IO::Socket::INET6->new(PeerAddr => 'www.perl.org',
Packit a83d8b
                                 PeerPort => 'http(80)',
Packit a83d8b
                                 Proto    => 'tcp');
Packit a83d8b
Packit a83d8b
Suppose either you have no IPv6 connectivity or www.perl.org has no http service on IPv6. Then,
Packit a83d8b
Packit a83d8b
(Trying all address/families until reach)
Packit a83d8b
Packit a83d8b
   $sock = IO::Socket::INET6->new(PeerAddr => 'www.perl.org',
Packit a83d8b
                                 PeerPort => 'http(80)',
Packit a83d8b
				 Multihomed => 1 ,
Packit a83d8b
                                 Proto    => 'tcp');
Packit a83d8b
Packit a83d8b
(Concrete to IPv4 protocol)
Packit a83d8b
Packit a83d8b
   $sock = IO::Socket::INET6->new(PeerAddr => 'www.perl.org',
Packit a83d8b
                                 PeerPort => 'http(80)',
Packit a83d8b
				 Domain => AF_INET ,
Packit a83d8b
                                 Proto    => 'tcp');
Packit a83d8b
Packit a83d8b
Packit a83d8b
   $sock = IO::Socket::INET6->new(PeerAddr => 'localhost:smtp(25)');
Packit a83d8b
Packit a83d8b
   $sock = IO::Socket::INET6->new(Listen    => 5,
Packit a83d8b
                                 LocalAddr => 'localhost',
Packit a83d8b
                                 LocalPort => 9000,
Packit a83d8b
                                 Proto     => 'tcp');
Packit a83d8b
Packit a83d8b
   $sock = IO::Socket::INET6->new('[::1]:25');
Packit a83d8b
Packit a83d8b
   $sock = IO::Socket::INET6->new(PeerPort  => 9999,
Packit a83d8b
                                 PeerAddr  => Socket6::inet_ntop(AF_INET6,in6addr_broadcast),
Packit a83d8b
                                 Proto     => udp,
Packit a83d8b
                                 LocalAddr => 'localhost',
Packit a83d8b
                                 Broadcast => 1 )
Packit a83d8b
                             or die "Can't bind : $@\n";
Packit a83d8b
Packit a83d8b
 NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
Packit a83d8b
Packit a83d8b
As of VERSION 1.18 all IO::Socket objects have autoflush turned on
Packit a83d8b
by default. This was not the case with earlier releases.
Packit a83d8b
Packit a83d8b
 NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
Packit a83d8b
Packit a83d8b
=back
Packit a83d8b
Packit a83d8b
=head2 METHODS
Packit a83d8b
Packit a83d8b
=over 4
Packit a83d8b
Packit a83d8b
=item accept ()
Packit a83d8b
Packit a83d8b
See L<IO::Socket::INET>.
Packit a83d8b
Packit a83d8b
=item bind ()
Packit a83d8b
Packit a83d8b
See L<IO::Socket::INET>.
Packit a83d8b
Packit a83d8b
=item configure ()
Packit a83d8b
Packit a83d8b
This function exists in this module, but I (= Shlomi Fish) don't know what it
Packit a83d8b
does, or understand it. It's also not tested anywhere. I'll be happy to be
Packit a83d8b
enlightened.
Packit a83d8b
Packit a83d8b
=item connect ()
Packit a83d8b
Packit a83d8b
See L<IO::Socket::INET>.
Packit a83d8b
Packit a83d8b
=item sockaddr ()
Packit a83d8b
Packit a83d8b
Return the address part of the sockaddr structure for the socket
Packit a83d8b
Packit a83d8b
=item sockdomain()
Packit a83d8b
Packit a83d8b
Returns the domain of the socket - AF_INET or AF_INET6 or whatever.
Packit a83d8b
Packit a83d8b
=item sockport ()
Packit a83d8b
Packit a83d8b
Return the port number that the socket is using on the local host
Packit a83d8b
Packit a83d8b
=item sockhost ()
Packit a83d8b
Packit a83d8b
Return the address part of the sockaddr structure for the socket in a
Packit a83d8b
text form ("2001:800:40:2a05::10" or "245.245.13.27")
Packit a83d8b
Packit a83d8b
=item sockflow ()
Packit a83d8b
Packit a83d8b
Return the flow information part of the sockaddr structure for the socket
Packit a83d8b
Packit a83d8b
=item sockscope ()
Packit a83d8b
Packit a83d8b
Return the scope identification part of the sockaddr structure for the socket
Packit a83d8b
Packit a83d8b
=item peeraddr ()
Packit a83d8b
Packit a83d8b
Return the address part of the sockaddr structure for the socket on
Packit a83d8b
the peer host
Packit a83d8b
Packit a83d8b
=item peerport ()
Packit a83d8b
Packit a83d8b
Return the port number for the socket on the peer host.
Packit a83d8b
Packit a83d8b
=item peerhost ()
Packit a83d8b
Packit a83d8b
Return the address part of the sockaddr structure for the socket on the
Packit a83d8b
peer host in a text form ("2001:800:40:2a05::10" or "245.245.13.27")
Packit a83d8b
Packit a83d8b
=item peerflow ()
Packit a83d8b
Packit a83d8b
Return the flow information part of the sockaddr structure for the socket
Packit a83d8b
on the peer host
Packit a83d8b
Packit a83d8b
=item peerscope ()
Packit a83d8b
Packit a83d8b
Return the scope identification part of the sockaddr structure for the socket
Packit a83d8b
on the peer host
Packit a83d8b
Packit a83d8b
=back
Packit a83d8b
Packit a83d8b
=head1 REPOSITORY
Packit a83d8b
Packit a83d8b
The Subversion repository for this module carrying complete version history
Packit a83d8b
and other information is:
Packit a83d8b
Packit a83d8b
L<http://svn.berlios.de/svnroot/repos/web-cpan/IO-Socket-INET6/>
Packit a83d8b
Packit a83d8b
=head1 SEE ALSO
Packit a83d8b
Packit a83d8b
L<Socket>,L<Socket6>, L<IO::Socket>
Packit a83d8b
Packit a83d8b
=head1 AUTHOR
Packit a83d8b
Packit a83d8b
This program is based on L<IO::Socket::INET> by Graham Barr
Packit a83d8b
<gbarr@pobox.com> and currently maintained by the Perl Porters.
Packit a83d8b
Packit a83d8b
Modified by Rafael Martinez Torres <rafael.martinez@novagnet.com> and
Packit a83d8b
Euro6IX project.
Packit a83d8b
Packit a83d8b
Modified further by Shlomi Fish <shlomif@iglu.org.il>, while disclaiming
Packit a83d8b
all copyrights.
Packit a83d8b
Packit a83d8b
=head1 COPYRIGHT
Packit a83d8b
Packit a83d8b
Copyright (c) 2003- Rafael Martinez Torres <rafael.martinez@novagnet.com>.
Packit a83d8b
Packit a83d8b
Copyright (c) 2003- Euro6IX project.
Packit a83d8b
Packit a83d8b
Copyright (c) 1996-8 Graham Barr <gbarr@pobox.com>.
Packit a83d8b
Packit a83d8b
All rights reserved.
Packit a83d8b
Packit a83d8b
This program is free software; you can redistribute it and/or
Packit a83d8b
modify it under the same terms as Perl itself.
Packit a83d8b
Packit a83d8b
=cut