File Coverage

blib/lib/Net/DNSServer/Proxy.pm
Criterion Covered Total %
statement 27 65 41.5
branch 0 16 0.0
condition 0 7 0.0
subroutine 9 12 75.0
pod 2 2 100.0
total 38 102 37.2


line stmt bran cond sub pod time code
1             package Net::DNSServer::Proxy;
2              
3             # $Id: Proxy.pm,v 1.13 2002/11/13 19:57:24 rob Exp $
4             # This module simply forwards a request to another name server to do the work.
5              
6 1     1   600 use strict;
  1         1  
  1         35  
7 1     1   13 use Exporter;
  1         2  
  1         32  
8 1     1   4 use vars qw(@ISA $default_response_timeout);
  1         1  
  1         44  
9 1     1   482 use Net::DNSServer::Base;
  1         2  
  1         20  
10 1     1   4 use Net::DNS;
  1         2  
  1         77  
11 1     1   4 use Net::DNS::Packet;
  1         2  
  1         20  
12 1     1   653 use Net::Bind 0.03;
  1         6928  
  1         26  
13 1     1   6 use Carp qw(croak);
  1         3  
  1         38  
14 1     1   4 use IO::Socket;
  1         2  
  1         10  
15              
16             @ISA = qw(Net::DNSServer::Base);
17              
18             # Default timeout in seconds to wait for
19             # a response from real_dns_server.
20             $default_response_timeout = 5;
21              
22             # Created before calling Net::DNSServer->run()
23             sub new {
24 0   0 0 1   my $class = shift || __PACKAGE__;
25 0   0       my $self = shift || {};
26 0 0         if (! $self -> {real_dns_server} ) {
27             # Use the first nameserver in resolv.conf as default
28 0           my $res = Net::Bind::Resolv->new('/etc/resolv.conf');
29 0           ($self -> {real_dns_server}) = $res -> nameservers();
30             # XXX - This should probably cycle through all the
31             # nameserver entries until one successfully accepts.
32             }
33 0 0         $self -> {real_dns_server} = $1
34             if $self -> {real_dns_server} =~ /^([\d\.]+)$/;
35             # XXX - It should allow a way to override the port
36             # (like host:5353) instead of forcing to 53
37             # Initial "connect" to a remote resolver
38 0           my $that_server = IO::Socket::INET->new
39             (PeerAddr => $self->{real_dns_server},
40             PeerPort => "domain",
41             Proto => "udp");
42 0 0         unless ( $that_server ) {
43 0           croak "Remote dns server [$self->{real_dns_server}] is down.";
44             }
45 0           $self -> {that_server} = $that_server;
46 0   0       $self -> {patience} ||= $default_response_timeout;
47 0           return bless $self, $class;
48             }
49              
50             # Called after all pre methods have finished
51             # Returns a Net::DNS::Packet object as the answer
52             # or undef to pass to the next module to resolve
53             sub resolve {
54 0     0 1   my $self = shift;
55 0           my $dns_packet = $self -> {question};
56 0           my $response_data;
57 0           my $old_alarm = 0;
58 0           my $result_packet = undef;
59 0           $@ = "";
60 0           eval {
61             local $SIG{ALRM} = sub {
62 0     0     die "Got bored!\n";
63 0           };
64 0           $old_alarm = alarm ($self->{patience});
65 0 0         if (!$self -> {that_server} -> send($dns_packet->data)) {
66 0           die "send: $!\n";
67             }
68 0           while (1) {
69 0 0         if (!$self -> {that_server} -> recv($response_data,4096)) {
70 0           die "recv: $!\n";
71             }
72 0           $result_packet = Net::DNS::Packet->new(\$response_data);
73 0 0         if ($result_packet->header->id == $dns_packet->header->id) {
74 0           last;
75             }
76 0           $result_packet = undef;
77             }
78             };
79 0           alarm ($old_alarm);
80 0 0         if ($@) {
81 0 0         if ($@ =~ /bored/i) {
82 0           print STDERR "Warning: real_dns_server [$self->{real_dns_server}] did not respond after [$self->{patience}] seconds.\n";
83             } else {
84 0           print STDERR "Warning: Failed to proxy via real_dns_server [$self->{real_dns_server}]: $@";
85             }
86 0           return undef;
87             }
88 0           return $result_packet;
89             }
90              
91             1;
92             __END__