AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Socket.pm view on Meta::CPAN
unpack "x2 n x4 a16", $_[0]
} elsif ($af == AF_UNIX) {
((Socket::unpack_sockaddr_un $_[0] ^ $sa_un_zero), pack "S", AF_UNIX)
} else {
Carp::croak "unpack_sockaddr: unsupported protocol family $af";
}
}
=item AnyEvent::Socket::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, an
internet hostname (DNS domain name or IDN), 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>).
If a host cannot be found via DNS, then it will be looked up in
F</etc/hosts> (or the file specified via C<< $ENV{PERL_ANYEVENT_HOSTS}
>>). If they are found, the addresses there will be used. The effect is as
if entries from F</etc/hosts> would yield C<A> and C<AAAA> records for the
host name unless DNS already had records for them.
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). The default is 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 to be C<SOCK_STREAM>
unless C<$proto> is C<udp>).
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
our %HOSTS; # $HOSTS{$nodename}[$ipv6] = [@aliases...]
our @HOSTS_CHECKING; # callbacks to call when hosts have been loaded
our $HOSTS_MTIME;
sub _parse_hosts($) {
%HOSTS = ();
for (split /\n/, $_[0]) {
s/#.*$//;
s/^[ \t]+//;
y/A-Z/a-z/;
my ($addr, @aliases) = split /[ \t]+/;
next unless @aliases;
if (my $ip = parse_ipv4 $addr) {
($ip) = $ip =~ /^(.*)$/s if AnyEvent::TAINT;
push @{ $HOSTS{$_}[0] }, $ip
for @aliases;
} elsif (my $ip = parse_ipv6 $addr) {
($ip) = $ip =~ /^(.*)$/s if AnyEvent::TAINT;
push @{ $HOSTS{$_}[1] }, $ip
for @aliases;
}
}
}
# helper function - unless dns delivered results, check and parse hosts, then call continuation code
sub _load_hosts_unless(&$@) {
my ($cont, $cv, @dns) = @_;
if (@dns) {
$cv->end;
} else {
my $etc_hosts = length $ENV{PERL_ANYEVENT_HOSTS} ? $ENV{PERL_ANYEVENT_HOSTS}
: AnyEvent::WIN32 ? "$ENV{SystemRoot}/system32/drivers/etc/hosts"
: "/etc/hosts";
push @HOSTS_CHECKING, sub {
$cont->();
$cv->end;
};
unless ($#HOSTS_CHECKING) {
# we are not the first, so we actually have to do the work
require AnyEvent::IO;
AnyEvent::IO::aio_stat ($etc_hosts, sub {
if ((stat _)[9] ne $HOSTS_MTIME) {
AE::log 8 => "(re)loading $etc_hosts.";
$HOSTS_MTIME = (stat _)[9];
# we might load a newer version of hosts,but that's a harmless race,
# as the next call will just load it again.
AnyEvent::IO::aio_load ($etc_hosts, sub {
_parse_hosts $_[0];
(shift @HOSTS_CHECKING)->() while @HOSTS_CHECKING;
});
} else {
(shift @HOSTS_CHECKING)->() while @HOSTS_CHECKING;
}
});
}
( run in 0.617 second using v1.01-cache-2.11-cpan-39bf76dae61 )