AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/DNS.pm view on Meta::CPAN
$self
}
# called to start asynchronous configuration
sub _config_begin {
++$_[0]{inhibit};
}
# called when done with async config
sub _config_done {
--$_[0]{inhibit};
$_[0]->_compile;
$_[0]->_scheduler;
}
=item $resolver->parse_resolv_conf ($string)
Parses the given string as if it were a F<resolv.conf> file. The following
directives are supported (but not necessarily implemented).
C<#>- and C<;>-style comments, C<nameserver>, C<domain>, C<search>, C<sortlist>,
C<options> (C<timeout>, C<attempts>, C<ndots>).
Everything else is silently ignored.
=cut
sub parse_resolv_conf {
my ($self, $resolvconf) = @_;
$self->{server} = [];
$self->{search} = [];
my $attempts;
for (split /\n/, $resolvconf) {
s/\s*[;#].*$//; # not quite legal, but many people insist
if (/^\s*nameserver\s+(\S+)\s*$/i) {
my $ip = $1;
if (my $ipn = AnyEvent::Socket::parse_address ($ip)) {
push @{ $self->{server} }, $ipn;
} else {
AE::log 5 => "nameserver $ip invalid and ignored, while parsing resolver config.";
}
} elsif (/^\s*domain\s+(\S*)\s*$/i) {
$self->{search} = [$1];
} elsif (/^\s*search\s+(.*?)\s*$/i) {
$self->{search} = [split /\s+/, $1];
} elsif (/^\s*sortlist\s+(.*?)\s*$/i) {
# ignored, NYI
} elsif (/^\s*options\s+(.*?)\s*$/i) {
for (split /\s+/, $1) {
if (/^timeout:(\d+)$/) {
$self->{timeout} = [$1];
} elsif (/^attempts:(\d+)$/) {
$attempts = $1;
} elsif (/^ndots:(\d+)$/) {
$self->{ndots} = $1;
} else {
# debug, rotate, no-check-names, inet6
}
}
} else {
# silently skip stuff we don't understand
}
}
$self->{timeout} = [($self->{timeout}[0]) x $attempts]
if $attempts;
$self->_compile;
}
sub _load_resolv_conf_file {
my ($self, $resolv_conf) = @_;
$self->_config_begin;
require AnyEvent::IO;
AnyEvent::IO::aio_load ($resolv_conf, sub {
if (my ($contents) = @_) {
$self->parse_resolv_conf ($contents);
} else {
AE::log 4 => "$resolv_conf: $!";
}
$self->_config_done;
});
}
=item $resolver->os_config
Tries so load and parse F</etc/resolv.conf> on portable operating
systems. Tries various egregious hacks on windows to force the DNS servers
and searchlist out of the system.
This method must be called at most once before trying to resolve anything.
=cut
sub os_config {
my ($self) = @_;
$self->_config_begin;
$self->{server} = [];
$self->{search} = [];
if ((AnyEvent::WIN32 || $^O =~ /cygwin/i)) {
# TODO: this blocks the program, but should not, but I
# am too lazy to implement and test it. need to boot windows. ugh.
#no strict 'refs';
# there are many options to find the current nameservers etc. on windows
# all of them don't work consistently:
# - the registry thing needs separate code on win32 native vs. cygwin
# - the registry layout differs between windows versions
# - calling windows api functions doesn't work on cygwin
# - ipconfig uses locale-specific messages
( run in 1.984 second using v1.01-cache-2.11-cpan-39bf76dae61 )