File Coverage

blib/lib/Net/DNS/Native.pm
Criterion Covered Total %
statement 68 71 95.7
branch 13 20 65.0
condition 10 18 55.5
subroutine 23 24 95.8
pod 7 7 100.0
total 121 140 86.4


line stmt bran cond sub pod time code
1             package Net::DNS::Native;
2              
3 5     5   169470 use strict;
  5         37  
  5         126  
4 5     5   20 use warnings;
  5         9  
  5         107  
5 5     5   20 use DynaLoader;
  5         10  
  5         127  
6 5     5   2336 use Socket ();
  5         14889  
  5         112  
7 5     5   1914 use Symbol ();
  5         2645  
  5         94  
8 5     5   2171 use POSIX ();
  5         27043  
  5         121  
9 5     5   25 use Config;
  5         10  
  5         525  
10              
11             our $VERSION = '0.22';
12              
13             use constant {
14             INET_ATON => 0,
15             INET_PTON => 1,
16             GETHOSTBYNAME => 2,
17             GETADDRINFO => 3,
18             NEED_RTLD_GLOBAL => $Config{osname} =~ /linux/i &&
19 5   33     3750 !($Config{usethreads} || $Config{libs} =~ /-l?pthread\b/ || $Config{ldflags} =~ /-l?pthread\b/)
20 5     5   29 };
  5         10  
21              
22             our @ISA = 'DynaLoader';
23             sub dl_load_flags {
24 5     5 1 15 if (NEED_RTLD_GLOBAL) {
25             return 0x01;
26             }
27            
28 5         1007 return 0;
29             }
30             DynaLoader::bootstrap('Net::DNS::Native');
31             if (NEED_RTLD_GLOBAL && &_is_non_safe_symbols_loaded) {
32             die sprintf(
33             "***********************************************************************
34             Some package defined non thread safe symbols which %s uses internally
35             Please make sure you are not placed loading of modules like IO::Socket::IP
36             before this one and not called functions like getaddrinfo(), gethostbyname(),
37             inet_aton() before loading of %s
38             ************************************************************************", __PACKAGE__, __PACKAGE__);
39             }
40              
41             sub _fd2socket($$) {
42 314     314   2184 my $sock = Symbol::gensym();
43 314         8373 tie *$sock, 'Net::DNS::Native::Handle', $_[1], $_[0];
44 314         1054 $sock;
45             }
46              
47             sub getaddrinfo {
48 233     233 1 291501 my $self = shift;
49 233         203057 _fd2socket $self, $self->_getaddrinfo($_[0], $_[1], $_[2], GETADDRINFO);
50             }
51              
52             sub inet_aton {
53 18     18 1 78732 my $self = shift;
54 18         1245 _fd2socket $self, $self->_getaddrinfo($_[0], undef, {family => Socket::AF_INET, socktype => Socket::SOCK_STREAM}, INET_ATON);
55             }
56              
57             sub inet_pton {
58 18     18 1 258 my $self = shift;
59 18         1479 _fd2socket $self, $self->_getaddrinfo($_[1], undef, {family => $_[0], socktype => Socket::SOCK_STREAM}, INET_PTON);
60             }
61              
62             sub gethostbyname {
63 45     45 1 167613 my $self = shift;
64 45         10437 _fd2socket $self, $self->_getaddrinfo($_[0], undef, {family => Socket::AF_INET, flags => Socket::AI_CANONNAME, socktype => Socket::SOCK_STREAM}, GETHOSTBYNAME);
65             }
66              
67             sub get_result {
68 317     317 1 9048 my ($self, $sock) = @_;
69            
70 317         695 my ($type, $err, @res) = $self->_get_result(fileno($sock));
71            
72 305         1264 tied(*$sock)->need_result(0);
73            
74 305 100       604 if ($type == GETADDRINFO) {
75 233         924 return ($err, @res);
76             }
77            
78 72 50 100     672 if ($type == INET_ATON || $type == INET_PTON || (!wantarray() && $type == GETHOSTBYNAME)) {
      33        
      66        
79             return
80             $err ? undef :
81             ( $res[0]{family} == Socket::AF_INET ?
82             Socket::unpack_sockaddr_in($res[0]{addr}) :
83 72 100       636 Net::DNS::Native::unpack_sockaddr_in6($res[0]{addr}) )[1];
    100          
84             }
85            
86 0 0       0 if ($type == GETHOSTBYNAME) {
87             return
88             $err ? () :
89 0 0       0 ($res[0]{canonname}, undef, Socket::AF_INET, length($res[0]{addr}), map { (Socket::unpack_sockaddr_in($_->{addr}))[1] } @res);
  0         0  
90             }
91             }
92              
93             sub timedout {
94 9     9 1 1146 my ($self, $sock) = @_;
95            
96 9 50 33     81 return if defined ${^GLOBAL_PHASE} && ${^GLOBAL_PHASE} eq 'DESTRUCT';
97            
98 9 100       36 if (ref $sock) {
99 6         27 tied(*$sock)->need_result(0);
100 6         21 $sock = fileno $sock;
101             }
102            
103 9         54 $self->_timedout($sock);
104             }
105              
106             package Net::DNS::Native::Handle;
107              
108 5     5   34 use strict;
  5         9  
  5         107  
109 5     5   21 use warnings;
  5         6  
  5         1168  
110              
111             sub TIEHANDLE {
112 314     314   725 my ($class, $fd, $resolver) = @_;
113 314         1261 bless { fd => $fd, rs => $resolver, need_result => 1 }, $class;
114             }
115              
116             sub FILENO {
117 516     516   1413861 return $_[0]->{fd};
118             }
119              
120             sub READ {
121 249     249   409235 my $self = shift;
122 249         14466 POSIX::read( $self->{fd}, $_[0], $_[1] );
123             }
124              
125       0     sub CLOSE {}
126              
127             sub DESTROY {
128 314     314   68069 my $self = shift;
129            
130 314 50 66     469 if ($self->need_result && $self->{rs}) {
131 3         18 $self->{rs}->timedout($self->{fd});
132             }
133             }
134              
135             sub need_result {
136 625     625   842 my $self = shift;
137            
138 625 100       1232 unless (@_) {
139 314         1595 return $self->{need_result};
140             }
141            
142 311         555 $self->{need_result} = $_[0];
143             }
144              
145             1;
146              
147             __END__