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