|
Packit Service |
64bc36 |
NAME
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
IO::Socket::IP - Family-neutral IP socket supporting both IPv4 and IPv6
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
SYNOPSIS
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
use IO::Socket::IP;
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
my $sock = IO::Socket::IP->new(
|
|
Packit Service |
64bc36 |
PeerHost => "www.google.com",
|
|
Packit Service |
64bc36 |
PeerPort => "http",
|
|
Packit Service |
64bc36 |
Type => SOCK_STREAM,
|
|
Packit Service |
64bc36 |
) or die "Cannot construct socket - $@";
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
my $familyname = ( $sock->sockdomain == PF_INET6 ) ? "IPv6" :
|
|
Packit Service |
64bc36 |
( $sock->sockdomain == PF_INET ) ? "IPv4" :
|
|
Packit Service |
64bc36 |
"unknown";
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
printf "Connected to google via %s\n", $familyname;
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
DESCRIPTION
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
This module provides a protocol-independent way to use IPv4 and IPv6
|
|
Packit Service |
64bc36 |
sockets, intended as a replacement for IO::Socket::INET. Most
|
|
Packit Service |
64bc36 |
constructor arguments and methods are provided in a backward-compatible
|
|
Packit Service |
64bc36 |
way. For a list of known differences, see the IO::Socket::INET
|
|
Packit Service |
64bc36 |
INCOMPATIBILITES section below.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
It uses the getaddrinfo(3) function to convert hostnames and service
|
|
Packit Service |
64bc36 |
names or port numbers into sets of possible addresses to connect to or
|
|
Packit Service |
64bc36 |
listen on. This allows it to work for IPv6 where the system supports
|
|
Packit Service |
64bc36 |
it, while still falling back to IPv4-only on systems which don't.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
REPLACING IO::Socket DEFAULT BEHAVIOUR
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
By placing -register in the import list, IO::Socket uses IO::Socket::IP
|
|
Packit Service |
64bc36 |
rather than IO::Socket::INET as the class that handles PF_INET.
|
|
Packit Service |
64bc36 |
IO::Socket will also use IO::Socket::IP rather than IO::Socket::INET6
|
|
Packit Service |
64bc36 |
to handle PF_INET6, provided that the AF_INET6 constant is available.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Changing IO::Socket's default behaviour means that calling the
|
|
Packit Service |
64bc36 |
IO::Socket constructor with either PF_INET or PF_INET6 as the Domain
|
|
Packit Service |
64bc36 |
parameter will yield an IO::Socket::IP object.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
use IO::Socket::IP -register;
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
my $sock = IO::Socket->new(
|
|
Packit Service |
64bc36 |
Domain => PF_INET6,
|
|
Packit Service |
64bc36 |
LocalHost => "::1",
|
|
Packit Service |
64bc36 |
Listen => 1,
|
|
Packit Service |
64bc36 |
) or die "Cannot create socket - $@\n";
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
print "Created a socket of type " . ref($sock) . "\n";
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Note that -register is a global setting that applies to the entire
|
|
Packit Service |
64bc36 |
program; it cannot be applied only for certain callers, removed, or
|
|
Packit Service |
64bc36 |
limited by lexical scope.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
CONSTRUCTORS
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$sock = IO::Socket::IP->new( %args )
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Creates a new IO::Socket::IP object, containing a newly created socket
|
|
Packit Service |
64bc36 |
handle according to the named arguments passed. The recognised
|
|
Packit Service |
64bc36 |
arguments are:
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
PeerHost => STRING
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
PeerService => STRING
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Hostname and service name for the peer to connect() to. The service
|
|
Packit Service |
64bc36 |
name may be given as a port number, as a decimal string.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
PeerAddr => STRING
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
PeerPort => STRING
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
For symmetry with the accessor methods and compatibility with
|
|
Packit Service |
64bc36 |
IO::Socket::INET, these are accepted as synonyms for PeerHost and
|
|
Packit Service |
64bc36 |
PeerService respectively.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
PeerAddrInfo => ARRAY
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Alternate form of specifying the peer to connect() to. This should be
|
|
Packit Service |
64bc36 |
an array of the form returned by Socket::getaddrinfo.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
This parameter takes precedence over the Peer*, Family, Type and
|
|
Packit Service |
64bc36 |
Proto arguments.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
LocalHost => STRING
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
LocalService => STRING
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Hostname and service name for the local address to bind() to.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
LocalAddr => STRING
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
LocalPort => STRING
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
For symmetry with the accessor methods and compatibility with
|
|
Packit Service |
64bc36 |
IO::Socket::INET, these are accepted as synonyms for LocalHost and
|
|
Packit Service |
64bc36 |
LocalService respectively.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
LocalAddrInfo => ARRAY
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Alternate form of specifying the local address to bind() to. This
|
|
Packit Service |
64bc36 |
should be an array of the form returned by Socket::getaddrinfo.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
This parameter takes precedence over the Local*, Family, Type and
|
|
Packit Service |
64bc36 |
Proto arguments.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Family => INT
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
The address family to pass to getaddrinfo (e.g. AF_INET, AF_INET6).
|
|
Packit Service |
64bc36 |
Normally this will be left undefined, and getaddrinfo will search
|
|
Packit Service |
64bc36 |
using any address family supported by the system.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Type => INT
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
The socket type to pass to getaddrinfo (e.g. SOCK_STREAM,
|
|
Packit Service |
64bc36 |
SOCK_DGRAM). Normally defined by the caller; if left undefined
|
|
Packit Service |
64bc36 |
getaddrinfo may attempt to infer the type from the service name.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Proto => STRING or INT
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
The IP protocol to use for the socket (e.g. 'tcp', IPPROTO_TCP,
|
|
Packit Service |
64bc36 |
'udp',IPPROTO_UDP). Normally this will be left undefined, and either
|
|
Packit Service |
64bc36 |
getaddrinfo or the kernel will choose an appropriate value. May be
|
|
Packit Service |
64bc36 |
given either in string name or numeric form.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
GetAddrInfoFlags => INT
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
More flags to pass to the getaddrinfo() function. If not supplied, a
|
|
Packit Service |
64bc36 |
default of AI_ADDRCONFIG will be used.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
These flags will be combined with AI_PASSIVE if the Listen argument
|
|
Packit Service |
64bc36 |
is given. For more information see the documentation about
|
|
Packit Service |
64bc36 |
getaddrinfo() in the Socket module.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Listen => INT
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If defined, puts the socket into listening mode where new connections
|
|
Packit Service |
64bc36 |
can be accepted using the accept method. The value given is used as
|
|
Packit Service |
64bc36 |
the listen(2) queue size.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
ReuseAddr => BOOL
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If true, set the SO_REUSEADDR sockopt
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
ReusePort => BOOL
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If true, set the SO_REUSEPORT sockopt (not all OSes implement this
|
|
Packit Service |
64bc36 |
sockopt)
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Broadcast => BOOL
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If true, set the SO_BROADCAST sockopt
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Sockopts => ARRAY
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
An optional array of other socket options to apply after the three
|
|
Packit Service |
64bc36 |
listed above. The value is an ARRAY containing 2- or 3-element
|
|
Packit Service |
64bc36 |
ARRAYrefs. Each inner array relates to a single option, giving the
|
|
Packit Service |
64bc36 |
level and option name, and an optional value. If the value element is
|
|
Packit Service |
64bc36 |
missing, it will be given the value of a platform-sized integer 1
|
|
Packit Service |
64bc36 |
constant (i.e. suitable to enable most of the common boolean
|
|
Packit Service |
64bc36 |
options).
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
For example, both options given below are equivalent to setting
|
|
Packit Service |
64bc36 |
ReuseAddr.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Sockopts => [
|
|
Packit Service |
64bc36 |
[ SOL_SOCKET, SO_REUSEADDR ],
|
|
Packit Service |
64bc36 |
[ SOL_SOCKET, SO_REUSEADDR, pack( "i", 1 ) ],
|
|
Packit Service |
64bc36 |
]
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
V6Only => BOOL
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If defined, set the IPV6_V6ONLY sockopt when creating PF_INET6
|
|
Packit Service |
64bc36 |
sockets to the given value. If true, a listening-mode socket will
|
|
Packit Service |
64bc36 |
only listen on the AF_INET6 addresses; if false it will also accept
|
|
Packit Service |
64bc36 |
connections from AF_INET addresses.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If not defined, the socket option will not be changed, and default
|
|
Packit Service |
64bc36 |
value set by the operating system will apply. For repeatable
|
|
Packit Service |
64bc36 |
behaviour across platforms it is recommended this value always be
|
|
Packit Service |
64bc36 |
defined for listening-mode sockets.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Note that not all platforms support disabling this option. Some, at
|
|
Packit Service |
64bc36 |
least OpenBSD and MirBSD, will fail with EINVAL if you attempt to
|
|
Packit Service |
64bc36 |
disable it. To determine whether it is possible to disable, you may
|
|
Packit Service |
64bc36 |
use the class method
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
if( IO::Socket::IP->CAN_DISABLE_V6ONLY ) {
|
|
Packit Service |
64bc36 |
...
|
|
Packit Service |
64bc36 |
}
|
|
Packit Service |
64bc36 |
else {
|
|
Packit Service |
64bc36 |
...
|
|
Packit Service |
64bc36 |
}
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If your platform does not support disabling this option but you still
|
|
Packit Service |
64bc36 |
want to listen for both AF_INET and AF_INET6 connections you will
|
|
Packit Service |
64bc36 |
have to create two listening sockets, one bound to each protocol.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
MultiHomed
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
This IO::Socket::INET-style argument is ignored, except if it is
|
|
Packit Service |
64bc36 |
defined but false. See the IO::Socket::INET INCOMPATIBILITES section
|
|
Packit Service |
64bc36 |
below.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
However, the behaviour it enables is always performed by
|
|
Packit Service |
64bc36 |
IO::Socket::IP.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Blocking => BOOL
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If defined but false, the socket will be set to non-blocking mode.
|
|
Packit Service |
64bc36 |
Otherwise it will default to blocking mode. See the NON-BLOCKING
|
|
Packit Service |
64bc36 |
section below for more detail.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Timeout => NUM
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If defined, gives a maximum time in seconds to block per connect()
|
|
Packit Service |
64bc36 |
call when in blocking mode. If missing, no timeout is applied other
|
|
Packit Service |
64bc36 |
than that provided by the underlying operating system. When in
|
|
Packit Service |
64bc36 |
non-blocking mode this parameter is ignored.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Note that if the hostname resolves to multiple address candidates,
|
|
Packit Service |
64bc36 |
the same timeout will apply to each connection attempt individually,
|
|
Packit Service |
64bc36 |
rather than to the operation as a whole. Further note that the
|
|
Packit Service |
64bc36 |
timeout does not apply to the initial hostname resolve operation, if
|
|
Packit Service |
64bc36 |
connecting by hostname.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
This behviour is copied inspired by IO::Socket::INET; for more fine
|
|
Packit Service |
64bc36 |
grained control over connection timeouts, consider performing a
|
|
Packit Service |
64bc36 |
nonblocking connect directly.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If neither Type nor Proto hints are provided, a default of SOCK_STREAM
|
|
Packit Service |
64bc36 |
and IPPROTO_TCP respectively will be set, to maintain compatibility
|
|
Packit Service |
64bc36 |
with IO::Socket::INET. Other named arguments that are not recognised
|
|
Packit Service |
64bc36 |
are ignored.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If neither Family nor any hosts or addresses are passed, nor any
|
|
Packit Service |
64bc36 |
*AddrInfo, then the constructor has no information on which to decide a
|
|
Packit Service |
64bc36 |
socket family to create. In this case, it performs a getaddinfo call
|
|
Packit Service |
64bc36 |
with the AI_ADDRCONFIG flag, no host name, and a service name of "0",
|
|
Packit Service |
64bc36 |
and uses the family of the first returned result.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If the constructor fails, it will set $@ to an appropriate error
|
|
Packit Service |
64bc36 |
message; this may be from $! or it may be some other string; not every
|
|
Packit Service |
64bc36 |
failure necessarily has an associated errno value.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$sock = IO::Socket::IP->new( $peeraddr )
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
As a special case, if the constructor is passed a single argument (as
|
|
Packit Service |
64bc36 |
opposed to an even-sized list of key/value pairs), it is taken to be
|
|
Packit Service |
64bc36 |
the value of the PeerAddr parameter. This is parsed in the same way,
|
|
Packit Service |
64bc36 |
according to the behaviour given in the PeerHost AND LocalHost PARSING
|
|
Packit Service |
64bc36 |
section below.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
METHODS
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
As well as the following methods, this class inherits all the methods
|
|
Packit Service |
64bc36 |
in IO::Socket and IO::Handle.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
( $host, $service ) = $sock->sockhost_service( $numeric )
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Returns the hostname and service name of the local address (that is,
|
|
Packit Service |
64bc36 |
the socket address given by the sockname method).
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If $numeric is true, these will be given in numeric form rather than
|
|
Packit Service |
64bc36 |
being resolved into names.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
The following four convenience wrappers may be used to obtain one of
|
|
Packit Service |
64bc36 |
the two values returned here. If both host and service names are
|
|
Packit Service |
64bc36 |
required, this method is preferable to the following wrappers, because
|
|
Packit Service |
64bc36 |
it will call getnameinfo(3) only once.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$addr = $sock->sockhost
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Return the numeric form of the local address as a textual
|
|
Packit Service |
64bc36 |
representation
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$port = $sock->sockport
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Return the numeric form of the local port number
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$host = $sock->sockhostname
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Return the resolved name of the local address
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$service = $sock->sockservice
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Return the resolved name of the local port number
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$addr = $sock->sockaddr
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Return the local address as a binary octet string
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
( $host, $service ) = $sock->peerhost_service( $numeric )
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Returns the hostname and service name of the peer address (that is, the
|
|
Packit Service |
64bc36 |
socket address given by the peername method), similar to the
|
|
Packit Service |
64bc36 |
sockhost_service method.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
The following four convenience wrappers may be used to obtain one of
|
|
Packit Service |
64bc36 |
the two values returned here. If both host and service names are
|
|
Packit Service |
64bc36 |
required, this method is preferable to the following wrappers, because
|
|
Packit Service |
64bc36 |
it will call getnameinfo(3) only once.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$addr = $sock->peerhost
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Return the numeric form of the peer address as a textual representation
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$port = $sock->peerport
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Return the numeric form of the peer port number
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$host = $sock->peerhostname
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Return the resolved name of the peer address
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$service = $sock->peerservice
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Return the resolved name of the peer port number
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$addr = $peer->peeraddr
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Return the peer address as a binary octet string
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$inet = $sock->as_inet
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Returns a new IO::Socket::INET instance wrapping the same filehandle.
|
|
Packit Service |
64bc36 |
This may be useful in cases where it is required, for
|
|
Packit Service |
64bc36 |
backward-compatibility, to have a real object of IO::Socket::INET type
|
|
Packit Service |
64bc36 |
instead of IO::Socket::IP. The new object will wrap the same underlying
|
|
Packit Service |
64bc36 |
socket filehandle as the original, so care should be taken not to
|
|
Packit Service |
64bc36 |
continue to use both objects concurrently. Ideally the original $sock
|
|
Packit Service |
64bc36 |
should be discarded after this method is called.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
This method checks that the socket domain is PF_INET and will throw an
|
|
Packit Service |
64bc36 |
exception if it isn't.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
NON-BLOCKING
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If the constructor is passed a defined but false value for the Blocking
|
|
Packit Service |
64bc36 |
argument then the socket is put into non-blocking mode. When in
|
|
Packit Service |
64bc36 |
non-blocking mode, the socket will not be set up by the time the
|
|
Packit Service |
64bc36 |
constructor returns, because the underlying connect(2) syscall would
|
|
Packit Service |
64bc36 |
otherwise have to block.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
The non-blocking behaviour is an extension of the IO::Socket::INET API,
|
|
Packit Service |
64bc36 |
unique to IO::Socket::IP, because the former does not support
|
|
Packit Service |
64bc36 |
multi-homed non-blocking connect.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
When using non-blocking mode, the caller must repeatedly check for
|
|
Packit Service |
64bc36 |
writeability on the filehandle (for instance using select or IO::Poll).
|
|
Packit Service |
64bc36 |
Each time the filehandle is ready to write, the connect method must be
|
|
Packit Service |
64bc36 |
called, with no arguments. Note that some operating systems, most
|
|
Packit Service |
64bc36 |
notably MSWin32 do not report a connect() failure using write-ready; so
|
|
Packit Service |
64bc36 |
you must also select() for exceptional status.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
While connect returns false, the value of $! indicates whether it
|
|
Packit Service |
64bc36 |
should be tried again (by being set to the value EINPROGRESS, or
|
|
Packit Service |
64bc36 |
EWOULDBLOCK on MSWin32), or whether a permanent error has occurred
|
|
Packit Service |
64bc36 |
(e.g. ECONNREFUSED).
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Once the socket has been connected to the peer, connect will return
|
|
Packit Service |
64bc36 |
true and the socket will now be ready to use.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Note that calls to the platform's underlying getaddrinfo(3) function
|
|
Packit Service |
64bc36 |
may block. If IO::Socket::IP has to perform this lookup, the
|
|
Packit Service |
64bc36 |
constructor will block even when in non-blocking mode.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
To avoid this blocking behaviour, the caller should pass in the result
|
|
Packit Service |
64bc36 |
of such a lookup using the PeerAddrInfo or LocalAddrInfo arguments.
|
|
Packit Service |
64bc36 |
This can be achieved by using Net::LibAsyncNS, or the getaddrinfo(3)
|
|
Packit Service |
64bc36 |
function can be called in a child process.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
use IO::Socket::IP;
|
|
Packit Service |
64bc36 |
use Errno qw( EINPROGRESS EWOULDBLOCK );
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
my @peeraddrinfo = ... # Caller must obtain the getaddinfo result here
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
my $socket = IO::Socket::IP->new(
|
|
Packit Service |
64bc36 |
PeerAddrInfo => \@peeraddrinfo,
|
|
Packit Service |
64bc36 |
Blocking => 0,
|
|
Packit Service |
64bc36 |
) or die "Cannot construct socket - $@";
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
while( !$socket->connect and ( $! == EINPROGRESS || $! == EWOULDBLOCK ) ) {
|
|
Packit Service |
64bc36 |
my $wvec = '';
|
|
Packit Service |
64bc36 |
vec( $wvec, fileno $socket, 1 ) = 1;
|
|
Packit Service |
64bc36 |
my $evec = '';
|
|
Packit Service |
64bc36 |
vec( $evec, fileno $socket, 1 ) = 1;
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
select( undef, $wvec, $evec, undef ) or die "Cannot select - $!";
|
|
Packit Service |
64bc36 |
}
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
die "Cannot connect - $!" if $!;
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
...
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
The example above uses select(), but any similar mechanism should work
|
|
Packit Service |
64bc36 |
analogously. IO::Socket::IP takes care when creating new socket
|
|
Packit Service |
64bc36 |
filehandles to preserve the actual file descriptor number, so such
|
|
Packit Service |
64bc36 |
techniques as poll or epoll should be transparent to its reallocation
|
|
Packit Service |
64bc36 |
of a different socket underneath, perhaps in order to switch protocol
|
|
Packit Service |
64bc36 |
family between PF_INET and PF_INET6.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
For another example using IO::Poll and Net::LibAsyncNS, see the
|
|
Packit Service |
64bc36 |
examples/nonblocking_libasyncns.pl file in the module distribution.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
PeerHost AND LocalHost PARSING
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
To support the IO::Socket::INET API, the host and port information may
|
|
Packit Service |
64bc36 |
be passed in a single string rather than as two separate arguments.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If either LocalHost or PeerHost (or their ...Addr synonyms) have any of
|
|
Packit Service |
64bc36 |
the following special forms then special parsing is applied.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
The value of the ...Host argument will be split to give both the
|
|
Packit Service |
64bc36 |
hostname and port (or service name):
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
hostname.example.org:http # Host name
|
|
Packit Service |
64bc36 |
192.0.2.1:80 # IPv4 address
|
|
Packit Service |
64bc36 |
[2001:db8::1]:80 # IPv6 address
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
In each case, the port or service name (e.g. 80) is passed as the
|
|
Packit Service |
64bc36 |
LocalService or PeerService argument.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Either of LocalService or PeerService (or their ...Port synonyms) can
|
|
Packit Service |
64bc36 |
be either a service name, a decimal number, or a string containing both
|
|
Packit Service |
64bc36 |
a service name and number, in a form such as
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
http(80)
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
In this case, the name (http) will be tried first, but if the resolver
|
|
Packit Service |
64bc36 |
does not understand it then the port number (80) will be used instead.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
If the ...Host argument is in this special form and the corresponding
|
|
Packit Service |
64bc36 |
...Service or ...Port argument is also defined, the one parsed from the
|
|
Packit Service |
64bc36 |
...Host argument will take precedence and the other will be ignored.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
( $host, $port ) = IO::Socket::IP->split_addr( $addr )
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Utility method that provides the parsing functionality described above.
|
|
Packit Service |
64bc36 |
Returns a 2-element list, containing either the split hostname and port
|
|
Packit Service |
64bc36 |
description if it could be parsed, or the given address and undef if it
|
|
Packit Service |
64bc36 |
was not recognised.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
IO::Socket::IP->split_addr( "hostname:http" )
|
|
Packit Service |
64bc36 |
# ( "hostname", "http" )
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
IO::Socket::IP->split_addr( "192.0.2.1:80" )
|
|
Packit Service |
64bc36 |
# ( "192.0.2.1", "80" )
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
IO::Socket::IP->split_addr( "[2001:db8::1]:80" )
|
|
Packit Service |
64bc36 |
# ( "2001:db8::1", "80" )
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
IO::Socket::IP->split_addr( "something.else" )
|
|
Packit Service |
64bc36 |
# ( "something.else", undef )
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$addr = IO::Socket::IP->join_addr( $host, $port )
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Utility method that performs the reverse of split_addr, returning a
|
|
Packit Service |
64bc36 |
string formed by joining the specified host address and port number.
|
|
Packit Service |
64bc36 |
The host address will be wrapped in [] brackets if required (because it
|
|
Packit Service |
64bc36 |
is a raw IPv6 numeric address).
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
This can be especially useful when combined with the sockhost_service
|
|
Packit Service |
64bc36 |
or peerhost_service methods.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
say "Connected to ", IO::Socket::IP->join_addr( $sock->peerhost_service );
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
IO::Socket::INET INCOMPATIBILITES
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
* The behaviour enabled by MultiHomed is in fact implemented by
|
|
Packit Service |
64bc36 |
IO::Socket::IP as it is required to correctly support searching for a
|
|
Packit Service |
64bc36 |
useable address from the results of the getaddrinfo(3) call. The
|
|
Packit Service |
64bc36 |
constructor will ignore the value of this argument, except if it is
|
|
Packit Service |
64bc36 |
defined but false. An exception is thrown in this case, because that
|
|
Packit Service |
64bc36 |
would request it disable the getaddrinfo(3) search behaviour in the
|
|
Packit Service |
64bc36 |
first place.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
* IO::Socket::IP implements both the Blocking and Timeout parameters,
|
|
Packit Service |
64bc36 |
but it implements the interaction of both in a different way.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
In ::INET, supplying a timeout overrides the non-blocking behaviour,
|
|
Packit Service |
64bc36 |
meaning that the connect() operation will still block despite that
|
|
Packit Service |
64bc36 |
the caller asked for a non-blocking socket. This is not explicitly
|
|
Packit Service |
64bc36 |
specified in its documentation, nor does this author believe that is
|
|
Packit Service |
64bc36 |
a useful behaviour - it appears to come from a quirk of
|
|
Packit Service |
64bc36 |
implementation.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
In ::IP therefore, the Blocking parameter takes precedence - if a
|
|
Packit Service |
64bc36 |
non-blocking socket is requested, no operation will block. The
|
|
Packit Service |
64bc36 |
Timeout parameter here simply defines the maximum time that a
|
|
Packit Service |
64bc36 |
blocking connect() call will wait, if it blocks at all.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
In order to specifically obtain the "blocking connect then
|
|
Packit Service |
64bc36 |
non-blocking send and receive" behaviour of specifying this
|
|
Packit Service |
64bc36 |
combination of options to ::INET when using ::IP, perform first a
|
|
Packit Service |
64bc36 |
blocking connect, then afterwards turn the socket into nonblocking
|
|
Packit Service |
64bc36 |
mode.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
my $sock = IO::Socket::IP->new(
|
|
Packit Service |
64bc36 |
PeerHost => $peer,
|
|
Packit Service |
64bc36 |
Timeout => 20,
|
|
Packit Service |
64bc36 |
) or die "Cannot connect - $@";
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
$sock->blocking( 0 );
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
This code will behave identically under both IO::Socket::INET and
|
|
Packit Service |
64bc36 |
IO::Socket::IP.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
TODO
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
* Investigate whether POSIX::dup2 upsets BSD's kqueue watchers, and
|
|
Packit Service |
64bc36 |
if so, consider what possible workarounds might be applied.
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
AUTHOR
|
|
Packit Service |
64bc36 |
|
|
Packit Service |
64bc36 |
Paul Evans <leonerd@leonerd.org.uk>
|
|
Packit Service |
64bc36 |
|