16fb12b70Safresh1#  You may distribute under the terms of either the GNU General Public License
26fb12b70Safresh1#  or the Artistic License (the same terms as Perl itself)
36fb12b70Safresh1#
4*3d61058aSafresh1#  (C) Paul Evans, 2010-2023 -- leonerd@leonerd.org.uk
56fb12b70Safresh1
6*3d61058aSafresh1package IO::Socket::IP 0.42;
7eac174f2Safresh1
8*3d61058aSafresh1use v5.14;
9eac174f2Safresh1use warnings;
10eac174f2Safresh1
116fb12b70Safresh1use base qw( IO::Socket );
126fb12b70Safresh1
136fb12b70Safresh1use Carp;
146fb12b70Safresh1
156fb12b70Safresh1use Socket 1.97 qw(
166fb12b70Safresh1   getaddrinfo getnameinfo
176fb12b70Safresh1   sockaddr_family
186fb12b70Safresh1   AF_INET
196fb12b70Safresh1   AI_PASSIVE
206fb12b70Safresh1   IPPROTO_TCP IPPROTO_UDP
216fb12b70Safresh1   IPPROTO_IPV6 IPV6_V6ONLY
226fb12b70Safresh1   NI_DGRAM NI_NUMERICHOST NI_NUMERICSERV NIx_NOHOST NIx_NOSERV
236fb12b70Safresh1   SO_REUSEADDR SO_REUSEPORT SO_BROADCAST SO_ERROR
246fb12b70Safresh1   SOCK_DGRAM SOCK_STREAM
256fb12b70Safresh1   SOL_SOCKET
266fb12b70Safresh1);
276fb12b70Safresh1my $AF_INET6 = eval { Socket::AF_INET6() }; # may not be defined
286fb12b70Safresh1my $AI_ADDRCONFIG = eval { Socket::AI_ADDRCONFIG() } || 0;
296fb12b70Safresh1use POSIX qw( dup2 );
302e109fb9Safresh1use Errno qw( EINVAL EINPROGRESS EISCONN ENOTCONN ETIMEDOUT EWOULDBLOCK EOPNOTSUPP );
316fb12b70Safresh1
326fb12b70Safresh1use constant HAVE_MSWIN32 => ( $^O eq "MSWin32" );
336fb12b70Safresh1
346fb12b70Safresh1# At least one OS (Android) is known not to have getprotobyname()
356fb12b70Safresh1use constant HAVE_GETPROTOBYNAME => defined eval { getprotobyname( "tcp" ) };
366fb12b70Safresh1
376fb12b70Safresh1my $IPv6_re = do {
386fb12b70Safresh1   # translation of RFC 3986 3.2.2 ABNF to re
396fb12b70Safresh1   my $IPv4address = do {
406fb12b70Safresh1      my $dec_octet = q<(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])>;
416fb12b70Safresh1      qq<$dec_octet(?: \\. $dec_octet){3}>;
426fb12b70Safresh1   };
436fb12b70Safresh1   my $IPv6address = do {
446fb12b70Safresh1      my $h16  = qq<[0-9A-Fa-f]{1,4}>;
456fb12b70Safresh1      my $ls32 = qq<(?: $h16 : $h16 | $IPv4address)>;
466fb12b70Safresh1      qq<(?:
476fb12b70Safresh1                                            (?: $h16 : ){6} $ls32
486fb12b70Safresh1         |                               :: (?: $h16 : ){5} $ls32
496fb12b70Safresh1         | (?:                   $h16 )? :: (?: $h16 : ){4} $ls32
506fb12b70Safresh1         | (?: (?: $h16 : ){0,1} $h16 )? :: (?: $h16 : ){3} $ls32
516fb12b70Safresh1         | (?: (?: $h16 : ){0,2} $h16 )? :: (?: $h16 : ){2} $ls32
526fb12b70Safresh1         | (?: (?: $h16 : ){0,3} $h16 )? ::     $h16 :      $ls32
536fb12b70Safresh1         | (?: (?: $h16 : ){0,4} $h16 )? ::                 $ls32
546fb12b70Safresh1         | (?: (?: $h16 : ){0,5} $h16 )? ::                 $h16
556fb12b70Safresh1         | (?: (?: $h16 : ){0,6} $h16 )? ::
566fb12b70Safresh1      )>
576fb12b70Safresh1   };
586fb12b70Safresh1   qr<$IPv6address>xo;
596fb12b70Safresh1};
606fb12b70Safresh1
616fb12b70Safresh1=head1 NAME
626fb12b70Safresh1
636fb12b70Safresh1C<IO::Socket::IP> - Family-neutral IP socket supporting both IPv4 and IPv6
646fb12b70Safresh1
656fb12b70Safresh1=head1 SYNOPSIS
666fb12b70Safresh1
676fb12b70Safresh1   use IO::Socket::IP;
686fb12b70Safresh1
696fb12b70Safresh1   my $sock = IO::Socket::IP->new(
706fb12b70Safresh1      PeerHost => "www.google.com",
716fb12b70Safresh1      PeerPort => "http",
726fb12b70Safresh1      Type     => SOCK_STREAM,
73*3d61058aSafresh1   ) or die "Cannot construct socket - $IO::Socket::errstr";
746fb12b70Safresh1
756fb12b70Safresh1   my $familyname = ( $sock->sockdomain == PF_INET6 ) ? "IPv6" :
766fb12b70Safresh1                    ( $sock->sockdomain == PF_INET  ) ? "IPv4" :
776fb12b70Safresh1                                                        "unknown";
786fb12b70Safresh1
796fb12b70Safresh1   printf "Connected to google via %s\n", $familyname;
806fb12b70Safresh1
816fb12b70Safresh1=head1 DESCRIPTION
826fb12b70Safresh1
836fb12b70Safresh1This module provides a protocol-independent way to use IPv4 and IPv6 sockets,
846fb12b70Safresh1intended as a replacement for L<IO::Socket::INET>. Most constructor arguments
856fb12b70Safresh1and methods are provided in a backward-compatible way. For a list of known
866fb12b70Safresh1differences, see the C<IO::Socket::INET> INCOMPATIBILITES section below.
876fb12b70Safresh1
886fb12b70Safresh1It uses the C<getaddrinfo(3)> function to convert hostnames and service names
896fb12b70Safresh1or port numbers into sets of possible addresses to connect to or listen on.
906fb12b70Safresh1This allows it to work for IPv6 where the system supports it, while still
916fb12b70Safresh1falling back to IPv4-only on systems which don't.
926fb12b70Safresh1
936fb12b70Safresh1=head1 REPLACING C<IO::Socket> DEFAULT BEHAVIOUR
946fb12b70Safresh1
95eac174f2Safresh1By placing C<-register> in the import list to C<IO::Socket::IP>, it will
96eac174f2Safresh1register itself with L<IO::Socket> as the class that handles C<PF_INET>. It
97eac174f2Safresh1will also ask to handle C<PF_INET6> as well, provided that constant is
98eac174f2Safresh1available.
996fb12b70Safresh1
1006fb12b70Safresh1Changing C<IO::Socket>'s default behaviour means that calling the
1016fb12b70Safresh1C<IO::Socket> constructor with either C<PF_INET> or C<PF_INET6> as the
1026fb12b70Safresh1C<Domain> parameter will yield an C<IO::Socket::IP> object.
1036fb12b70Safresh1
1046fb12b70Safresh1   use IO::Socket::IP -register;
1056fb12b70Safresh1
1066fb12b70Safresh1   my $sock = IO::Socket->new(
1076fb12b70Safresh1      Domain    => PF_INET6,
1086fb12b70Safresh1      LocalHost => "::1",
1096fb12b70Safresh1      Listen    => 1,
110*3d61058aSafresh1   ) or die "Cannot create socket - $IO::Socket::errstr\n";
1116fb12b70Safresh1
1126fb12b70Safresh1   print "Created a socket of type " . ref($sock) . "\n";
1136fb12b70Safresh1
1146fb12b70Safresh1Note that C<-register> is a global setting that applies to the entire program;
1156fb12b70Safresh1it cannot be applied only for certain callers, removed, or limited by lexical
1166fb12b70Safresh1scope.
1176fb12b70Safresh1
1186fb12b70Safresh1=cut
1196fb12b70Safresh1
1206fb12b70Safresh1sub import
1216fb12b70Safresh1{
1226fb12b70Safresh1   my $pkg = shift;
1236fb12b70Safresh1   my @symbols;
1246fb12b70Safresh1
1256fb12b70Safresh1   foreach ( @_ ) {
1266fb12b70Safresh1      if( $_ eq "-register" ) {
1276fb12b70Safresh1         IO::Socket::IP::_ForINET->register_domain( AF_INET );
1286fb12b70Safresh1         IO::Socket::IP::_ForINET6->register_domain( $AF_INET6 ) if defined $AF_INET6;
1296fb12b70Safresh1      }
1306fb12b70Safresh1      else {
1316fb12b70Safresh1         push @symbols, $_;
1326fb12b70Safresh1      }
1336fb12b70Safresh1   }
1346fb12b70Safresh1
1356fb12b70Safresh1   @_ = ( $pkg, @symbols );
1366fb12b70Safresh1   goto &IO::Socket::import;
1376fb12b70Safresh1}
1386fb12b70Safresh1
1396fb12b70Safresh1# Convenient capability test function
1406fb12b70Safresh1{
1416fb12b70Safresh1   my $can_disable_v6only;
1426fb12b70Safresh1   sub CAN_DISABLE_V6ONLY
1436fb12b70Safresh1   {
1446fb12b70Safresh1      return $can_disable_v6only if defined $can_disable_v6only;
1456fb12b70Safresh1
1466fb12b70Safresh1      socket my $testsock, Socket::PF_INET6(), SOCK_STREAM, 0 or
1476fb12b70Safresh1         die "Cannot socket(PF_INET6) - $!";
1486fb12b70Safresh1
1496fb12b70Safresh1      if( setsockopt $testsock, IPPROTO_IPV6, IPV6_V6ONLY, 0 ) {
150e0680481Safresh1         if( $^O eq "dragonfly") {
151e0680481Safresh1            # dragonflybsd 6.4 lies about successfully turning this off
152e0680481Safresh1            if( getsockopt $testsock, IPPROTO_IPV6, IPV6_V6ONLY ) {
153e0680481Safresh1               return $can_disable_v6only = 0;
154e0680481Safresh1            }
155e0680481Safresh1         }
1566fb12b70Safresh1         return $can_disable_v6only = 1;
1576fb12b70Safresh1      }
1582e109fb9Safresh1      elsif( $! == EINVAL || $! == EOPNOTSUPP ) {
1596fb12b70Safresh1         return $can_disable_v6only = 0;
1606fb12b70Safresh1      }
1616fb12b70Safresh1      else {
1626fb12b70Safresh1         die "Cannot setsockopt() - $!";
1636fb12b70Safresh1      }
1646fb12b70Safresh1   }
1656fb12b70Safresh1}
1666fb12b70Safresh1
1676fb12b70Safresh1=head1 CONSTRUCTORS
1686fb12b70Safresh1
1696fb12b70Safresh1=cut
1706fb12b70Safresh1
171eac174f2Safresh1=head2 new
172eac174f2Safresh1
173eac174f2Safresh1   $sock = IO::Socket::IP->new( %args )
1746fb12b70Safresh1
1756fb12b70Safresh1Creates a new C<IO::Socket::IP> object, containing a newly created socket
1766fb12b70Safresh1handle according to the named arguments passed. The recognised arguments are:
1776fb12b70Safresh1
1786fb12b70Safresh1=over 8
1796fb12b70Safresh1
1806fb12b70Safresh1=item PeerHost => STRING
1816fb12b70Safresh1
1826fb12b70Safresh1=item PeerService => STRING
1836fb12b70Safresh1
1846fb12b70Safresh1Hostname and service name for the peer to C<connect()> to. The service name
1856fb12b70Safresh1may be given as a port number, as a decimal string.
1866fb12b70Safresh1
1876fb12b70Safresh1=item PeerAddr => STRING
1886fb12b70Safresh1
1896fb12b70Safresh1=item PeerPort => STRING
1906fb12b70Safresh1
1916fb12b70Safresh1For symmetry with the accessor methods and compatibility with
1926fb12b70Safresh1C<IO::Socket::INET>, these are accepted as synonyms for C<PeerHost> and
1936fb12b70Safresh1C<PeerService> respectively.
1946fb12b70Safresh1
1956fb12b70Safresh1=item PeerAddrInfo => ARRAY
1966fb12b70Safresh1
1976fb12b70Safresh1Alternate form of specifying the peer to C<connect()> to. This should be an
1986fb12b70Safresh1array of the form returned by C<Socket::getaddrinfo>.
1996fb12b70Safresh1
2006fb12b70Safresh1This parameter takes precedence over the C<Peer*>, C<Family>, C<Type> and
2016fb12b70Safresh1C<Proto> arguments.
2026fb12b70Safresh1
2036fb12b70Safresh1=item LocalHost => STRING
2046fb12b70Safresh1
2056fb12b70Safresh1=item LocalService => STRING
2066fb12b70Safresh1
2076fb12b70Safresh1Hostname and service name for the local address to C<bind()> to.
2086fb12b70Safresh1
2096fb12b70Safresh1=item LocalAddr => STRING
2106fb12b70Safresh1
2116fb12b70Safresh1=item LocalPort => STRING
2126fb12b70Safresh1
2136fb12b70Safresh1For symmetry with the accessor methods and compatibility with
2146fb12b70Safresh1C<IO::Socket::INET>, these are accepted as synonyms for C<LocalHost> and
2156fb12b70Safresh1C<LocalService> respectively.
2166fb12b70Safresh1
2176fb12b70Safresh1=item LocalAddrInfo => ARRAY
2186fb12b70Safresh1
2196fb12b70Safresh1Alternate form of specifying the local address to C<bind()> to. This should be
2206fb12b70Safresh1an array of the form returned by C<Socket::getaddrinfo>.
2216fb12b70Safresh1
2226fb12b70Safresh1This parameter takes precedence over the C<Local*>, C<Family>, C<Type> and
2236fb12b70Safresh1C<Proto> arguments.
2246fb12b70Safresh1
2256fb12b70Safresh1=item Family => INT
2266fb12b70Safresh1
2276fb12b70Safresh1The address family to pass to C<getaddrinfo> (e.g. C<AF_INET>, C<AF_INET6>).
2286fb12b70Safresh1Normally this will be left undefined, and C<getaddrinfo> will search using any
2296fb12b70Safresh1address family supported by the system.
2306fb12b70Safresh1
2316fb12b70Safresh1=item Type => INT
2326fb12b70Safresh1
2336fb12b70Safresh1The socket type to pass to C<getaddrinfo> (e.g. C<SOCK_STREAM>,
2346fb12b70Safresh1C<SOCK_DGRAM>). Normally defined by the caller; if left undefined
2356fb12b70Safresh1C<getaddrinfo> may attempt to infer the type from the service name.
2366fb12b70Safresh1
2376fb12b70Safresh1=item Proto => STRING or INT
2386fb12b70Safresh1
2396fb12b70Safresh1The IP protocol to use for the socket (e.g. C<'tcp'>, C<IPPROTO_TCP>,
2406fb12b70Safresh1C<'udp'>,C<IPPROTO_UDP>). Normally this will be left undefined, and either
2416fb12b70Safresh1C<getaddrinfo> or the kernel will choose an appropriate value. May be given
2426fb12b70Safresh1either in string name or numeric form.
2436fb12b70Safresh1
2446fb12b70Safresh1=item GetAddrInfoFlags => INT
2456fb12b70Safresh1
2466fb12b70Safresh1More flags to pass to the C<getaddrinfo()> function. If not supplied, a
2476fb12b70Safresh1default of C<AI_ADDRCONFIG> will be used.
2486fb12b70Safresh1
2496fb12b70Safresh1These flags will be combined with C<AI_PASSIVE> if the C<Listen> argument is
2506fb12b70Safresh1given. For more information see the documentation about C<getaddrinfo()> in
2516fb12b70Safresh1the L<Socket> module.
2526fb12b70Safresh1
2536fb12b70Safresh1=item Listen => INT
2546fb12b70Safresh1
2556fb12b70Safresh1If defined, puts the socket into listening mode where new connections can be
2566fb12b70Safresh1accepted using the C<accept> method. The value given is used as the
2576fb12b70Safresh1C<listen(2)> queue size.
2586fb12b70Safresh1
2596fb12b70Safresh1=item ReuseAddr => BOOL
2606fb12b70Safresh1
2616fb12b70Safresh1If true, set the C<SO_REUSEADDR> sockopt
2626fb12b70Safresh1
2636fb12b70Safresh1=item ReusePort => BOOL
2646fb12b70Safresh1
2656fb12b70Safresh1If true, set the C<SO_REUSEPORT> sockopt (not all OSes implement this sockopt)
2666fb12b70Safresh1
2676fb12b70Safresh1=item Broadcast => BOOL
2686fb12b70Safresh1
2696fb12b70Safresh1If true, set the C<SO_BROADCAST> sockopt
2706fb12b70Safresh1
2712e109fb9Safresh1=item Sockopts => ARRAY
2722e109fb9Safresh1
2732e109fb9Safresh1An optional array of other socket options to apply after the three listed
2742e109fb9Safresh1above. The value is an ARRAY containing 2- or 3-element ARRAYrefs. Each inner
2752e109fb9Safresh1array relates to a single option, giving the level and option name, and an
2762e109fb9Safresh1optional value. If the value element is missing, it will be given the value of
2772e109fb9Safresh1a platform-sized integer 1 constant (i.e. suitable to enable most of the
2782e109fb9Safresh1common boolean options).
2792e109fb9Safresh1
2802e109fb9Safresh1For example, both options given below are equivalent to setting C<ReuseAddr>.
2812e109fb9Safresh1
2822e109fb9Safresh1   Sockopts => [
2832e109fb9Safresh1      [ SOL_SOCKET, SO_REUSEADDR ],
2842e109fb9Safresh1      [ SOL_SOCKET, SO_REUSEADDR, pack( "i", 1 ) ],
2852e109fb9Safresh1   ]
2862e109fb9Safresh1
2876fb12b70Safresh1=item V6Only => BOOL
2886fb12b70Safresh1
2896fb12b70Safresh1If defined, set the C<IPV6_V6ONLY> sockopt when creating C<PF_INET6> sockets
2906fb12b70Safresh1to the given value. If true, a listening-mode socket will only listen on the
2916fb12b70Safresh1C<AF_INET6> addresses; if false it will also accept connections from
2926fb12b70Safresh1C<AF_INET> addresses.
2936fb12b70Safresh1
2946fb12b70Safresh1If not defined, the socket option will not be changed, and default value set
2956fb12b70Safresh1by the operating system will apply. For repeatable behaviour across platforms
2966fb12b70Safresh1it is recommended this value always be defined for listening-mode sockets.
2976fb12b70Safresh1
2986fb12b70Safresh1Note that not all platforms support disabling this option. Some, at least
2996fb12b70Safresh1OpenBSD and MirBSD, will fail with C<EINVAL> if you attempt to disable it.
3006fb12b70Safresh1To determine whether it is possible to disable, you may use the class method
3016fb12b70Safresh1
3026fb12b70Safresh1   if( IO::Socket::IP->CAN_DISABLE_V6ONLY ) {
3036fb12b70Safresh1      ...
3046fb12b70Safresh1   }
3056fb12b70Safresh1   else {
3066fb12b70Safresh1      ...
3076fb12b70Safresh1   }
3086fb12b70Safresh1
3096fb12b70Safresh1If your platform does not support disabling this option but you still want to
3106fb12b70Safresh1listen for both C<AF_INET> and C<AF_INET6> connections you will have to create
3116fb12b70Safresh1two listening sockets, one bound to each protocol.
3126fb12b70Safresh1
3136fb12b70Safresh1=item MultiHomed
3146fb12b70Safresh1
3156fb12b70Safresh1This C<IO::Socket::INET>-style argument is ignored, except if it is defined
3166fb12b70Safresh1but false. See the C<IO::Socket::INET> INCOMPATIBILITES section below.
3176fb12b70Safresh1
3186fb12b70Safresh1However, the behaviour it enables is always performed by C<IO::Socket::IP>.
3196fb12b70Safresh1
3206fb12b70Safresh1=item Blocking => BOOL
3216fb12b70Safresh1
3226fb12b70Safresh1If defined but false, the socket will be set to non-blocking mode. Otherwise
3236fb12b70Safresh1it will default to blocking mode. See the NON-BLOCKING section below for more
3246fb12b70Safresh1detail.
3256fb12b70Safresh1
326b8851fccSafresh1=item Timeout => NUM
327b8851fccSafresh1
328b8851fccSafresh1If defined, gives a maximum time in seconds to block per C<connect()> call
329b8851fccSafresh1when in blocking mode. If missing, no timeout is applied other than that
330b8851fccSafresh1provided by the underlying operating system. When in non-blocking mode this
331b8851fccSafresh1parameter is ignored.
332b8851fccSafresh1
333b8851fccSafresh1Note that if the hostname resolves to multiple address candidates, the same
334b8851fccSafresh1timeout will apply to each connection attempt individually, rather than to the
335b8851fccSafresh1operation as a whole. Further note that the timeout does not apply to the
336b8851fccSafresh1initial hostname resolve operation, if connecting by hostname.
337b8851fccSafresh1
338*3d61058aSafresh1This behaviour is copied inspired by C<IO::Socket::INET>; for more fine
339*3d61058aSafresh1grained control over connection timeouts, consider performing a nonblocking
340*3d61058aSafresh1connect directly.
341b8851fccSafresh1
3426fb12b70Safresh1=back
3436fb12b70Safresh1
3446fb12b70Safresh1If neither C<Type> nor C<Proto> hints are provided, a default of
3456fb12b70Safresh1C<SOCK_STREAM> and C<IPPROTO_TCP> respectively will be set, to maintain
3466fb12b70Safresh1compatibility with C<IO::Socket::INET>. Other named arguments that are not
3476fb12b70Safresh1recognised are ignored.
3486fb12b70Safresh1
3496fb12b70Safresh1If neither C<Family> nor any hosts or addresses are passed, nor any
3506fb12b70Safresh1C<*AddrInfo>, then the constructor has no information on which to decide a
3516fb12b70Safresh1socket family to create. In this case, it performs a C<getaddinfo> call with
3526fb12b70Safresh1the C<AI_ADDRCONFIG> flag, no host name, and a service name of C<"0">, and
3536fb12b70Safresh1uses the family of the first returned result.
3546fb12b70Safresh1
355*3d61058aSafresh1If the constructor fails, it will set C<$IO::Socket::errstr> and C<$@> to
356*3d61058aSafresh1an appropriate error message; this may be from C<$!> or it may be some other
357*3d61058aSafresh1string; not every failure necessarily has an associated C<errno> value.
3586fb12b70Safresh1
359eac174f2Safresh1=head2 new (one arg)
360eac174f2Safresh1
361eac174f2Safresh1   $sock = IO::Socket::IP->new( $peeraddr )
3626fb12b70Safresh1
3636fb12b70Safresh1As a special case, if the constructor is passed a single argument (as
3646fb12b70Safresh1opposed to an even-sized list of key/value pairs), it is taken to be the value
3656fb12b70Safresh1of the C<PeerAddr> parameter. This is parsed in the same way, according to the
3666fb12b70Safresh1behaviour given in the C<PeerHost> AND C<LocalHost> PARSING section below.
3676fb12b70Safresh1
3686fb12b70Safresh1=cut
3696fb12b70Safresh1
3706fb12b70Safresh1sub new
3716fb12b70Safresh1{
3726fb12b70Safresh1   my $class = shift;
3736fb12b70Safresh1   my %arg = (@_ == 1) ? (PeerHost => $_[0]) : @_;
3746fb12b70Safresh1   return $class->SUPER::new(%arg);
3756fb12b70Safresh1}
3766fb12b70Safresh1
3776fb12b70Safresh1# IO::Socket may call this one; neaten up the arguments from IO::Socket::INET
3786fb12b70Safresh1# before calling our real _configure method
3796fb12b70Safresh1sub configure
3806fb12b70Safresh1{
3816fb12b70Safresh1   my $self = shift;
3826fb12b70Safresh1   my ( $arg ) = @_;
3836fb12b70Safresh1
3846fb12b70Safresh1   $arg->{PeerHost} = delete $arg->{PeerAddr}
3856fb12b70Safresh1      if exists $arg->{PeerAddr} && !exists $arg->{PeerHost};
3866fb12b70Safresh1
3876fb12b70Safresh1   $arg->{PeerService} = delete $arg->{PeerPort}
3886fb12b70Safresh1      if exists $arg->{PeerPort} && !exists $arg->{PeerService};
3896fb12b70Safresh1
3906fb12b70Safresh1   $arg->{LocalHost} = delete $arg->{LocalAddr}
3916fb12b70Safresh1      if exists $arg->{LocalAddr} && !exists $arg->{LocalHost};
3926fb12b70Safresh1
3936fb12b70Safresh1   $arg->{LocalService} = delete $arg->{LocalPort}
3946fb12b70Safresh1      if exists $arg->{LocalPort} && !exists $arg->{LocalService};
3956fb12b70Safresh1
3966fb12b70Safresh1   for my $type (qw(Peer Local)) {
3976fb12b70Safresh1      my $host    = $type . 'Host';
3986fb12b70Safresh1      my $service = $type . 'Service';
3996fb12b70Safresh1
4006fb12b70Safresh1      if( defined $arg->{$host} ) {
4016fb12b70Safresh1         ( $arg->{$host}, my $s ) = $self->split_addr( $arg->{$host} );
4026fb12b70Safresh1         # IO::Socket::INET compat - *Host parsed port always takes precedence
4036fb12b70Safresh1         $arg->{$service} = $s if defined $s;
4046fb12b70Safresh1      }
4056fb12b70Safresh1   }
4066fb12b70Safresh1
4076fb12b70Safresh1   $self->_io_socket_ip__configure( $arg );
4086fb12b70Safresh1}
4096fb12b70Safresh1
4106fb12b70Safresh1# Avoid simply calling it _configure, as some subclasses of IO::Socket::INET on CPAN already take that
4116fb12b70Safresh1sub _io_socket_ip__configure
4126fb12b70Safresh1{
4136fb12b70Safresh1   my $self = shift;
4146fb12b70Safresh1   my ( $arg ) = @_;
4156fb12b70Safresh1
4166fb12b70Safresh1   my %hints;
4176fb12b70Safresh1   my @localinfos;
4186fb12b70Safresh1   my @peerinfos;
4196fb12b70Safresh1
420b8851fccSafresh1   my $listenqueue = $arg->{Listen};
421b8851fccSafresh1   if( defined $listenqueue and
422b8851fccSafresh1       ( defined $arg->{PeerHost} || defined $arg->{PeerService} || defined $arg->{PeerAddrInfo} ) ) {
423b8851fccSafresh1      croak "Cannot Listen with a peer address";
424b8851fccSafresh1   }
425b8851fccSafresh1
4266fb12b70Safresh1   if( defined $arg->{GetAddrInfoFlags} ) {
4276fb12b70Safresh1      $hints{flags} = $arg->{GetAddrInfoFlags};
4286fb12b70Safresh1   }
4296fb12b70Safresh1   else {
4306fb12b70Safresh1      $hints{flags} = $AI_ADDRCONFIG;
4316fb12b70Safresh1   }
4326fb12b70Safresh1
4336fb12b70Safresh1   if( defined( my $family = $arg->{Family} ) ) {
4346fb12b70Safresh1      $hints{family} = $family;
4356fb12b70Safresh1   }
4366fb12b70Safresh1
4376fb12b70Safresh1   if( defined( my $type = $arg->{Type} ) ) {
4386fb12b70Safresh1      $hints{socktype} = $type;
4396fb12b70Safresh1   }
4406fb12b70Safresh1
4416fb12b70Safresh1   if( defined( my $proto = $arg->{Proto} ) ) {
4426fb12b70Safresh1      unless( $proto =~ m/^\d+$/ ) {
4436fb12b70Safresh1         my $protonum = HAVE_GETPROTOBYNAME
4446fb12b70Safresh1            ? getprotobyname( $proto )
4456fb12b70Safresh1            : eval { Socket->${\"IPPROTO_\U$proto"}() };
4466fb12b70Safresh1         defined $protonum or croak "Unrecognised protocol $proto";
4476fb12b70Safresh1         $proto = $protonum;
4486fb12b70Safresh1      }
4496fb12b70Safresh1
4506fb12b70Safresh1      $hints{protocol} = $proto;
4516fb12b70Safresh1   }
4526fb12b70Safresh1
4536fb12b70Safresh1   # To maintain compatibility with IO::Socket::INET, imply a default of
4546fb12b70Safresh1   # SOCK_STREAM + IPPROTO_TCP if neither hint is given
4556fb12b70Safresh1   if( !defined $hints{socktype} and !defined $hints{protocol} ) {
4566fb12b70Safresh1      $hints{socktype} = SOCK_STREAM;
4576fb12b70Safresh1      $hints{protocol} = IPPROTO_TCP;
4586fb12b70Safresh1   }
4596fb12b70Safresh1
4606fb12b70Safresh1   # Some OSes (NetBSD) don't seem to like just a protocol hint without a
4616fb12b70Safresh1   # socktype hint as well. We'll set a couple of common ones
4626fb12b70Safresh1   if( !defined $hints{socktype} and defined $hints{protocol} ) {
4636fb12b70Safresh1      $hints{socktype} = SOCK_STREAM if $hints{protocol} == IPPROTO_TCP;
4646fb12b70Safresh1      $hints{socktype} = SOCK_DGRAM  if $hints{protocol} == IPPROTO_UDP;
4656fb12b70Safresh1   }
4666fb12b70Safresh1
4676fb12b70Safresh1   if( my $info = $arg->{LocalAddrInfo} ) {
4686fb12b70Safresh1      ref $info eq "ARRAY" or croak "Expected 'LocalAddrInfo' to be an ARRAY ref";
4696fb12b70Safresh1      @localinfos = @$info;
4706fb12b70Safresh1   }
471b8851fccSafresh1   elsif( defined $arg->{LocalHost} or
472b8851fccSafresh1          defined $arg->{LocalService} or
473b8851fccSafresh1          HAVE_MSWIN32 and $arg->{Listen} ) {
4746fb12b70Safresh1      # Either may be undef
4756fb12b70Safresh1      my $host = $arg->{LocalHost};
4766fb12b70Safresh1      my $service = $arg->{LocalService};
4776fb12b70Safresh1
478b8851fccSafresh1      unless ( defined $host or defined $service ) {
479b8851fccSafresh1         $service = 0;
480b8851fccSafresh1      }
481b8851fccSafresh1
4826fb12b70Safresh1      local $1; # Placate a taint-related bug; [perl #67962]
4836fb12b70Safresh1      defined $service and $service =~ s/\((\d+)\)$// and
4846fb12b70Safresh1         my $fallback_port = $1;
4856fb12b70Safresh1
4866fb12b70Safresh1      my %localhints = %hints;
4876fb12b70Safresh1      $localhints{flags} |= AI_PASSIVE;
4886fb12b70Safresh1      ( my $err, @localinfos ) = getaddrinfo( $host, $service, \%localhints );
4896fb12b70Safresh1
4906fb12b70Safresh1      if( $err and defined $fallback_port ) {
4916fb12b70Safresh1         ( $err, @localinfos ) = getaddrinfo( $host, $fallback_port, \%localhints );
4926fb12b70Safresh1      }
4936fb12b70Safresh1
4946fb12b70Safresh1      if( $err ) {
495*3d61058aSafresh1         $IO::Socket::errstr = $@ = "$err";
4966fb12b70Safresh1         $! = EINVAL;
4976fb12b70Safresh1         return;
4986fb12b70Safresh1      }
4996fb12b70Safresh1   }
5006fb12b70Safresh1
5016fb12b70Safresh1   if( my $info = $arg->{PeerAddrInfo} ) {
5026fb12b70Safresh1      ref $info eq "ARRAY" or croak "Expected 'PeerAddrInfo' to be an ARRAY ref";
5036fb12b70Safresh1      @peerinfos = @$info;
5046fb12b70Safresh1   }
5056fb12b70Safresh1   elsif( defined $arg->{PeerHost} or defined $arg->{PeerService} ) {
5066fb12b70Safresh1      defined( my $host = $arg->{PeerHost} ) or
5076fb12b70Safresh1         croak "Expected 'PeerHost'";
5086fb12b70Safresh1      defined( my $service = $arg->{PeerService} ) or
5096fb12b70Safresh1         croak "Expected 'PeerService'";
5106fb12b70Safresh1
5116fb12b70Safresh1      local $1; # Placate a taint-related bug; [perl #67962]
5126fb12b70Safresh1      defined $service and $service =~ s/\((\d+)\)$// and
5136fb12b70Safresh1         my $fallback_port = $1;
5146fb12b70Safresh1
5156fb12b70Safresh1      ( my $err, @peerinfos ) = getaddrinfo( $host, $service, \%hints );
5166fb12b70Safresh1
5176fb12b70Safresh1      if( $err and defined $fallback_port ) {
5186fb12b70Safresh1         ( $err, @peerinfos ) = getaddrinfo( $host, $fallback_port, \%hints );
5196fb12b70Safresh1      }
5206fb12b70Safresh1
5216fb12b70Safresh1      if( $err ) {
522*3d61058aSafresh1         $IO::Socket::errstr = $@ = "$err";
5236fb12b70Safresh1         $! = EINVAL;
5246fb12b70Safresh1         return;
5256fb12b70Safresh1      }
5266fb12b70Safresh1   }
5276fb12b70Safresh1
5282e109fb9Safresh1   my $INT_1 = pack "i", 1;
5292e109fb9Safresh1
5306fb12b70Safresh1   my @sockopts_enabled;
5312e109fb9Safresh1   push @sockopts_enabled, [ SOL_SOCKET, SO_REUSEADDR, $INT_1 ] if $arg->{ReuseAddr};
5322e109fb9Safresh1   push @sockopts_enabled, [ SOL_SOCKET, SO_REUSEPORT, $INT_1 ] if $arg->{ReusePort};
5332e109fb9Safresh1   push @sockopts_enabled, [ SOL_SOCKET, SO_BROADCAST, $INT_1 ] if $arg->{Broadcast};
5342e109fb9Safresh1
5352e109fb9Safresh1   if( my $sockopts = $arg->{Sockopts} ) {
5362e109fb9Safresh1      ref $sockopts eq "ARRAY" or croak "Expected 'Sockopts' to be an ARRAY ref";
5372e109fb9Safresh1      foreach ( @$sockopts ) {
5382e109fb9Safresh1         ref $_ eq "ARRAY" or croak "Bad Sockopts item - expected ARRAYref";
5392e109fb9Safresh1         @$_ >= 2 and @$_ <= 3 or
5402e109fb9Safresh1            croak "Bad Sockopts item - expected 2 or 3 elements";
5412e109fb9Safresh1
5422e109fb9Safresh1         my ( $level, $optname, $value ) = @$_;
5432e109fb9Safresh1         # TODO: consider more sanity checking on argument values
5442e109fb9Safresh1
5452e109fb9Safresh1         defined $value or $value = $INT_1;
5462e109fb9Safresh1         push @sockopts_enabled, [ $level, $optname, $value ];
5472e109fb9Safresh1      }
5482e109fb9Safresh1   }
5496fb12b70Safresh1
5506fb12b70Safresh1   my $blocking = $arg->{Blocking};
5516fb12b70Safresh1   defined $blocking or $blocking = 1;
5526fb12b70Safresh1
5536fb12b70Safresh1   my $v6only = $arg->{V6Only};
5546fb12b70Safresh1
5556fb12b70Safresh1   # IO::Socket::INET defines this key. IO::Socket::IP always implements the
5566fb12b70Safresh1   # behaviour it requests, so we can ignore it, unless the caller is for some
5576fb12b70Safresh1   # reason asking to disable it.
5586fb12b70Safresh1   if( defined $arg->{MultiHomed} and !$arg->{MultiHomed} ) {
5596fb12b70Safresh1      croak "Cannot disable the MultiHomed parameter";
5606fb12b70Safresh1   }
5616fb12b70Safresh1
5626fb12b70Safresh1   my @infos;
5636fb12b70Safresh1   foreach my $local ( @localinfos ? @localinfos : {} ) {
5646fb12b70Safresh1      foreach my $peer ( @peerinfos ? @peerinfos : {} ) {
5656fb12b70Safresh1         next if defined $local->{family}   and defined $peer->{family}   and
5666fb12b70Safresh1            $local->{family} != $peer->{family};
5676fb12b70Safresh1         next if defined $local->{socktype} and defined $peer->{socktype} and
5686fb12b70Safresh1            $local->{socktype} != $peer->{socktype};
5696fb12b70Safresh1         next if defined $local->{protocol} and defined $peer->{protocol} and
5706fb12b70Safresh1            $local->{protocol} != $peer->{protocol};
5716fb12b70Safresh1
5726fb12b70Safresh1         my $family   = $local->{family}   || $peer->{family}   or next;
5736fb12b70Safresh1         my $socktype = $local->{socktype} || $peer->{socktype} or next;
5746fb12b70Safresh1         my $protocol = $local->{protocol} || $peer->{protocol} || 0;
5756fb12b70Safresh1
5766fb12b70Safresh1         push @infos, {
5776fb12b70Safresh1            family    => $family,
5786fb12b70Safresh1            socktype  => $socktype,
5796fb12b70Safresh1            protocol  => $protocol,
5806fb12b70Safresh1            localaddr => $local->{addr},
5816fb12b70Safresh1            peeraddr  => $peer->{addr},
5826fb12b70Safresh1         };
5836fb12b70Safresh1      }
5846fb12b70Safresh1   }
5856fb12b70Safresh1
5866fb12b70Safresh1   if( !@infos ) {
5876fb12b70Safresh1      # If there was a Family hint then create a plain unbound, unconnected socket
5886fb12b70Safresh1      if( defined $hints{family} ) {
5896fb12b70Safresh1         @infos = ( {
5906fb12b70Safresh1            family   => $hints{family},
5916fb12b70Safresh1            socktype => $hints{socktype},
5926fb12b70Safresh1            protocol => $hints{protocol},
5936fb12b70Safresh1         } );
5946fb12b70Safresh1      }
5956fb12b70Safresh1      # If there wasn't, use getaddrinfo()'s AI_ADDRCONFIG side-effect to guess a
5966fb12b70Safresh1      # suitable family first.
5976fb12b70Safresh1      else {
5986fb12b70Safresh1         ( my $err, @infos ) = getaddrinfo( "", "0", \%hints );
5996fb12b70Safresh1         if( $err ) {
600*3d61058aSafresh1            $IO::Socket::errstr = $@ = "$err";
6016fb12b70Safresh1            $! = EINVAL;
6026fb12b70Safresh1            return;
6036fb12b70Safresh1         }
6046fb12b70Safresh1
6056fb12b70Safresh1         # We'll take all the @infos anyway, because some OSes (HPUX) are known to
6066fb12b70Safresh1         # ignore the AI_ADDRCONFIG hint and return AF_INET6 even if they don't
6076fb12b70Safresh1         # support them
6086fb12b70Safresh1      }
6096fb12b70Safresh1   }
6106fb12b70Safresh1
6116fb12b70Safresh1   # In the nonblocking case, caller will be calling ->setup multiple times.
6126fb12b70Safresh1   # Store configuration in the object for the ->setup method
6136fb12b70Safresh1   # Yes, these are messy. Sorry, I can't help that...
6146fb12b70Safresh1
6156fb12b70Safresh1   ${*$self}{io_socket_ip_infos} = \@infos;
6166fb12b70Safresh1
6176fb12b70Safresh1   ${*$self}{io_socket_ip_idx} = -1;
6186fb12b70Safresh1
6196fb12b70Safresh1   ${*$self}{io_socket_ip_sockopts} = \@sockopts_enabled;
6206fb12b70Safresh1   ${*$self}{io_socket_ip_v6only} = $v6only;
6216fb12b70Safresh1   ${*$self}{io_socket_ip_listenqueue} = $listenqueue;
6226fb12b70Safresh1   ${*$self}{io_socket_ip_blocking} = $blocking;
6236fb12b70Safresh1
6246fb12b70Safresh1   ${*$self}{io_socket_ip_errors} = [ undef, undef, undef ];
6256fb12b70Safresh1
6266fb12b70Safresh1   # ->setup is allowed to return false in nonblocking mode
6276fb12b70Safresh1   $self->setup or !$blocking or return undef;
6286fb12b70Safresh1
6296fb12b70Safresh1   return $self;
6306fb12b70Safresh1}
6316fb12b70Safresh1
6326fb12b70Safresh1sub setup
6336fb12b70Safresh1{
6346fb12b70Safresh1   my $self = shift;
6356fb12b70Safresh1
6366fb12b70Safresh1   while(1) {
6376fb12b70Safresh1      ${*$self}{io_socket_ip_idx}++;
6386fb12b70Safresh1      last if ${*$self}{io_socket_ip_idx} >= @{ ${*$self}{io_socket_ip_infos} };
6396fb12b70Safresh1
6406fb12b70Safresh1      my $info = ${*$self}{io_socket_ip_infos}->[${*$self}{io_socket_ip_idx}];
6416fb12b70Safresh1
6426fb12b70Safresh1      $self->socket( @{$info}{qw( family socktype protocol )} ) or
6436fb12b70Safresh1         ( ${*$self}{io_socket_ip_errors}[2] = $!, next );
6446fb12b70Safresh1
6456fb12b70Safresh1      $self->blocking( 0 ) unless ${*$self}{io_socket_ip_blocking};
6466fb12b70Safresh1
6476fb12b70Safresh1      foreach my $sockopt ( @{ ${*$self}{io_socket_ip_sockopts} } ) {
6482e109fb9Safresh1         my ( $level, $optname, $value ) = @$sockopt;
649*3d61058aSafresh1         $self->setsockopt( $level, $optname, $value ) or
650*3d61058aSafresh1            ( $IO::Socket::errstr = $@ = "$!", return undef );
6516fb12b70Safresh1      }
6526fb12b70Safresh1
6536fb12b70Safresh1      if( defined ${*$self}{io_socket_ip_v6only} and defined $AF_INET6 and $info->{family} == $AF_INET6 ) {
6546fb12b70Safresh1         my $v6only = ${*$self}{io_socket_ip_v6only};
655*3d61058aSafresh1         $self->setsockopt( IPPROTO_IPV6, IPV6_V6ONLY, pack "i", $v6only ) or
656*3d61058aSafresh1            ( $IO::Socket::errstr = $@ = "$!", return undef );
6576fb12b70Safresh1      }
6586fb12b70Safresh1
6596fb12b70Safresh1      if( defined( my $addr = $info->{localaddr} ) ) {
6606fb12b70Safresh1         $self->bind( $addr ) or
6616fb12b70Safresh1            ( ${*$self}{io_socket_ip_errors}[1] = $!, next );
6626fb12b70Safresh1      }
6636fb12b70Safresh1
6646fb12b70Safresh1      if( defined( my $listenqueue = ${*$self}{io_socket_ip_listenqueue} ) ) {
665*3d61058aSafresh1         $self->listen( $listenqueue ) or
666*3d61058aSafresh1            ( $IO::Socket::errstr = $@ = "$!", return undef );
6676fb12b70Safresh1      }
6686fb12b70Safresh1
6696fb12b70Safresh1      if( defined( my $addr = $info->{peeraddr} ) ) {
6706fb12b70Safresh1         if( $self->connect( $addr ) ) {
6716fb12b70Safresh1            $! = 0;
6726fb12b70Safresh1            return 1;
6736fb12b70Safresh1         }
6746fb12b70Safresh1
675b8851fccSafresh1         if( $! == EINPROGRESS or $! == EWOULDBLOCK ) {
6766fb12b70Safresh1            ${*$self}{io_socket_ip_connect_in_progress} = 1;
6776fb12b70Safresh1            return 0;
6786fb12b70Safresh1         }
6796fb12b70Safresh1
680b8851fccSafresh1         # If connect failed but we have no system error there must be an error
681b8851fccSafresh1         # at the application layer, like a bad certificate with
682b8851fccSafresh1         # IO::Socket::SSL.
683b8851fccSafresh1         # In this case don't continue IP based multi-homing because the problem
684b8851fccSafresh1         # cannot be solved at the IP layer.
685b8851fccSafresh1         return 0 if ! $!;
686b8851fccSafresh1
6876fb12b70Safresh1         ${*$self}{io_socket_ip_errors}[0] = $!;
6886fb12b70Safresh1         next;
6896fb12b70Safresh1      }
6906fb12b70Safresh1
6916fb12b70Safresh1      return 1;
6926fb12b70Safresh1   }
6936fb12b70Safresh1
6946fb12b70Safresh1   # Pick the most appropriate error, stringified
6956fb12b70Safresh1   $! = ( grep defined, @{ ${*$self}{io_socket_ip_errors}} )[0];
696*3d61058aSafresh1   $IO::Socket::errstr = $@ = "$!";
6976fb12b70Safresh1   return undef;
6986fb12b70Safresh1}
6996fb12b70Safresh1
700b8851fccSafresh1sub connect :method
7016fb12b70Safresh1{
7026fb12b70Safresh1   my $self = shift;
7036fb12b70Safresh1
7046fb12b70Safresh1   # It seems that IO::Socket hides EINPROGRESS errors, making them look like
7056fb12b70Safresh1   # a success. This is annoying here.
7066fb12b70Safresh1   # Instead of putting up with its frankly-irritating intentional breakage of
707b8851fccSafresh1   # useful APIs I'm just going to end-run around it and call core's connect()
7086fb12b70Safresh1   # directly
7096fb12b70Safresh1
710b8851fccSafresh1   if( @_ ) {
711b8851fccSafresh1      my ( $addr ) = @_;
712b8851fccSafresh1
713b8851fccSafresh1      # Annoyingly IO::Socket's connect() is where the timeout logic is
714b8851fccSafresh1      # implemented, so we'll have to reinvent it here
715b8851fccSafresh1      my $timeout = ${*$self}{'io_socket_timeout'};
716b8851fccSafresh1
717b8851fccSafresh1      return connect( $self, $addr ) unless defined $timeout;
718b8851fccSafresh1
719b8851fccSafresh1      my $was_blocking = $self->blocking( 0 );
720b8851fccSafresh1
721b8851fccSafresh1      my $err = defined connect( $self, $addr ) ? 0 : $!+0;
722b8851fccSafresh1
723b8851fccSafresh1      if( !$err ) {
724b8851fccSafresh1         # All happy
725b8851fccSafresh1         $self->blocking( $was_blocking );
726b8851fccSafresh1         return 1;
727b8851fccSafresh1      }
728b8851fccSafresh1      elsif( not( $err == EINPROGRESS or $err == EWOULDBLOCK ) ) {
729b8851fccSafresh1         # Failed for some other reason
7302e109fb9Safresh1         $self->blocking( $was_blocking );
731b8851fccSafresh1         return undef;
732b8851fccSafresh1      }
733b8851fccSafresh1      elsif( !$was_blocking ) {
734b8851fccSafresh1         # We shouldn't block anyway
735b8851fccSafresh1         return undef;
736b8851fccSafresh1      }
737b8851fccSafresh1
738b8851fccSafresh1      my $vec = ''; vec( $vec, $self->fileno, 1 ) = 1;
739b8851fccSafresh1      if( !select( undef, $vec, $vec, $timeout ) ) {
7402e109fb9Safresh1         $self->blocking( $was_blocking );
741b8851fccSafresh1         $! = ETIMEDOUT;
742b8851fccSafresh1         return undef;
743b8851fccSafresh1      }
744b8851fccSafresh1
745b8851fccSafresh1      # Hoist the error by connect()ing a second time
746b8851fccSafresh1      $err = $self->getsockopt( SOL_SOCKET, SO_ERROR );
747b8851fccSafresh1      $err = 0 if $err == EISCONN; # Some OSes give EISCONN
748b8851fccSafresh1
749b8851fccSafresh1      $self->blocking( $was_blocking );
750b8851fccSafresh1
751b8851fccSafresh1      $! = $err, return undef if $err;
752b8851fccSafresh1      return 1;
753b8851fccSafresh1   }
7546fb12b70Safresh1
7556fb12b70Safresh1   return 1 if !${*$self}{io_socket_ip_connect_in_progress};
7566fb12b70Safresh1
7576fb12b70Safresh1   # See if a connect attempt has just failed with an error
7586fb12b70Safresh1   if( my $errno = $self->getsockopt( SOL_SOCKET, SO_ERROR ) ) {
7596fb12b70Safresh1      delete ${*$self}{io_socket_ip_connect_in_progress};
7606fb12b70Safresh1      ${*$self}{io_socket_ip_errors}[0] = $! = $errno;
7616fb12b70Safresh1      return $self->setup;
7626fb12b70Safresh1   }
7636fb12b70Safresh1
7646fb12b70Safresh1   # No error, so either connect is still in progress, or has completed
7656fb12b70Safresh1   # successfully. We can tell by trying to connect() again; either it will
7666fb12b70Safresh1   # succeed or we'll get EISCONN (connected successfully), or EALREADY
7676fb12b70Safresh1   # (still in progress). This even works on MSWin32.
7686fb12b70Safresh1   my $addr = ${*$self}{io_socket_ip_infos}[${*$self}{io_socket_ip_idx}]{peeraddr};
7696fb12b70Safresh1
770b8851fccSafresh1   if( connect( $self, $addr ) or $! == EISCONN ) {
7716fb12b70Safresh1      delete ${*$self}{io_socket_ip_connect_in_progress};
7726fb12b70Safresh1      $! = 0;
7736fb12b70Safresh1      return 1;
7746fb12b70Safresh1   }
7756fb12b70Safresh1   else {
7766fb12b70Safresh1      $! = EINPROGRESS;
7776fb12b70Safresh1      return 0;
7786fb12b70Safresh1   }
7796fb12b70Safresh1}
7806fb12b70Safresh1
7816fb12b70Safresh1sub connected
7826fb12b70Safresh1{
7836fb12b70Safresh1   my $self = shift;
7846fb12b70Safresh1   return defined $self->fileno &&
7856fb12b70Safresh1          !${*$self}{io_socket_ip_connect_in_progress} &&
7866fb12b70Safresh1          defined getpeername( $self ); # ->peername caches, we need to detect disconnection
7876fb12b70Safresh1}
7886fb12b70Safresh1
7896fb12b70Safresh1=head1 METHODS
7906fb12b70Safresh1
7916fb12b70Safresh1As well as the following methods, this class inherits all the methods in
7926fb12b70Safresh1L<IO::Socket> and L<IO::Handle>.
7936fb12b70Safresh1
7946fb12b70Safresh1=cut
7956fb12b70Safresh1
7966fb12b70Safresh1sub _get_host_service
7976fb12b70Safresh1{
7986fb12b70Safresh1   my $self = shift;
7996fb12b70Safresh1   my ( $addr, $flags, $xflags ) = @_;
8006fb12b70Safresh1
801b8851fccSafresh1   defined $addr or
802b8851fccSafresh1      $! = ENOTCONN, return;
803b8851fccSafresh1
8046fb12b70Safresh1   $flags |= NI_DGRAM if $self->socktype == SOCK_DGRAM;
8056fb12b70Safresh1
8066fb12b70Safresh1   my ( $err, $host, $service ) = getnameinfo( $addr, $flags, $xflags || 0 );
8076fb12b70Safresh1   croak "getnameinfo - $err" if $err;
8086fb12b70Safresh1
8096fb12b70Safresh1   return ( $host, $service );
8106fb12b70Safresh1}
8116fb12b70Safresh1
8126fb12b70Safresh1sub _unpack_sockaddr
8136fb12b70Safresh1{
8146fb12b70Safresh1   my ( $addr ) = @_;
8156fb12b70Safresh1   my $family = sockaddr_family $addr;
8166fb12b70Safresh1
8176fb12b70Safresh1   if( $family == AF_INET ) {
8186fb12b70Safresh1      return ( Socket::unpack_sockaddr_in( $addr ) )[1];
8196fb12b70Safresh1   }
8206fb12b70Safresh1   elsif( defined $AF_INET6 and $family == $AF_INET6 ) {
8216fb12b70Safresh1      return ( Socket::unpack_sockaddr_in6( $addr ) )[1];
8226fb12b70Safresh1   }
8236fb12b70Safresh1   else {
8246fb12b70Safresh1      croak "Unrecognised address family $family";
8256fb12b70Safresh1   }
8266fb12b70Safresh1}
8276fb12b70Safresh1
828eac174f2Safresh1=head2 sockhost_service
829eac174f2Safresh1
830eac174f2Safresh1   ( $host, $service ) = $sock->sockhost_service( $numeric )
8316fb12b70Safresh1
8326fb12b70Safresh1Returns the hostname and service name of the local address (that is, the
8336fb12b70Safresh1socket address given by the C<sockname> method).
8346fb12b70Safresh1
8356fb12b70Safresh1If C<$numeric> is true, these will be given in numeric form rather than being
8366fb12b70Safresh1resolved into names.
8376fb12b70Safresh1
8386fb12b70Safresh1The following four convenience wrappers may be used to obtain one of the two
8396fb12b70Safresh1values returned here. If both host and service names are required, this method
8406fb12b70Safresh1is preferable to the following wrappers, because it will call
8416fb12b70Safresh1C<getnameinfo(3)> only once.
8426fb12b70Safresh1
8436fb12b70Safresh1=cut
8446fb12b70Safresh1
8456fb12b70Safresh1sub sockhost_service
8466fb12b70Safresh1{
8476fb12b70Safresh1   my $self = shift;
8486fb12b70Safresh1   my ( $numeric ) = @_;
8496fb12b70Safresh1
8506fb12b70Safresh1   $self->_get_host_service( $self->sockname, $numeric ? NI_NUMERICHOST|NI_NUMERICSERV : 0 );
8516fb12b70Safresh1}
8526fb12b70Safresh1
853eac174f2Safresh1=head2 sockhost
854eac174f2Safresh1
855eac174f2Safresh1   $addr = $sock->sockhost
8566fb12b70Safresh1
8576fb12b70Safresh1Return the numeric form of the local address as a textual representation
8586fb12b70Safresh1
859eac174f2Safresh1=head2 sockport
860eac174f2Safresh1
861eac174f2Safresh1   $port = $sock->sockport
8626fb12b70Safresh1
8636fb12b70Safresh1Return the numeric form of the local port number
8646fb12b70Safresh1
865eac174f2Safresh1=head2 sockhostname
866eac174f2Safresh1
867eac174f2Safresh1   $host = $sock->sockhostname
8686fb12b70Safresh1
8696fb12b70Safresh1Return the resolved name of the local address
8706fb12b70Safresh1
871eac174f2Safresh1=head2 sockservice
872eac174f2Safresh1
873eac174f2Safresh1   $service = $sock->sockservice
8746fb12b70Safresh1
8756fb12b70Safresh1Return the resolved name of the local port number
8766fb12b70Safresh1
8776fb12b70Safresh1=cut
8786fb12b70Safresh1
879b8851fccSafresh1sub sockhost { my $self = shift; scalar +( $self->_get_host_service( $self->sockname, NI_NUMERICHOST, NIx_NOSERV ) )[0] }
880b8851fccSafresh1sub sockport { my $self = shift; scalar +( $self->_get_host_service( $self->sockname, NI_NUMERICSERV, NIx_NOHOST ) )[1] }
8816fb12b70Safresh1
882b8851fccSafresh1sub sockhostname { my $self = shift; scalar +( $self->_get_host_service( $self->sockname, 0, NIx_NOSERV ) )[0] }
883b8851fccSafresh1sub sockservice  { my $self = shift; scalar +( $self->_get_host_service( $self->sockname, 0, NIx_NOHOST ) )[1] }
8846fb12b70Safresh1
885eac174f2Safresh1=head2 sockaddr
886eac174f2Safresh1
887eac174f2Safresh1   $addr = $sock->sockaddr
8886fb12b70Safresh1
8896fb12b70Safresh1Return the local address as a binary octet string
8906fb12b70Safresh1
8916fb12b70Safresh1=cut
8926fb12b70Safresh1
8936fb12b70Safresh1sub sockaddr { my $self = shift; _unpack_sockaddr $self->sockname }
8946fb12b70Safresh1
895eac174f2Safresh1=head2 peerhost_service
896eac174f2Safresh1
897eac174f2Safresh1   ( $host, $service ) = $sock->peerhost_service( $numeric )
8986fb12b70Safresh1
8996fb12b70Safresh1Returns the hostname and service name of the peer address (that is, the
9006fb12b70Safresh1socket address given by the C<peername> method), similar to the
9016fb12b70Safresh1C<sockhost_service> method.
9026fb12b70Safresh1
9036fb12b70Safresh1The following four convenience wrappers may be used to obtain one of the two
9046fb12b70Safresh1values returned here. If both host and service names are required, this method
9056fb12b70Safresh1is preferable to the following wrappers, because it will call
9066fb12b70Safresh1C<getnameinfo(3)> only once.
9076fb12b70Safresh1
9086fb12b70Safresh1=cut
9096fb12b70Safresh1
9106fb12b70Safresh1sub peerhost_service
9116fb12b70Safresh1{
9126fb12b70Safresh1   my $self = shift;
9136fb12b70Safresh1   my ( $numeric ) = @_;
9146fb12b70Safresh1
9156fb12b70Safresh1   $self->_get_host_service( $self->peername, $numeric ? NI_NUMERICHOST|NI_NUMERICSERV : 0 );
9166fb12b70Safresh1}
9176fb12b70Safresh1
918eac174f2Safresh1=head2 peerhost
919eac174f2Safresh1
920eac174f2Safresh1   $addr = $sock->peerhost
9216fb12b70Safresh1
9226fb12b70Safresh1Return the numeric form of the peer address as a textual representation
9236fb12b70Safresh1
924eac174f2Safresh1=head2 peerport
925eac174f2Safresh1
926eac174f2Safresh1   $port = $sock->peerport
9276fb12b70Safresh1
9286fb12b70Safresh1Return the numeric form of the peer port number
9296fb12b70Safresh1
930eac174f2Safresh1=head2 peerhostname
931eac174f2Safresh1
932eac174f2Safresh1   $host = $sock->peerhostname
9336fb12b70Safresh1
9346fb12b70Safresh1Return the resolved name of the peer address
9356fb12b70Safresh1
936eac174f2Safresh1=head2 peerservice
937eac174f2Safresh1
938eac174f2Safresh1   $service = $sock->peerservice
9396fb12b70Safresh1
9406fb12b70Safresh1Return the resolved name of the peer port number
9416fb12b70Safresh1
9426fb12b70Safresh1=cut
9436fb12b70Safresh1
944b8851fccSafresh1sub peerhost { my $self = shift; scalar +( $self->_get_host_service( $self->peername, NI_NUMERICHOST, NIx_NOSERV ) )[0] }
945b8851fccSafresh1sub peerport { my $self = shift; scalar +( $self->_get_host_service( $self->peername, NI_NUMERICSERV, NIx_NOHOST ) )[1] }
9466fb12b70Safresh1
947b8851fccSafresh1sub peerhostname { my $self = shift; scalar +( $self->_get_host_service( $self->peername, 0, NIx_NOSERV ) )[0] }
948b8851fccSafresh1sub peerservice  { my $self = shift; scalar +( $self->_get_host_service( $self->peername, 0, NIx_NOHOST ) )[1] }
9496fb12b70Safresh1
950eac174f2Safresh1=head2 peeraddr
951eac174f2Safresh1
952eac174f2Safresh1   $addr = $peer->peeraddr
9536fb12b70Safresh1
9546fb12b70Safresh1Return the peer address as a binary octet string
9556fb12b70Safresh1
9566fb12b70Safresh1=cut
9576fb12b70Safresh1
9586fb12b70Safresh1sub peeraddr { my $self = shift; _unpack_sockaddr $self->peername }
9596fb12b70Safresh1
9606fb12b70Safresh1# This unbelievably dodgy hack works around the bug that IO::Socket doesn't do
9616fb12b70Safresh1# it
9626fb12b70Safresh1#    https://rt.cpan.org/Ticket/Display.html?id=61577
9636fb12b70Safresh1sub accept
9646fb12b70Safresh1{
9656fb12b70Safresh1   my $self = shift;
9666fb12b70Safresh1   my ( $new, $peer ) = $self->SUPER::accept( @_ ) or return;
9676fb12b70Safresh1
9686fb12b70Safresh1   ${*$new}{$_} = ${*$self}{$_} for qw( io_socket_domain io_socket_type io_socket_proto );
9696fb12b70Safresh1
9706fb12b70Safresh1   return wantarray ? ( $new, $peer )
9716fb12b70Safresh1                    : $new;
9726fb12b70Safresh1}
9736fb12b70Safresh1
9746fb12b70Safresh1# This second unbelievably dodgy hack guarantees that $self->fileno doesn't
9756fb12b70Safresh1# change, which is useful during nonblocking connect
976b8851fccSafresh1sub socket :method
9776fb12b70Safresh1{
9786fb12b70Safresh1   my $self = shift;
9796fb12b70Safresh1   return $self->SUPER::socket(@_) if not defined $self->fileno;
9806fb12b70Safresh1
9816fb12b70Safresh1   # I hate core prototypes sometimes...
982b8851fccSafresh1   socket( my $tmph, $_[0], $_[1], $_[2] ) or return undef;
9836fb12b70Safresh1
9846fb12b70Safresh1   dup2( $tmph->fileno, $self->fileno ) or die "Unable to dup2 $tmph onto $self - $!";
9856fb12b70Safresh1}
9866fb12b70Safresh1
9876fb12b70Safresh1# Versions of IO::Socket before 1.35 may leave socktype undef if from, say, an
9886fb12b70Safresh1#   ->fdopen call. In this case we'll apply a fix
9896fb12b70Safresh1BEGIN {
990b8851fccSafresh1   if( eval($IO::Socket::VERSION) < 1.35 ) {
9916fb12b70Safresh1      *socktype = sub {
9926fb12b70Safresh1         my $self = shift;
9936fb12b70Safresh1         my $type = $self->SUPER::socktype;
9946fb12b70Safresh1         if( !defined $type ) {
9956fb12b70Safresh1            $type = $self->sockopt( Socket::SO_TYPE() );
9966fb12b70Safresh1         }
9976fb12b70Safresh1         return $type;
9986fb12b70Safresh1      };
9996fb12b70Safresh1   }
10006fb12b70Safresh1}
10016fb12b70Safresh1
1002eac174f2Safresh1=head2 as_inet
1003eac174f2Safresh1
1004eac174f2Safresh1   $inet = $sock->as_inet
10056fb12b70Safresh1
10066fb12b70Safresh1Returns a new L<IO::Socket::INET> instance wrapping the same filehandle. This
10076fb12b70Safresh1may be useful in cases where it is required, for backward-compatibility, to
10086fb12b70Safresh1have a real object of C<IO::Socket::INET> type instead of C<IO::Socket::IP>.
10096fb12b70Safresh1The new object will wrap the same underlying socket filehandle as the
10106fb12b70Safresh1original, so care should be taken not to continue to use both objects
10116fb12b70Safresh1concurrently. Ideally the original C<$sock> should be discarded after this
10126fb12b70Safresh1method is called.
10136fb12b70Safresh1
10146fb12b70Safresh1This method checks that the socket domain is C<PF_INET> and will throw an
10156fb12b70Safresh1exception if it isn't.
10166fb12b70Safresh1
10176fb12b70Safresh1=cut
10186fb12b70Safresh1
10196fb12b70Safresh1sub as_inet
10206fb12b70Safresh1{
10216fb12b70Safresh1   my $self = shift;
10226fb12b70Safresh1   croak "Cannot downgrade a non-PF_INET socket to IO::Socket::INET" unless $self->sockdomain == AF_INET;
10236fb12b70Safresh1   return IO::Socket::INET->new_from_fd( $self->fileno, "r+" );
10246fb12b70Safresh1}
10256fb12b70Safresh1
10266fb12b70Safresh1=head1 NON-BLOCKING
10276fb12b70Safresh1
10286fb12b70Safresh1If the constructor is passed a defined but false value for the C<Blocking>
10296fb12b70Safresh1argument then the socket is put into non-blocking mode. When in non-blocking
10306fb12b70Safresh1mode, the socket will not be set up by the time the constructor returns,
10316fb12b70Safresh1because the underlying C<connect(2)> syscall would otherwise have to block.
10326fb12b70Safresh1
10336fb12b70Safresh1The non-blocking behaviour is an extension of the C<IO::Socket::INET> API,
10346fb12b70Safresh1unique to C<IO::Socket::IP>, because the former does not support multi-homed
10356fb12b70Safresh1non-blocking connect.
10366fb12b70Safresh1
10376fb12b70Safresh1When using non-blocking mode, the caller must repeatedly check for
10386fb12b70Safresh1writeability on the filehandle (for instance using C<select> or C<IO::Poll>).
10396fb12b70Safresh1Each time the filehandle is ready to write, the C<connect> method must be
10406fb12b70Safresh1called, with no arguments. Note that some operating systems, most notably
10416fb12b70Safresh1C<MSWin32> do not report a C<connect()> failure using write-ready; so you must
10426fb12b70Safresh1also C<select()> for exceptional status.
10436fb12b70Safresh1
10446fb12b70Safresh1While C<connect> returns false, the value of C<$!> indicates whether it should
10456fb12b70Safresh1be tried again (by being set to the value C<EINPROGRESS>, or C<EWOULDBLOCK> on
10466fb12b70Safresh1MSWin32), or whether a permanent error has occurred (e.g. C<ECONNREFUSED>).
10476fb12b70Safresh1
10486fb12b70Safresh1Once the socket has been connected to the peer, C<connect> will return true
10496fb12b70Safresh1and the socket will now be ready to use.
10506fb12b70Safresh1
10516fb12b70Safresh1Note that calls to the platform's underlying C<getaddrinfo(3)> function may
10526fb12b70Safresh1block. If C<IO::Socket::IP> has to perform this lookup, the constructor will
10536fb12b70Safresh1block even when in non-blocking mode.
10546fb12b70Safresh1
10556fb12b70Safresh1To avoid this blocking behaviour, the caller should pass in the result of such
10566fb12b70Safresh1a lookup using the C<PeerAddrInfo> or C<LocalAddrInfo> arguments. This can be
10576fb12b70Safresh1achieved by using L<Net::LibAsyncNS>, or the C<getaddrinfo(3)> function can be
10586fb12b70Safresh1called in a child process.
10596fb12b70Safresh1
10606fb12b70Safresh1   use IO::Socket::IP;
10616fb12b70Safresh1   use Errno qw( EINPROGRESS EWOULDBLOCK );
10626fb12b70Safresh1
10636fb12b70Safresh1   my @peeraddrinfo = ... # Caller must obtain the getaddinfo result here
10646fb12b70Safresh1
10656fb12b70Safresh1   my $socket = IO::Socket::IP->new(
10666fb12b70Safresh1      PeerAddrInfo => \@peeraddrinfo,
10676fb12b70Safresh1      Blocking     => 0,
10686fb12b70Safresh1   ) or die "Cannot construct socket - $@";
10696fb12b70Safresh1
10706fb12b70Safresh1   while( !$socket->connect and ( $! == EINPROGRESS || $! == EWOULDBLOCK ) ) {
10716fb12b70Safresh1      my $wvec = '';
10726fb12b70Safresh1      vec( $wvec, fileno $socket, 1 ) = 1;
10736fb12b70Safresh1      my $evec = '';
10746fb12b70Safresh1      vec( $evec, fileno $socket, 1 ) = 1;
10756fb12b70Safresh1
10766fb12b70Safresh1      select( undef, $wvec, $evec, undef ) or die "Cannot select - $!";
10776fb12b70Safresh1   }
10786fb12b70Safresh1
10796fb12b70Safresh1   die "Cannot connect - $!" if $!;
10806fb12b70Safresh1
10816fb12b70Safresh1   ...
10826fb12b70Safresh1
10836fb12b70Safresh1The example above uses C<select()>, but any similar mechanism should work
10846fb12b70Safresh1analogously. C<IO::Socket::IP> takes care when creating new socket filehandles
10856fb12b70Safresh1to preserve the actual file descriptor number, so such techniques as C<poll>
10866fb12b70Safresh1or C<epoll> should be transparent to its reallocation of a different socket
10876fb12b70Safresh1underneath, perhaps in order to switch protocol family between C<PF_INET> and
10886fb12b70Safresh1C<PF_INET6>.
10896fb12b70Safresh1
10906fb12b70Safresh1For another example using C<IO::Poll> and C<Net::LibAsyncNS>, see the
10916fb12b70Safresh1F<examples/nonblocking_libasyncns.pl> file in the module distribution.
10926fb12b70Safresh1
10936fb12b70Safresh1=cut
10946fb12b70Safresh1
10956fb12b70Safresh1=head1 C<PeerHost> AND C<LocalHost> PARSING
10966fb12b70Safresh1
10976fb12b70Safresh1To support the C<IO::Socket::INET> API, the host and port information may be
10986fb12b70Safresh1passed in a single string rather than as two separate arguments.
10996fb12b70Safresh1
11006fb12b70Safresh1If either C<LocalHost> or C<PeerHost> (or their C<...Addr> synonyms) have any
11016fb12b70Safresh1of the following special forms then special parsing is applied.
11026fb12b70Safresh1
11036fb12b70Safresh1The value of the C<...Host> argument will be split to give both the hostname
11046fb12b70Safresh1and port (or service name):
11056fb12b70Safresh1
11066fb12b70Safresh1   hostname.example.org:http    # Host name
11076fb12b70Safresh1   192.0.2.1:80                 # IPv4 address
11086fb12b70Safresh1   [2001:db8::1]:80             # IPv6 address
11096fb12b70Safresh1
11106fb12b70Safresh1In each case, the port or service name (e.g. C<80>) is passed as the
11116fb12b70Safresh1C<LocalService> or C<PeerService> argument.
11126fb12b70Safresh1
11136fb12b70Safresh1Either of C<LocalService> or C<PeerService> (or their C<...Port> synonyms) can
11146fb12b70Safresh1be either a service name, a decimal number, or a string containing both a
11156fb12b70Safresh1service name and number, in a form such as
11166fb12b70Safresh1
11176fb12b70Safresh1   http(80)
11186fb12b70Safresh1
11196fb12b70Safresh1In this case, the name (C<http>) will be tried first, but if the resolver does
11206fb12b70Safresh1not understand it then the port number (C<80>) will be used instead.
11216fb12b70Safresh1
11226fb12b70Safresh1If the C<...Host> argument is in this special form and the corresponding
11236fb12b70Safresh1C<...Service> or C<...Port> argument is also defined, the one parsed from
11246fb12b70Safresh1the C<...Host> argument will take precedence and the other will be ignored.
11256fb12b70Safresh1
1126eac174f2Safresh1=head2 split_addr
1127eac174f2Safresh1
1128eac174f2Safresh1   ( $host, $port ) = IO::Socket::IP->split_addr( $addr )
11296fb12b70Safresh1
11306fb12b70Safresh1Utility method that provides the parsing functionality described above.
11316fb12b70Safresh1Returns a 2-element list, containing either the split hostname and port
11326fb12b70Safresh1description if it could be parsed, or the given address and C<undef> if it was
11336fb12b70Safresh1not recognised.
11346fb12b70Safresh1
11356fb12b70Safresh1   IO::Socket::IP->split_addr( "hostname:http" )
11366fb12b70Safresh1                                # ( "hostname",  "http" )
11376fb12b70Safresh1
11386fb12b70Safresh1   IO::Socket::IP->split_addr( "192.0.2.1:80" )
11396fb12b70Safresh1                                # ( "192.0.2.1", "80"   )
11406fb12b70Safresh1
11416fb12b70Safresh1   IO::Socket::IP->split_addr( "[2001:db8::1]:80" )
11426fb12b70Safresh1                                # ( "2001:db8::1", "80" )
11436fb12b70Safresh1
11446fb12b70Safresh1   IO::Socket::IP->split_addr( "something.else" )
11456fb12b70Safresh1                                # ( "something.else", undef )
11466fb12b70Safresh1
11476fb12b70Safresh1=cut
11486fb12b70Safresh1
11496fb12b70Safresh1sub split_addr
11506fb12b70Safresh1{
11516fb12b70Safresh1   shift;
11526fb12b70Safresh1   my ( $addr ) = @_;
11536fb12b70Safresh1
11546fb12b70Safresh1   local ( $1, $2 ); # Placate a taint-related bug; [perl #67962]
11556fb12b70Safresh1   if( $addr =~ m/\A\[($IPv6_re)\](?::([^\s:]*))?\z/ or
11566fb12b70Safresh1       $addr =~ m/\A([^\s:]*):([^\s:]*)\z/ ) {
11576fb12b70Safresh1      return ( $1, $2 ) if defined $2 and length $2;
11586fb12b70Safresh1      return ( $1, undef );
11596fb12b70Safresh1   }
11606fb12b70Safresh1
11616fb12b70Safresh1   return ( $addr, undef );
11626fb12b70Safresh1}
11636fb12b70Safresh1
1164eac174f2Safresh1=head2 join_addr
1165eac174f2Safresh1
1166eac174f2Safresh1   $addr = IO::Socket::IP->join_addr( $host, $port )
11676fb12b70Safresh1
11686fb12b70Safresh1Utility method that performs the reverse of C<split_addr>, returning a string
11696fb12b70Safresh1formed by joining the specified host address and port number. The host address
11706fb12b70Safresh1will be wrapped in C<[]> brackets if required (because it is a raw IPv6
11716fb12b70Safresh1numeric address).
11726fb12b70Safresh1
11736fb12b70Safresh1This can be especially useful when combined with the C<sockhost_service> or
11746fb12b70Safresh1C<peerhost_service> methods.
11756fb12b70Safresh1
11766fb12b70Safresh1   say "Connected to ", IO::Socket::IP->join_addr( $sock->peerhost_service );
11776fb12b70Safresh1
11786fb12b70Safresh1=cut
11796fb12b70Safresh1
11806fb12b70Safresh1sub join_addr
11816fb12b70Safresh1{
11826fb12b70Safresh1   shift;
11836fb12b70Safresh1   my ( $host, $port ) = @_;
11846fb12b70Safresh1
11856fb12b70Safresh1   $host = "[$host]" if $host =~ m/:/;
11866fb12b70Safresh1
11876fb12b70Safresh1   return join ":", $host, $port if defined $port;
11886fb12b70Safresh1   return $host;
11896fb12b70Safresh1}
11906fb12b70Safresh1
11916fb12b70Safresh1# Since IO::Socket->new( Domain => ... ) will delete the Domain parameter
11926fb12b70Safresh1# before calling ->configure, we need to keep track of which it was
11936fb12b70Safresh1
11946fb12b70Safresh1package # hide from indexer
11956fb12b70Safresh1   IO::Socket::IP::_ForINET;
11966fb12b70Safresh1use base qw( IO::Socket::IP );
11976fb12b70Safresh1
11986fb12b70Safresh1sub configure
11996fb12b70Safresh1{
12006fb12b70Safresh1   # This is evil
12016fb12b70Safresh1   my $self = shift;
12026fb12b70Safresh1   my ( $arg ) = @_;
12036fb12b70Safresh1
12046fb12b70Safresh1   bless $self, "IO::Socket::IP";
12056fb12b70Safresh1   $self->configure( { %$arg, Family => Socket::AF_INET() } );
12066fb12b70Safresh1}
12076fb12b70Safresh1
12086fb12b70Safresh1package # hide from indexer
12096fb12b70Safresh1   IO::Socket::IP::_ForINET6;
12106fb12b70Safresh1use base qw( IO::Socket::IP );
12116fb12b70Safresh1
12126fb12b70Safresh1sub configure
12136fb12b70Safresh1{
12146fb12b70Safresh1   # This is evil
12156fb12b70Safresh1   my $self = shift;
12166fb12b70Safresh1   my ( $arg ) = @_;
12176fb12b70Safresh1
12186fb12b70Safresh1   bless $self, "IO::Socket::IP";
12196fb12b70Safresh1   $self->configure( { %$arg, Family => Socket::AF_INET6() } );
12206fb12b70Safresh1}
12216fb12b70Safresh1
12226fb12b70Safresh1=head1 C<IO::Socket::INET> INCOMPATIBILITES
12236fb12b70Safresh1
12246fb12b70Safresh1=over 4
12256fb12b70Safresh1
12266fb12b70Safresh1=item *
12276fb12b70Safresh1
12286fb12b70Safresh1The behaviour enabled by C<MultiHomed> is in fact implemented by
12296fb12b70Safresh1C<IO::Socket::IP> as it is required to correctly support searching for a
12306fb12b70Safresh1useable address from the results of the C<getaddrinfo(3)> call. The
12316fb12b70Safresh1constructor will ignore the value of this argument, except if it is defined
12326fb12b70Safresh1but false. An exception is thrown in this case, because that would request it
12336fb12b70Safresh1disable the C<getaddrinfo(3)> search behaviour in the first place.
12346fb12b70Safresh1
1235b8851fccSafresh1=item *
1236b8851fccSafresh1
1237b8851fccSafresh1C<IO::Socket::IP> implements both the C<Blocking> and C<Timeout> parameters,
1238b8851fccSafresh1but it implements the interaction of both in a different way.
1239b8851fccSafresh1
1240b8851fccSafresh1In C<::INET>, supplying a timeout overrides the non-blocking behaviour,
1241b8851fccSafresh1meaning that the C<connect()> operation will still block despite that the
1242b8851fccSafresh1caller asked for a non-blocking socket. This is not explicitly specified in
1243b8851fccSafresh1its documentation, nor does this author believe that is a useful behaviour -
1244b8851fccSafresh1it appears to come from a quirk of implementation.
1245b8851fccSafresh1
1246b8851fccSafresh1In C<::IP> therefore, the C<Blocking> parameter takes precedence - if a
1247b8851fccSafresh1non-blocking socket is requested, no operation will block. The C<Timeout>
1248b8851fccSafresh1parameter here simply defines the maximum time that a blocking C<connect()>
1249b8851fccSafresh1call will wait, if it blocks at all.
1250b8851fccSafresh1
1251b8851fccSafresh1In order to specifically obtain the "blocking connect then non-blocking send
1252b8851fccSafresh1and receive" behaviour of specifying this combination of options to C<::INET>
1253b8851fccSafresh1when using C<::IP>, perform first a blocking connect, then afterwards turn the
1254b8851fccSafresh1socket into nonblocking mode.
1255b8851fccSafresh1
1256b8851fccSafresh1   my $sock = IO::Socket::IP->new(
1257b8851fccSafresh1      PeerHost => $peer,
1258b8851fccSafresh1      Timeout => 20,
1259b8851fccSafresh1   ) or die "Cannot connect - $@";
1260b8851fccSafresh1
1261b8851fccSafresh1   $sock->blocking( 0 );
1262b8851fccSafresh1
1263b8851fccSafresh1This code will behave identically under both C<IO::Socket::INET> and
1264b8851fccSafresh1C<IO::Socket::IP>.
1265b8851fccSafresh1
12666fb12b70Safresh1=back
12676fb12b70Safresh1
12686fb12b70Safresh1=cut
12696fb12b70Safresh1
12706fb12b70Safresh1=head1 TODO
12716fb12b70Safresh1
12726fb12b70Safresh1=over 4
12736fb12b70Safresh1
12746fb12b70Safresh1=item *
12756fb12b70Safresh1
12766fb12b70Safresh1Investigate whether C<POSIX::dup2> upsets BSD's C<kqueue> watchers, and if so,
12776fb12b70Safresh1consider what possible workarounds might be applied.
12786fb12b70Safresh1
12796fb12b70Safresh1=back
12806fb12b70Safresh1
12816fb12b70Safresh1=head1 AUTHOR
12826fb12b70Safresh1
12836fb12b70Safresh1Paul Evans <leonerd@leonerd.org.uk>
12846fb12b70Safresh1
12856fb12b70Safresh1=cut
12866fb12b70Safresh1
12876fb12b70Safresh10x55AA;
1288