Reputation: 1412
I am trying to write a Perl script that checks if the device's name exists in DNS and if it doesn't, it prints the device's name. Currently, this is how I do that:
my $host_result = `host $device`;
my @host_result = split(/ /, $host_result);
my $dns = $host_result[0];
# host normally puts out something like this if there is an error:
# Host blah not found: 3(NXDOMAIN)
# So I check to see if the first word is 'Host'
if ($dns eq "Host") {
print $device;
}
As you can see, I use the system's host
command to do this. More specifically, I check to see if host
can find the device's name or not.
I know that this is not the purpose of host
and I don't want to be using system calls unless I really have to, so I was hoping someone could point me towards a Perl module that allows me to check these device names against DNS. I'm guessing Net::DNS, but what specifically inside Net::DNS should I use to accomplish this?
I Googled around, but I'm having a hard time finding anything because I don't know what to look for (is it a DNS query? or DNS resolution?), because I only have a basic understanding of DNS and the terminology related to it.
Also, I'm passing in a lot of device names, so any tips on how to speed up the check are welcome!
Upvotes: 1
Views: 248
Reputation: 24083
I'm not very knowledgeable about DNS either, but I think this would be a rough equivalent to the host
approach using Net::DNS::Resolver:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Net::DNS::Resolver;
my $device = shift;
my $res = Net::DNS::Resolver->new;
say $device unless $res->search($device); # Returns undef if not found
In terms of speed, I did a simple benchmark and Net::DNS::Resolver is way faster than system("host $device")
if you reuse the same Resolver object for each query. Here are my timing results when the host is not in DNS:
Rate system Net::DNS
system 233/s -- -60%
Net::DNS 578/s 148% --
There's an even bigger difference when the host is in DNS:
Rate system Net::DNS
system 232/s -- -69%
Net::DNS 758/s 227% --
Here is the code I used for the benchmark:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Benchmark qw(cmpthese);
use Net::DNS::Resolver;
our $device = shift;
our $res = Net::DNS::Resolver->new;
cmpthese(1000, {
system => sub { system("host $device > /dev/null 2>&1"); },
'Net::DNS' => sub { $res->search($device); }
});
I also see that Net::DNS::Resolver has a function to run a query in the background and return immediately. If speed is really an issue, you could try sending your queries like this and forking a new process to check the results as soon as they're ready. Alternatively, you could just fork a process for each call to the normal foreground search()
function. Of course, depending on the number of hosts you're checking, be aware that you could run into memory or process limits with this approach.
Upvotes: 2