} elsif ($af == AF_UNIX) {
Socket::pack_sockaddr_un $_[0]
} else {
Carp::croak "pack_sockaddr: invalid host";
}
}
=item ($service, $host) = AnyEvent::Socket::unpack_sockaddr $sa
Unpack the given binary sockaddr structure (as used by bind, getpeername
etc.) into a C<$service, $host> combination.
For IPv4 and IPv6, C<$service> is the port number and C<$host> the host
address in network format (binary).
For UNIX domain sockets, C<$service> is the absolute pathname and C<$host>
is a special token that is understood by the other functions in this
module (C<format_address> converts it to C<unix/>).
=cut
sub unpack_sockaddr($) {
my $af = Socket::sockaddr_family $_[0];
if ($af == AF_INET) {
Socket::unpack_sockaddr_in $_[0]
} elsif ($af == AF_INET6) {
unpack "x2 n x4 a16", $_[0]
} elsif ($af == AF_UNIX) {
((Socket::unpack_sockaddr_un $_[0]), pack "S", AF_UNIX)
} else {
Carp::croak "unpack_sockaddr: unsupported protocol family $af";
}
}
=item resolve_sockaddr $node, $service, $proto, $family, $type, $cb->([$family, $type, $proto, $sockaddr], ...)
Tries to resolve the given nodename and service name into protocol families
and sockaddr structures usable to connect to this node and service in a
protocol-independent way. It works remotely similar to the getaddrinfo
posix function.
For internet addresses, C<$node> is either an IPv4 or IPv6 address or an
internet hostname, and C<$service> is either a service name (port name
from F</etc/services>) or a numerical port number. If both C<$node> and
C<$service> are names, then SRV records will be consulted to find the real
service, otherwise they will be used as-is. If you know that the service
name is not in your services database, then you can specify the service in
the format C<name=port> (e.g. C<http=80>).
For UNIX domain sockets, C<$node> must be the string C<unix/> and
C<$service> must be the absolute pathname of the socket. In this case,
C<$proto> will be ignored.
C<$proto> must be a protocol name, currently C<tcp>, C<udp> or
C<sctp>. The default is currently C<tcp>, but in the future, this function
might try to use other protocols such as C<sctp>, depending on the socket
type and any SRV records it might find.
C<$family> must be either C<0> (meaning any protocol is OK), C<4> (use
only IPv4) or C<6> (use only IPv6). This setting might be influenced by
C<$ENV{PERL_ANYEVENT_PROTOCOLS}>.
C<$type> must be C<SOCK_STREAM>, C<SOCK_DGRAM> or C<SOCK_SEQPACKET> (or
C<undef> in which case it gets automatically chosen).
The callback will receive zero or more array references that contain
C<$family, $type, $proto> for use in C<socket> and a binary
C<$sockaddr> for use in C<connect> (or C<bind>).
The application should try these in the order given.
Example:
resolve_sockaddr "google.com", "http", 0, undef, undef, sub { ... };
=cut
sub resolve_sockaddr($$$$$$) {
my ($node, $service, $proto, $family, $type, $cb) = @_;
if ($node eq "unix/") {
return $cb->() if $family || !/^\//; # no can do
return $cb->([AF_UNIX, $type, 0, Socket::pack_sockaddr_un $service]);
}
unless (AF_INET6) {
$family != 6
or return $cb->();
$family = 4;
}
$cb->() if $family == 4 && !$AnyEvent::PROTOCOL{ipv4};
$cb->() if $family == 6 && !$AnyEvent::PROTOCOL{ipv6};
$family ||= 4 unless $AnyEvent::PROTOCOL{ipv6};
$family ||= 6 unless $AnyEvent::PROTOCOL{ipv4};
=4= |