diff options
Diffstat (limited to 'Master/tlpkg/tlperl/lib/Socket.pm')
-rw-r--r-- | Master/tlpkg/tlperl/lib/Socket.pm | 1062 |
1 files changed, 664 insertions, 398 deletions
diff --git a/Master/tlpkg/tlperl/lib/Socket.pm b/Master/tlpkg/tlperl/lib/Socket.pm index aa3fe3fff80..e12d8517deb 100644 --- a/Master/tlpkg/tlperl/lib/Socket.pm +++ b/Master/tlpkg/tlperl/lib/Socket.pm @@ -1,242 +1,332 @@ package Socket; use strict; +{ use 5.006001; } -our($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); -$VERSION = "1.94"; +our $VERSION = '2.001'; =head1 NAME -Socket, sockaddr_in, sockaddr_un, inet_aton, inet_ntoa, inet_pton, inet_ntop - load the C socket.h defines and structure manipulators +C<Socket> - networking constants and support functions =head1 SYNOPSIS - use Socket; - - $proto = getprotobyname('udp'); - socket(Socket_Handle, PF_INET, SOCK_DGRAM, $proto); - $iaddr = gethostbyname('hishost.com'); - $port = getservbyname('time', 'udp'); - $sin = sockaddr_in($port, $iaddr); - send(Socket_Handle, 0, 0, $sin); - - $proto = getprotobyname('tcp'); - socket(Socket_Handle, PF_INET, SOCK_STREAM, $proto); - $port = getservbyname('smtp', 'tcp'); - $sin = sockaddr_in($port,inet_aton("127.1")); - $sin = sockaddr_in(7,inet_aton("localhost")); - $sin = sockaddr_in(7,INADDR_LOOPBACK); - connect(Socket_Handle,$sin); - - ($port, $iaddr) = sockaddr_in(getpeername(Socket_Handle)); - $peer_host = gethostbyaddr($iaddr, AF_INET); - $peer_addr = inet_ntoa($iaddr); - - $proto = getprotobyname('tcp'); - socket(Socket_Handle, PF_UNIX, SOCK_STREAM, $proto); - unlink('/var/run/usock'); - $sun = sockaddr_un('/var/run/usock'); - connect(Socket_Handle,$sun); +C<Socket> a low-level module used by, among other things, the L<IO::Socket> +family of modules. The following examples demonstrate some low-level uses but +a practical program would likely use the higher-level API provided by +C<IO::Socket> or similar instead. + + use Socket qw(PF_INET SOCK_STREAM pack_sockaddr_in inet_aton); + + socket(my $socket, PF_INET, SOCK_STREAM, 0) + or die "socket: $!"; + + my $port = getservbyname "echo", "tcp"; + connect($socket, pack_sockaddr_in($port, inet_aton("localhost"))) + or die "connect: $!"; + + print $socket "Hello, world!\n"; + print <$socket>; + +See also the L</EXAMPLES> section. =head1 DESCRIPTION -This module is just a translation of the C F<socket.h> file. -Unlike the old mechanism of requiring a translated F<socket.ph> -file, this uses the B<h2xs> program (see the Perl source distribution) -and your native C compiler. This means that it has a -far more likely chance of getting the numbers right. This includes -all of the commonly used pound-defines like AF_INET, SOCK_STREAM, etc. +This module provides a variety of constants, structure manipulators and other +functions related to socket-based networking. The values and functions +provided are useful when used in conjunction with Perl core functions such as +socket(), setsockopt() and bind(). It also provides several other support +functions, mostly for dealing with conversions of network addresses between +human-readable and native binary forms, and for hostname resolver operations. -Also, some common socket "newline" constants are provided: the -constants C<CR>, C<LF>, and C<CRLF>, as well as C<$CR>, C<$LF>, and -C<$CRLF>, which map to C<\015>, C<\012>, and C<\015\012>. If you do -not want to use the literal characters in your programs, then use -the constants provided here. They are not exported by default, but can -be imported individually, and with the C<:crlf> export tag: +Some constants and functions are exported by default by this module; but for +backward-compatibility any recently-added symbols are not exported by default +and must be requested explicitly. When an import list is provided to the +C<use Socket> line, the default exports are not automatically imported. It is +therefore best practice to always to explicitly list all the symbols required. - use Socket qw(:DEFAULT :crlf); +Also, some common socket "newline" constants are provided: the constants +C<CR>, C<LF>, and C<CRLF>, as well as C<$CR>, C<$LF>, and C<$CRLF>, which map +to C<\015>, C<\012>, and C<\015\012>. If you do not want to use the literal +characters in your programs, then use the constants provided here. They are +not exported by default, but can be imported individually, and with the +C<:crlf> export tag: -In addition, some structure manipulation functions are available: + use Socket qw(:DEFAULT :crlf); -=over 4 + $sock->print("GET / HTTP/1.0$CRLF"); -=item inet_aton HOSTNAME +The entire getaddrinfo() subsystem can be exported using the tag C<:addrinfo>; +this exports the getaddrinfo() and getnameinfo() functions, and all the +C<AI_*>, C<NI_*>, C<NIx_*> and C<EAI_*> constants. -Takes a string giving the name of a host, and translates that to an -opaque string (if programming in C, struct in_addr). Takes arguments -of both the 'rtfm.mit.edu' type and '18.181.0.24'. If the host name -cannot be resolved, returns undef. For multi-homed hosts (hosts with -more than one address), the first address found is returned. +=cut -For portability do not assume that the result of inet_aton() is 32 -bits wide, in other words, that it would contain only the IPv4 address -in network order. +=head1 CONSTANTS -=item inet_ntoa IP_ADDRESS +In each of the following groups, there may be many more constants provided +than just the ones given as examples in the section heading. If the heading +ends C<...> then this means there are likely more; the exact constants +provided will depend on the OS and headers found at compile-time. -Takes a string (an opaque string as returned by inet_aton(), -or a v-string representing the four octets of the IPv4 address in -network order) and translates it into a string of the form 'd.d.d.d' -where the 'd's are numbers less than 256 (the normal human-readable -four dotted number notation for Internet addresses). +=cut -=item INADDR_ANY +=head2 PF_INET, PF_INET6, PF_UNIX, ... -Note: does not return a number, but a packed string. +Protocol family constants to use as the first argument to socket() or the +value of the C<SO_DOMAIN> or C<SO_FAMILY> socket option. -Returns the 4-byte wildcard ip address which specifies any -of the hosts ip addresses. (A particular machine can have -more than one ip address, each address corresponding to -a particular network interface. This wildcard address -allows you to bind to all of them simultaneously.) -Normally equivalent to inet_aton('0.0.0.0'). +=head2 AF_INET, AF_INET6, AF_UNIX, ... -=item INADDR_BROADCAST +Address family constants used by the socket address structures, to pass to +such functions as inet_pton() or getaddrinfo(), or are returned by such +functions as sockaddr_family(). -Note: does not return a number, but a packed string. +=head2 SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, ... -Returns the 4-byte 'this-lan' ip broadcast address. -This can be useful for some protocols to solicit information -from all servers on the same LAN cable. -Normally equivalent to inet_aton('255.255.255.255'). +Socket type constants to use as the second argument to socket(), or the value +of the C<SO_TYPE> socket option. -=item INADDR_LOOPBACK +=head2 SOL_SOCKET -Note - does not return a number. +Socket option level constant for setsockopt() and getsockopt(). -Returns the 4-byte loopback address. Normally equivalent -to inet_aton('localhost'). +=head2 SO_ACCEPTCONN, SO_BROADCAST, SO_ERROR, ... -=item INADDR_NONE +Socket option name constants for setsockopt() and getsockopt() at the +C<SOL_SOCKET> level. -Note - does not return a number. +=head2 IP_OPTIONS, IP_TOS, IP_TTL, ... -Returns the 4-byte 'invalid' ip address. Normally equivalent -to inet_aton('255.255.255.255'). +Socket option name constants for IPv4 socket options at the C<IPPROTO_IP> +level. -=item IN6ADDR_ANY +=head2 MSG_BCAST, MSG_OOB, MSG_TRUNC, ... -Returns the 16-byte wildcard IPv6 address. Normally equivalent -to inet_pton(AF_INET6, "::") +Message flag constants for send() and recv(). -=item IN6ADDR_LOOPBACK +=head2 SHUT_RD, SHUT_RDWR, SHUT_WR -Returns the 16-byte loopback IPv6 address. Normally equivalent -to inet_pton(AF_INET6, "::1") +Direction constants for shutdown(). -=item sockaddr_family SOCKADDR +=head2 INADDR_ANY, INADDR_BROADCAST, INADDR_LOOPBACK, INADDR_NONE -Takes a sockaddr structure (as returned by pack_sockaddr_in(), -pack_sockaddr_un() or the perl builtin functions getsockname() and -getpeername()) and returns the address family tag. It will match the -constant AF_INET for a sockaddr_in and AF_UNIX for a sockaddr_un. It -can be used to figure out what unpacker to use for a sockaddr of -unknown type. +Constants giving the special C<AF_INET> addresses for wildcard, broadcast, +local loopback, and invalid addresses. + +Normally equivalent to inet_aton('0.0.0.0'), inet_aton('255.255.255.255'), +inet_aton('localhost') and inet_aton('255.255.255.255') respectively. + +=head2 IPPROTO_IP, IPPROTO_IPV6, IPPROTO_TCP, ... + +IP protocol constants to use as the third argument to socket(), the level +argument to getsockopt() or setsockopt(), or the value of the C<SO_PROTOCOL> +socket option. + +=head2 TCP_CORK, TCP_KEEPALIVE, TCP_NODELAY, ... + +Socket option name constants for TCP socket options at the C<IPPROTO_TCP> +level. + +=head2 IN6ADDR_ANY, IN6ADDR_LOOPBACK + +Constants giving the special C<AF_INET6> addresses for wildcard and local +loopback. + +Normally equivalent to inet_pton(AF_INET6, "::") and +inet_pton(AF_INET6, "::1") respectively. + +=head2 IPV6_ADD_MEMBERSHIP, IPV6_MTU, IPV6_V6ONLY, ... + +Socket option name constants for IPv6 socket options at the C<IPPROTO_IPV6> +level. + +=cut + +# Still undocumented: SCM_*, SOMAXCONN, IOV_MAX, UIO_MAXIOV + +=head1 STRUCTURE MANIPULATORS + +The following functions convert between lists of Perl values and packed binary +strings representing structures. + +=cut -=item sockaddr_in PORT, ADDRESS +=head2 $family = sockaddr_family $sockaddr -=item sockaddr_in SOCKADDR_IN +Takes a packed socket address (as returned by pack_sockaddr_in(), +pack_sockaddr_un() or the perl builtin functions getsockname() and +getpeername()). Returns the address family tag. This will be one of the +C<AF_*> constants, such as C<AF_INET> for a C<sockaddr_in> addresses or +C<AF_UNIX> for a C<sockaddr_un>. It can be used to figure out what unpack to +use for a sockaddr of unknown type. -In a list context, unpacks its SOCKADDR_IN argument and returns an array -consisting of (PORT, ADDRESS). In a scalar context, packs its (PORT, -ADDRESS) arguments as a SOCKADDR_IN and returns it. If this is confusing, -use pack_sockaddr_in() and unpack_sockaddr_in() explicitly. +=head2 $sockaddr = pack_sockaddr_in $port, $ip_address -=item pack_sockaddr_in PORT, IP_ADDRESS +Takes two arguments, a port number and an opaque string (as returned by +inet_aton(), or a v-string). Returns the C<sockaddr_in> structure with those +arguments packed in and C<AF_INET> filled in. For Internet domain sockets, +this structure is normally what you need for the arguments in bind(), +connect(), and send(). -Takes two arguments, a port number and an opaque string, IP_ADDRESS -(as returned by inet_aton(), or a v-string). Returns the sockaddr_in -structure with those arguments packed in with AF_INET filled in. For -Internet domain sockets, this structure is normally what you need for -the arguments in bind(), connect(), and send(), and is also returned -by getpeername(), getsockname() and recv(). +=head2 ($port, $ip_address) = unpack_sockaddr_in $sockaddr -=item unpack_sockaddr_in SOCKADDR_IN +Takes a C<sockaddr_in> structure (as returned by pack_sockaddr_in(), +getpeername() or recv()). Returns a list of two elements: the port and an +opaque string representing the IP address (you can use inet_ntoa() to convert +the address to the four-dotted numeric format). Will croak if the structure +does not represent an C<AF_INET> address. -Takes a sockaddr_in structure (as returned by pack_sockaddr_in()) and -returns an array of two elements: the port and an opaque string -representing the IP address (you can use inet_ntoa() to convert the -address to the four-dotted numeric format). Will croak if the -structure does not have AF_INET in the right place. +=head2 $sockaddr = sockaddr_in $port, $ip_address -=item sockaddr_in6 PORT, IP6_ADDRESS, [ SCOPE_ID, [ FLOWINFO ] ] +=head2 ($port, $ip_address) = sockaddr_in $sockaddr -=item sockaddr_in6 SOCKADDR_IN6 +A wrapper of pack_sockaddr_in() or unpack_sockaddr_in(). In list context, +unpacks its argument and returns a list consisting of the port and IP address. +In scalar context, packs its port and IP address arguments as a C<sockaddr_in> +and returns it. -In list context, unpacks its SOCKADDR_IN6 argument according to -unpack_sockaddr_in6(). In scalar context, packs its arguments according to -pack_sockaddr_in6(). +Provided largely for legacy compatibility; it is better to use +pack_sockaddr_in() or unpack_sockaddr_in() explicitly. -=item pack_sockaddr_in6 PORT, IP6_ADDRESS, [ SCOPE_ID, [ FLOWINFO ] ] +=head2 $sockaddr = pack_sockaddr_in6 $port, $ip6_address, [$scope_id, [$flowinfo]] Takes two to four arguments, a port number, an opaque string (as returned by inet_pton()), optionally a scope ID number, and optionally a flow label -number. Returns the sockaddr_in6 structure with those arguments packed in -with AF_INET6 filled in. IPv6 equivalent of pack_sockaddr_in(). +number. Returns the C<sockaddr_in6> structure with those arguments packed in +and C<AF_INET6> filled in. IPv6 equivalent of pack_sockaddr_in(). + +=head2 ($port, $ip6_address, $scope_id, $flowinfo) = unpack_sockaddr_in6 $sockaddr + +Takes a C<sockaddr_in6> structure. Returns a list of four elements: the port +number, an opaque string representing the IPv6 address, the scope ID, and the +flow label. (You can use inet_ntop() to convert the address to the usual +string format). Will croak if the structure does not represent an C<AF_INET6> +address. + +=head2 $sockaddr = sockaddr_in6 $port, $ip6_address, [$scope_id, [$flowinfo]] + +=head2 ($port, $ip6_address, $scope_id, $flowinfo) = sockaddr_in6 $sockaddr + +A wrapper of pack_sockaddr_in6() or unpack_sockaddr_in6(). In list context, +unpacks its argument according to unpack_sockaddr_in6(). In scalar context, +packs its arguments according to pack_sockaddr_in6(). -=item unpack_sockaddr_in6 SOCKADDR_IN6 +Provided largely for legacy compatibility; it is better to use +pack_sockaddr_in6() or unpack_sockaddr_in6() explicitly. -Takes a sockaddr_in6 structure (as returned by pack_sockaddr_in6()) and -returns an array of four elements: the port number, an opaque string -representing the IPv6 address, the scope ID, and the flow label. (You can -use inet_ntop() to convert the address to the usual string format). Will -croak if the structure does not have AF_INET6 in the right place. +=head2 $sockaddr = pack_sockaddr_un $path -=item sockaddr_un PATHNAME +Takes one argument, a pathname. Returns the C<sockaddr_un> structure with that +path packed in with C<AF_UNIX> filled in. For C<PF_UNIX> sockets, this +structure is normally what you need for the arguments in bind(), connect(), +and send(). -=item sockaddr_un SOCKADDR_UN +=head2 ($path) = unpack_sockaddr_un $sockaddr + +Takes a C<sockaddr_un> structure (as returned by pack_sockaddr_un(), +getpeername() or recv()). Returns a list of one element: the pathname. Will +croak if the structure does not represent an C<AF_UNIX> address. + +=head2 $sockaddr = sockaddr_un $path + +=head2 ($path) = sockaddr_un $sockaddr + +A wrapper of pack_sockaddr_un() or unpack_sockaddr_un(). In a list context, +unpacks its argument and returns a list consisting of the pathname. In a +scalar context, packs its pathname as a C<sockaddr_un> and returns it. + +Provided largely for legacy compatibility; it is better to use +pack_sockaddr_un() or unpack_sockaddr_un() explicitly. -In a list context, unpacks its SOCKADDR_UN argument and returns an array -consisting of (PATHNAME). In a scalar context, packs its PATHNAME -arguments as a SOCKADDR_UN and returns it. If this is confusing, use -pack_sockaddr_un() and unpack_sockaddr_un() explicitly. These are only supported if your system has E<lt>F<sys/un.h>E<gt>. -=item pack_sockaddr_un PATH +=head2 $ipv6_mreq = pack_ipv6_mreq $ip6_address, $ifindex + +Takes an IPv6 address and an interface number. Returns the C<ipv6_mreq> +structure with those arguments packed in. Suitable for use with the +C<IPV6_ADD_MEMBERSHIP> and C<IPV6_DROP_MEMBERSHIP> sockopts. + +=head2 ($ip6_address, $ifindex) = unpack_ipv6_mreq $ipv6_mreq + +Takes an C<ipv6_mreq> structure. Returns a list of two elements; the IPv6 +address and an interface number. + +=cut + +=head1 FUNCTIONS + +=cut + +=head2 $ip_address = inet_aton $string + +Takes a string giving the name of a host, or a textual representation of an IP +address and translates that to an packed binary address structure suitable to +pass to pack_sockaddr_in(). If passed a hostname that cannot be resolved, +returns C<undef>. For multi-homed hosts (hosts with more than one address), +the first address found is returned. + +For portability do not assume that the result of inet_aton() is 32 bits wide, +in other words, that it would contain only the IPv4 address in network order. + +This IPv4-only function is provided largely for legacy reasons. Newly-written +code should use getaddrinfo() or inet_pton() instead for IPv6 support. + +=head2 $string = inet_ntoa $ip_address + +Takes a packed binary address structure such as returned by +unpack_sockaddr_in() (or a v-string representing the four octets of the IPv4 +address in network order) and translates it into a string of the form +C<d.d.d.d> where the C<d>s are numbers less than 256 (the normal +human-readable four dotted number notation for Internet addresses). -Takes one argument, a pathname. Returns the sockaddr_un structure with -that path packed in with AF_UNIX filled in. For unix domain sockets, this -structure is normally what you need for the arguments in bind(), -connect(), and send(), and is also returned by getpeername(), -getsockname() and recv(). +This IPv4-only function is provided largely for legacy reasons. Newly-written +code should use getnameinfo() or inet_ntop() instead for IPv6 support. -=item unpack_sockaddr_un SOCKADDR_UN +=head2 $address = inet_pton $family, $string -Takes a sockaddr_un structure (as returned by pack_sockaddr_un()) -and returns the pathname. Will croak if the structure does not -have AF_UNIX in the right place. +Takes an address family (such as C<AF_INET> or C<AF_INET6>) and a string +containing a textual representation of an address in that family and +translates that to an packed binary address structure. -=item inet_pton ADDRESS_FAMILY, HOSTNAME +See also getaddrinfo() for a more powerful and flexible function to look up +socket addresses given hostnames or textual addresses. -Takes an address family, either AF_INET or AF_INET6, and a string giving -the name of a host, and translates that to an opaque string -(if programming in C, struct in_addr or struct in6_addr depending on the -address family passed in). The host string may be a string hostname, such -as 'www.perl.org', or an IP address. If using an IP address, the type of -IP address must be consistent with the address family passed into the function. +=head2 $string = inet_ntop $family, $address -This function is not exported by default. +Takes an address family and a packed binary address structure and translates +it into a human-readable textual representation of the address; typically in +C<d.d.d.d> form for C<AF_INET> or C<hhhh:hhhh::hhhh> form for C<AF_INET6>. -=item inet_ntop ADDRESS_FAMILY, IP_ADDRESS +See also getnameinfo() for a more powerful and flexible function to turn +socket addresses into human-readable textual representations. -Takes an address family, either AF_INET or AF_INET6, and a string -(an opaque string as returned by inet_aton() or inet_pton()) and -translates it to an IPv4 or IPv6 address string. +=head2 ($err, @result) = getaddrinfo $host, $service, [$hints] -This function is not exported by default. +Given both a hostname and service name, this function attempts to resolve the +host name into a list of network addresses, and the service name into a +protocol and port number, and then returns a list of address structures +suitable to connect() to it. -=item getaddrinfo HOST, SERVICE, [ HINTS ] +Given just a host name, this function attempts to resolve it to a list of +network addresses, and then returns a list of address structures giving these +addresses. -Given at least one of a hostname and a service name, returns a list of address -structures to listen on or connect to. HOST and SERVICE should be plain -strings (or a numerical port number for SERVICE). If present, HINTS should be -a reference to a HASH, where the following keys are recognised: +Given just a service name, this function attempts to resolve it to a protocol +and port number, and then returns a list of address structures that represent +it suitable to bind() to. This use should be combined with the C<AI_PASSIVE> +flag; see below. -=over 8 +Given neither name, it generates an error. + +If present, $hints should be a reference to a hash, where the following keys +are recognised: + +=over 4 =item flags => INT -A bitfield containing C<AI_*> constants +A bitfield containing C<AI_*> constants; see below. =item family => INT @@ -253,31 +343,33 @@ Restrict to only generating addresses for this protocol =back The return value will be a list; the first value being an error indication, -followed by a list of address structures (if no error occured). - - my ( $err, @results ) = getaddrinfo( ... ); +followed by a list of address structures (if no error occurred). The error value will be a dualvar; comparable to the C<EI_*> error constants, -or printable as a human-readable error message string. Each value in the -results list will be a HASH reference containing the following fields: +or printable as a human-readable error message string. If no error occurred it +will be zero numerically and an empty string. -=over 8 +Each value in the results list will be a hash reference containing the following +fields: + +=over 4 =item family => INT -The address family (e.g. AF_INET) +The address family (e.g. C<AF_INET>) =item socktype => INT -The socket type (e.g. SOCK_STREAM) +The socket type (e.g. C<SOCK_STREAM>) =item protocol => INT -The protocol (e.g. IPPROTO_TCP) +The protocol (e.g. C<IPPROTO_TCP>) =item addr => STRING -The address in a packed string (such as would be returned by pack_sockaddr_in) +The address in a packed string (such as would be returned by +pack_sockaddr_in()) =item canonname => STRING @@ -287,261 +379,390 @@ address. =back -=item getnameinfo ADDR, FLAGS +The following flag constants are recognised in the $hints hash. Other flag +constants may exist as provided by the OS. + +=over 4 + +=item AI_PASSIVE + +Indicates that this resolution is for a local bind() for a passive (i.e. +listening) socket, rather than an active (i.e. connecting) socket. + +=item AI_CANONNAME + +Indicates that the caller wishes the canonical hostname (C<canonname>) field +of the result to be filled in. + +=item AI_NUMERICHOST + +Indicates that the caller will pass a numeric address, rather than a hostname, +and that getaddrinfo() must not perform a resolve operation on this name. This +flag will prevent a possibly-slow network lookup operation, and instead return +an error if a hostname is passed. + +=back + +=head2 ($err, $hostname, $servicename) = getnameinfo $sockaddr, [$flags, [$xflags]] -Given a packed socket address (such as from C<getsockname>, C<getpeername>, or -returned by C<getaddrinfo> in a C<addr> field), returns the hostname and -symbolic service name it represents. FLAGS may be a bitmask of C<NI_*> +Given a packed socket address (such as from getsockname(), getpeername(), or +returned by getaddrinfo() in a C<addr> field), returns the hostname and +symbolic service name it represents. $flags may be a bitmask of C<NI_*> constants, or defaults to 0 if unspecified. The return value will be a list; the first value being an error condition, followed by the hostname and service name. - my ( $err, $host, $service ) = getnameinfo( ... ); - The error value will be a dualvar; comparable to the C<EI_*> error constants, or printable as a human-readable error message string. The host and service names will be plain strings. +The following flag constants are recognised as $flags. Other flag constants may +exist as provided by the OS. + +=over 4 + +=item NI_NUMERICHOST + +Requests that a human-readable string representation of the numeric address be +returned directly, rather than performing a name resolve operation that may +convert it into a hostname. This will also avoid potentially-blocking network +IO. + +=item NI_NUMERICSERV + +Requests that the port number be returned directly as a number representation +rather than performing a name resolve operation that may convert it into a +service name. + +=item NI_NAMEREQD + +If a name resolve operation fails to provide a name, then this flag will cause +getnameinfo() to indicate an error, rather than returning the numeric +representation as a human-readable string. + +=item NI_DGRAM + +Indicates that the socket address relates to a C<SOCK_DGRAM> socket, for the +services whose name differs between TCP and UDP protocols. + +=back + +The following constants may be supplied as $xflags. + +=over 4 + +=item NIx_NOHOST + +Indicates that the caller is not interested in the hostname of the result, so +it does not have to be converted. C<undef> will be returned as the hostname. + +=item NIx_NOSERV + +Indicates that the caller is not interested in the service name of the result, +so it does not have to be converted. C<undef> will be returned as the service +name. + +=back + +=head1 getaddrinfo() / getnameinfo() ERROR CONSTANTS + +The following constants may be returned by getaddrinfo() or getnameinfo(). +Others may be provided by the OS. + +=over 4 + +=item EAI_AGAIN + +A temporary failure occurred during name resolution. The operation may be +successful if it is retried later. + +=item EAI_BADFLAGS + +The value of the C<flags> hint to getaddrinfo(), or the $flags parameter to +getnameinfo() contains unrecognised flags. + +=item EAI_FAMILY + +The C<family> hint to getaddrinfo(), or the family of the socket address +passed to getnameinfo() is not supported. + +=item EAI_NODATA + +The host name supplied to getaddrinfo() did not provide any usable address +data. + +=item EAI_NONAME + +The host name supplied to getaddrinfo() does not exist, or the address +supplied to getnameinfo() is not associated with a host name and the +C<NI_NAMEREQD> flag was supplied. + +=item EAI_SERVICE + +The service name supplied to getaddrinfo() is not available for the socket +type given in the $hints. + =back =cut +=head1 EXAMPLES + +=head2 Lookup for connect() + +The getaddrinfo() function converts a hostname and a service name into a list +of structures, each containing a potential way to connect() to the named +service on the named host. + + use IO::Socket; + use Socket qw(SOCK_STREAM getaddrinfo); + + my %hints = (socktype => SOCK_STREAM); + my ($err, @res) = getaddrinfo("localhost", "echo", \%hints); + die "Cannot getaddrinfo - $err" if $err; + + my $sock; + + foreach my $ai (@res) { + my $candidate = IO::Socket->new(); + + $candidate->socket($ai->{family}, $ai->{socktype}, $ai->{protocol}) + or next; + + $candidate->connect($ai->{addr}) + or next; + + $sock = $candidate; + last; + } + + die "Cannot connect to localhost:echo" unless $sock; + + $sock->print("Hello, world!\n"); + print <$sock>; + +Because a list of potential candidates is returned, the C<while> loop tries +each in turn until it it finds one that succeeds both the socket() and +connect() calls. + +This function performs the work of the legacy functions gethostbyname(), +getservbyname(), inet_aton() and pack_sockaddr_in(). + +In practice this logic is better performed by L<IO::Socket::IP>. + +=head2 Making a human-readable string out of an address + +The getnameinfo() function converts a socket address, such as returned by +getsockname() or getpeername(), into a pair of human-readable strings +representing the address and service name. + + use IO::Socket::IP; + use Socket qw(getnameinfo); + + my $server = IO::Socket::IP->new(LocalPort => 12345, Listen => 1) or + die "Cannot listen - $@"; + + my $socket = $server->accept or die "accept: $!"; + + my ($err, $hostname, $servicename) = getnameinfo($socket->peername); + die "Cannot getnameinfo - $err" if $err; + + print "The peer is connected from $hostname\n"; + +Since in this example only the hostname was used, the redundant conversion of +the port number into a service name may be omitted by passing the +C<NIx_NOSERV> flag. + + use Socket qw(getnameinfo NIx_NOSERV); + + my ($err, $hostname) = getnameinfo($socket->peername, 0, NIx_NOSERV); + +This function performs the work of the legacy functions unpack_sockaddr_in(), +inet_ntoa(), gethostbyaddr() and getservbyport(). + +In practice this logic is better performed by L<IO::Socket::IP>. + +=head2 Resolving hostnames into IP addresses + +To turn a hostname into a human-readable plain IP address use getaddrinfo() +to turn the hostname into a list of socket structures, then getnameinfo() on +each one to make it a readable IP address again. + + use Socket qw(:addrinfo SOCK_RAW); + + my ($err, @res) = getaddrinfo($hostname, "", {socktype => SOCK_RAW}); + die "Cannot getaddrinfo - $err" if $err; + + while( my $ai = shift @res ) { + my ($err, $ipaddr) = getnameinfo($ai->{addr}, NI_NUMERICHOST, NIx_NOSERV); + die "Cannot getnameinfo - $err" if $err; + + print "$ipaddr\n"; + } + +The C<socktype> hint to getaddrinfo() filters the results to only include one +socket type and protocol. Without this most OSes return three combinations, +for C<SOCK_STREAM>, C<SOCK_DGRAM> and C<SOCK_RAW>, resulting in triplicate +output of addresses. The C<NI_NUMERICHOST> flag to getnameinfo() causes it to +return a string-formatted plain IP address, rather than reverse resolving it +back into a hostname. + +This combination performs the work of the legacy functions gethostbyname() +and inet_ntoa(). + +=head2 Accessing socket options + +The many C<SO_*> and other constants provide the socket option names for +getsockopt() and setsockopt(). + + use IO::Socket::INET; + use Socket qw(SOL_SOCKET SO_RCVBUF IPPROTO_IP IP_TTL); + + my $socket = IO::Socket::INET->new(LocalPort => 0, Proto => 'udp') + or die "Cannot create socket: $@"; + + $socket->setsockopt(SOL_SOCKET, SO_RCVBUF, 64*1024) or + die "setsockopt: $!"; + + print "Receive buffer is ", $socket->getsockopt(SOL_SOCKET, SO_RCVBUF), + " bytes\n"; + + print "IP TTL is ", $socket->getsockopt(IPPROTO_IP, IP_TTL), "\n"; + +As a convenience, L<IO::Socket>'s setsockopt() method will convert a number +into a packed byte buffer, and getsockopt() will unpack a byte buffer of the +correct size back into a number. + +=cut + +=head1 AUTHOR + +This module was originally maintained in Perl core by the Perl 5 Porters. + +It was extracted to dual-life on CPAN at version 1.95 by +Paul Evans <leonerd@leonerd.org.uk> + +=cut + use Carp; use warnings::register; require Exporter; require XSLoader; -@ISA = qw(Exporter); +our @ISA = qw(Exporter); # <@Nicholas> you can't change @EXPORT without breaking the implicit API # Please put any new constants in @EXPORT_OK! -@EXPORT = qw( - inet_aton inet_ntoa - sockaddr_family - pack_sockaddr_in unpack_sockaddr_in - pack_sockaddr_un unpack_sockaddr_un - pack_sockaddr_in6 unpack_sockaddr_in6 - sockaddr_in sockaddr_in6 sockaddr_un - INADDR_ANY INADDR_BROADCAST INADDR_LOOPBACK INADDR_NONE - AF_802 - AF_AAL - AF_APPLETALK - AF_CCITT - AF_CHAOS - AF_CTF - AF_DATAKIT - AF_DECnet - AF_DLI - AF_ECMA - AF_GOSIP - AF_HYLINK - AF_IMPLINK - AF_INET - AF_INET6 - AF_ISO - AF_KEY - AF_LAST - AF_LAT - AF_LINK - AF_MAX - AF_NBS - AF_NIT - AF_NS - AF_OSI - AF_OSINET - AF_PUP - AF_ROUTE - AF_SNA - AF_UNIX - AF_UNSPEC - AF_USER - AF_WAN - AF_X25 - IOV_MAX - IP_OPTIONS - IP_HDRINCL - IP_TOS - IP_TTL - IP_RECVOPTS - IP_RECVRETOPTS - IP_RETOPTS - MSG_BCAST - MSG_BTAG - MSG_CTLFLAGS - MSG_CTLIGNORE - MSG_CTRUNC - MSG_DONTROUTE - MSG_DONTWAIT - MSG_EOF - MSG_EOR - MSG_ERRQUEUE - MSG_ETAG - MSG_FIN - MSG_MAXIOVLEN - MSG_MCAST - MSG_NOSIGNAL - MSG_OOB - MSG_PEEK - MSG_PROXY - MSG_RST - MSG_SYN - MSG_TRUNC - MSG_URG - MSG_WAITALL - MSG_WIRE - PF_802 - PF_AAL - PF_APPLETALK - PF_CCITT - PF_CHAOS - PF_CTF - PF_DATAKIT - PF_DECnet - PF_DLI - PF_ECMA - PF_GOSIP - PF_HYLINK - PF_IMPLINK - PF_INET - PF_INET6 - PF_ISO - PF_KEY - PF_LAST - PF_LAT - PF_LINK - PF_MAX - PF_NBS - PF_NIT - PF_NS - PF_OSI - PF_OSINET - PF_PUP - PF_ROUTE - PF_SNA - PF_UNIX - PF_UNSPEC - PF_USER - PF_WAN + +# List re-ordered to match documentation above. Try to keep the ordering +# consistent so it's easier to see which ones are or aren't documented. +our @EXPORT = qw( + PF_802 PF_AAL PF_APPLETALK PF_CCITT PF_CHAOS PF_CTF PF_DATAKIT + PF_DECnet PF_DLI PF_ECMA PF_GOSIP PF_HYLINK PF_IMPLINK PF_INET PF_INET6 + PF_ISO PF_KEY PF_LAST PF_LAT PF_LINK PF_MAX PF_NBS PF_NIT PF_NS PF_OSI + PF_OSINET PF_PUP PF_ROUTE PF_SNA PF_UNIX PF_UNSPEC PF_USER PF_WAN PF_X25 - SCM_CONNECT - SCM_CREDENTIALS - SCM_CREDS - SCM_RIGHTS - SCM_TIMESTAMP - SHUT_RD - SHUT_RDWR - SHUT_WR - SOCK_DGRAM - SOCK_RAW - SOCK_RDM - SOCK_SEQPACKET - SOCK_STREAM + + AF_802 AF_AAL AF_APPLETALK AF_CCITT AF_CHAOS AF_CTF AF_DATAKIT + AF_DECnet AF_DLI AF_ECMA AF_GOSIP AF_HYLINK AF_IMPLINK AF_INET AF_INET6 + AF_ISO AF_KEY AF_LAST AF_LAT AF_LINK AF_MAX AF_NBS AF_NIT AF_NS AF_OSI + AF_OSINET AF_PUP AF_ROUTE AF_SNA AF_UNIX AF_UNSPEC AF_USER AF_WAN + AF_X25 + + SOCK_DGRAM SOCK_RAW SOCK_RDM SOCK_SEQPACKET SOCK_STREAM + SOL_SOCKET + + SO_ACCEPTCONN SO_ATTACH_FILTER SO_BACKLOG SO_BROADCAST SO_CHAMELEON + SO_DEBUG SO_DETACH_FILTER SO_DGRAM_ERRIND SO_DOMAIN SO_DONTLINGER + SO_DONTROUTE SO_ERROR SO_FAMILY SO_KEEPALIVE SO_LINGER SO_OOBINLINE + SO_PASSCRED SO_PASSIFNAME SO_PEERCRED SO_PROTOCOL SO_PROTOTYPE + SO_RCVBUF SO_RCVLOWAT SO_RCVTIMEO SO_REUSEADDR SO_REUSEPORT + SO_SECURITY_AUTHENTICATION SO_SECURITY_ENCRYPTION_NETWORK + SO_SECURITY_ENCRYPTION_TRANSPORT SO_SNDBUF SO_SNDLOWAT SO_SNDTIMEO + SO_STATE SO_TYPE SO_USELOOPBACK SO_XOPEN SO_XSE + + IP_OPTIONS IP_HDRINCL IP_TOS IP_TTL IP_RECVOPTS IP_RECVRETOPTS + IP_RETOPTS + + MSG_BCAST MSG_BTAG MSG_CTLFLAGS MSG_CTLIGNORE MSG_CTRUNC MSG_DONTROUTE + MSG_DONTWAIT MSG_EOF MSG_EOR MSG_ERRQUEUE MSG_ETAG MSG_FIN + MSG_MAXIOVLEN MSG_MCAST MSG_NOSIGNAL MSG_OOB MSG_PEEK MSG_PROXY MSG_RST + MSG_SYN MSG_TRUNC MSG_URG MSG_WAITALL MSG_WIRE + + SHUT_RD SHUT_RDWR SHUT_WR + + INADDR_ANY INADDR_BROADCAST INADDR_LOOPBACK INADDR_NONE + + SCM_CONNECT SCM_CREDENTIALS SCM_CREDS SCM_RIGHTS SCM_TIMESTAMP + SOMAXCONN - SO_ACCEPTCONN - SO_ATTACH_FILTER - SO_BACKLOG - SO_BROADCAST - SO_CHAMELEON - SO_DEBUG - SO_DETACH_FILTER - SO_DGRAM_ERRIND - SO_DONTLINGER - SO_DONTROUTE - SO_ERROR - SO_FAMILY - SO_KEEPALIVE - SO_LINGER - SO_OOBINLINE - SO_PASSCRED - SO_PASSIFNAME - SO_PEERCRED - SO_PROTOCOL - SO_PROTOTYPE - SO_RCVBUF - SO_RCVLOWAT - SO_RCVTIMEO - SO_REUSEADDR - SO_REUSEPORT - SO_SECURITY_AUTHENTICATION - SO_SECURITY_ENCRYPTION_NETWORK - SO_SECURITY_ENCRYPTION_TRANSPORT - SO_SNDBUF - SO_SNDLOWAT - SO_SNDTIMEO - SO_STATE - SO_TYPE - SO_USELOOPBACK - SO_XOPEN - SO_XSE + + IOV_MAX UIO_MAXIOV + + sockaddr_family + pack_sockaddr_in unpack_sockaddr_in sockaddr_in + pack_sockaddr_in6 unpack_sockaddr_in6 sockaddr_in6 + pack_sockaddr_un unpack_sockaddr_un sockaddr_un + + inet_aton inet_ntoa ); -@EXPORT_OK = qw(CR LF CRLF $CR $LF $CRLF - - inet_pton - inet_ntop - - getaddrinfo - getnameinfo - - IN6ADDR_ANY IN6ADDR_LOOPBACK - - AI_CANONNAME - AI_NUMERICHOST - AI_NUMERICSERV - AI_PASSIVE - - EAI_ADDRFAMILY - EAI_AGAIN - EAI_BADFLAGS - EAI_FAIL - EAI_FAMILY - EAI_NODATA - EAI_NONAME - EAI_SERVICE - EAI_SOCKTYPE - - IPPROTO_IP - IPPROTO_IPV6 - IPPROTO_RAW - IPPROTO_ICMP - IPPROTO_TCP - IPPROTO_UDP - - NI_DGRAM - NI_NAMEREQD - NI_NUMERICHOST - NI_NUMERICSERV - - TCP_KEEPALIVE - TCP_MAXRT - TCP_MAXSEG - TCP_NODELAY - TCP_STDURG - TCP_CORK - TCP_KEEPIDLE - TCP_KEEPINTVL - TCP_KEEPCNT - TCP_SYNCNT - TCP_LINGER2 - TCP_DEFER_ACCEPT - TCP_WINDOW_CLAMP - TCP_INFO - TCP_QUICKACK - TCP_CONGESTION - TCP_MD5SIG); - -%EXPORT_TAGS = ( - crlf => [qw(CR LF CRLF $CR $LF $CRLF)], - all => [@EXPORT, @EXPORT_OK], +# List re-ordered to match documentation above. Try to keep the ordering +# consistent so it's easier to see which ones are or aren't documented. +our @EXPORT_OK = qw( + CR LF CRLF $CR $LF $CRLF + + IPPROTO_IP IPPROTO_IPV6 IPPROTO_RAW IPPROTO_ICMP IPPROTO_TCP + IPPROTO_UDP + + TCP_CONGESTION TCP_CORK TCP_DEFER_ACCEPT TCP_INFO TCP_KEEPALIVE + TCP_KEEPCNT TCP_KEEPIDLE TCP_KEEPINTVL TCP_LINGER2 TCP_MAXRT TCP_MAXSEG + TCP_MD5SIG TCP_NODELAY TCP_QUICKACK TCP_STDURG TCP_SYNCNT + TCP_WINDOW_CLAMP + + IN6ADDR_ANY IN6ADDR_LOOPBACK + + IPV6_ADD_MEMBERSHIP IPV6_DROP_MEMBERSHIP IPV6_MTU IPV6_MTU_DISCOVER + IPV6_MULTICAST_HOPS IPV6_MULTICAST_IF IPV6_MULTICAST_LOOP + IPV6_UNICAST_HOPS IPV6_V6ONLY + + pack_ipv6_mreq unpack_ipv6_mreq + + inet_pton inet_ntop + + getaddrinfo getnameinfo + + AI_ADDRCONFIG AI_ALL AI_CANONIDN AI_CANONNAME AI_IDN + AI_IDN_ALLOW_UNASSIGNED AI_IDN_USE_STD3_ASCII_RULES AI_NUMERICHOST + AI_NUMERICSERV AI_PASSIVE AI_V4MAPPED + + NI_DGRAM NI_IDN NI_IDN_ALLOW_UNASSIGNED NI_IDN_USE_STD3_ASCII_RULES + NI_NAMEREQD NI_NOFQDN NI_NUMERICHOST NI_NUMERICSERV + + NIx_NOHOST NIx_NOSERV + + EAI_ADDRFAMILY EAI_AGAIN EAI_BADFLAGS EAI_BADHINTS EAI_FAIL EAI_FAMILY + EAI_NODATA EAI_NONAME EAI_PROTOCOL EAI_SERVICE EAI_SOCKTYPE EAI_SYSTEM +); + +our %EXPORT_TAGS = ( + crlf => [qw(CR LF CRLF $CR $LF $CRLF)], + addrinfo => [qw(getaddrinfo getnameinfo), grep m/^(?:AI|NI|NIx|EAI)_/, @EXPORT_OK], + all => [@EXPORT, @EXPORT_OK], ); BEGIN { sub CR () {"\015"} sub LF () {"\012"} sub CRLF () {"\015\012"} + + # These are not gni() constants; they're extensions for the perl API + # The definitions in Socket.pm and Socket.xs must match + sub NIx_NOHOST() {1 << 0} + sub NIx_NOSERV() {1 << 1} } *CR = \CR(); @@ -584,7 +805,7 @@ sub sockaddr_un { } } -XSLoader::load(); +XSLoader::load(__PACKAGE__, $VERSION); my %errstr; @@ -606,6 +827,9 @@ if( defined &getaddrinfo ) { AI_PASSIVE => 1, AI_CANONNAME => 2, AI_NUMERICHOST => 4, + AI_V4MAPPED => 8, + AI_ALL => 16, + AI_ADDRCONFIG => 32, # RFC 2553 doesn't define this but Linux does - lets be nice and # provide it since we can AI_NUMERICSERV => 1024, @@ -618,8 +842,25 @@ if( defined &getaddrinfo ) { NI_NUMERICHOST => 1, NI_NUMERICSERV => 2, + NI_NOFQDN => 4, NI_NAMEREQD => 8, NI_DGRAM => 16, + + # Constants we don't support. Export them, but croak if anyone tries to + # use them + AI_IDN => 64, + AI_CANONIDN => 128, + AI_IDN_ALLOW_UNASSIGNED => 256, + AI_IDN_USE_STD3_ASCII_RULES => 512, + NI_IDN => 32, + NI_IDN_ALLOW_UNASSIGNED => 64, + NI_IDN_USE_STD3_ASCII_RULES => 128, + + # Error constants we'll never return, so it doesn't matter what value + # these have, nor that we don't provide strings for them + EAI_SYSTEM => -11, + EAI_BADHINTS => -1000, + EAI_PROTOCOL => -1001 ); foreach my $name ( keys %constants ) { @@ -678,6 +919,14 @@ sub fake_getaddrinfo my $flag_numerichost = $flags & AI_NUMERICHOST(); $flags &= ~AI_NUMERICHOST(); my $flag_numericserv = $flags & AI_NUMERICSERV(); $flags &= ~AI_NUMERICSERV(); + # These constants don't apply to AF_INET-only lookups, so we might as well + # just ignore them. For AI_ADDRCONFIG we just presume the host has ability + # to talk AF_INET. If not we'd have to return no addresses at all. :) + $flags &= ~(AI_V4MAPPED()|AI_ALL()|AI_ADDRCONFIG()); + + $flags & (AI_IDN()|AI_CANONIDN()|AI_IDN_ALLOW_UNASSIGNED()|AI_IDN_USE_STD3_ASCII_RULES()) and + croak "Socket::getaddrinfo() does not support IDN"; + $flags == 0 or return fake_makeerr( EAI_BADFLAGS() ); $node eq "" and $service eq "" and return fake_makeerr( EAI_NONAME() ); @@ -757,7 +1006,7 @@ sub fake_getaddrinfo sub fake_getnameinfo { - my ( $addr, $flags ) = @_; + my ( $addr, $flags, $xflags ) = @_; my ( $port, $inetaddr ); eval { ( $port, $inetaddr ) = Socket::unpack_sockaddr_in( $addr ) } @@ -769,13 +1018,22 @@ sub fake_getnameinfo my $flag_numerichost = $flags & NI_NUMERICHOST(); $flags &= ~NI_NUMERICHOST(); my $flag_numericserv = $flags & NI_NUMERICSERV(); $flags &= ~NI_NUMERICSERV(); + my $flag_nofqdn = $flags & NI_NOFQDN(); $flags &= ~NI_NOFQDN(); my $flag_namereqd = $flags & NI_NAMEREQD(); $flags &= ~NI_NAMEREQD(); my $flag_dgram = $flags & NI_DGRAM() ; $flags &= ~NI_DGRAM(); + $flags & (NI_IDN()|NI_IDN_ALLOW_UNASSIGNED()|NI_IDN_USE_STD3_ASCII_RULES()) and + croak "Socket::getnameinfo() does not support IDN"; + $flags == 0 or return fake_makeerr( EAI_BADFLAGS() ); + $xflags ||= 0; + my $node; - if( $flag_numerichost ) { + if( $xflags & NIx_NOHOST ) { + $node = undef; + } + elsif( $flag_numerichost ) { $node = Socket::inet_ntoa( $inetaddr ); } else { @@ -784,10 +1042,18 @@ sub fake_getnameinfo return fake_makeerr( EAI_NONAME() ) if $flag_namereqd; $node = Socket::inet_ntoa( $inetaddr ); } + elsif( $flag_nofqdn ) { + my ( $shortname ) = split m/\./, $node; + my ( $fqdn ) = gethostbyname $shortname; + $node = $shortname if defined $fqdn and $fqdn eq $node; + } } my $service; - if( $flag_numericserv ) { + if( $xflags & NIx_NOSERV ) { + $service = undef; + } + elsif( $flag_numericserv ) { $service = "$port"; } else { |