Austin Moore
Austin Moore

Reputation: 1412

Device Name DNS Test

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

Answers (1)

ThisSuitIsBlackNot
ThisSuitIsBlackNot

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

Related Questions