File Coverage

blib/lib/Net/DNS/Native.pm
Criterion Covered Total %
statement 71 71 100.0
branch 17 20 85.0
condition 11 18 61.1
subroutine 23 24 95.8
pod 7 7 100.0
total 129 140 92.1


line stmt bran cond sub pod time code
1             package Net::DNS::Native;
2              
3 5     5   198341 use strict;
  5         40  
  5         148  
4 5     5   24 use warnings;
  5         10  
  5         119  
5 5     5   29 use DynaLoader;
  5         6  
  5         174  
6 5     5   2736 use Socket ();
  5         17905  
  5         148  
7 5     5   2162 use Symbol ();
  5         3205  
  5         133  
8 5     5   2420 use POSIX ();
  5         32041  
  5         152  
9 5     5   37 use Config;
  5         8  
  5         665  
10              
11             our $VERSION = '0.19';
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     4615 !($Config{usethreads} || $Config{libs} =~ /-l?pthread\b/ || $Config{ldflags} =~ /-l?pthread\b/)
20 5     5   42 };
  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         1206 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   1683 my $sock = Symbol::gensym();
43 314         8843 tie *$sock, 'Net::DNS::Native::Handle', $_[1], $_[0];
44 314         1223 $sock;
45             }
46              
47             sub getaddrinfo {
48 233     233 1 288746 my $self = shift;
49 233         89683 _fd2socket $self, $self->_getaddrinfo($_[0], $_[1], $_[2], GETADDRINFO);
50             }
51              
52             sub inet_aton {
53 18     18 1 11712 my $self = shift;
54 18         1416 _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 291 my $self = shift;
59 18         1503 _fd2socket $self, $self->_getaddrinfo($_[1], undef, {family => $_[0], socktype => Socket::SOCK_STREAM}, INET_PTON);
60             }
61              
62             sub gethostbyname {
63 45     45 1 2091 my $self = shift;
64 45         3444 _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 12107 my ($self, $sock) = @_;
69            
70 317         811 my ($type, $err, @res) = $self->_get_result(fileno($sock));
71            
72 305         1428 tied(*$sock)->need_result(0);
73            
74 305 100       713 if ($type == GETADDRINFO) {
75 233         1237 return ($err, @res);
76             }
77            
78 72 100 100     558 if ($type == INET_ATON || $type == INET_PTON || (!wantarray() && $type == GETHOSTBYNAME)) {
      66        
      66        
79             return
80             $err ? undef :
81             ( $res[0]{family} == Socket::AF_INET ?
82             Socket::unpack_sockaddr_in($res[0]{addr}) :
83 66 100       546 Net::DNS::Native::unpack_sockaddr_in6($res[0]{addr}) )[1];
    100          
84             }
85            
86 6 50       24 if ($type == GETHOSTBYNAME) {
87             return
88             $err ? () :
89 6 100       27 ($res[0]{canonname}, undef, Socket::AF_INET, length($res[0]{addr}), map { (Socket::unpack_sockaddr_in($_->{addr}))[1] } @res);
  3         42  
90             }
91             }
92              
93             sub timedout {
94 9     9 1 1305 my ($self, $sock) = @_;
95            
96 9 50 33     75 return if defined ${^GLOBAL_PHASE} && ${^GLOBAL_PHASE} eq 'DESTRUCT';
97            
98 9 100       36 if (ref $sock) {
99 6         24 tied(*$sock)->need_result(0);
100 6         18 $sock = fileno $sock;
101             }
102            
103 9         66 $self->_timedout($sock);
104             }
105              
106             package Net::DNS::Native::Handle;
107              
108 5     5   38 use strict;
  5         13  
  5         136  
109 5     5   26 use warnings;
  5         10  
  5         1336  
110              
111             sub TIEHANDLE {
112 314     314   954 my ($class, $fd, $resolver) = @_;
113 314         1536 bless { fd => $fd, rs => $resolver, need_result => 1 }, $class;
114             }
115              
116             sub FILENO {
117 516     516   1141100 return $_[0]->{fd};
118             }
119              
120             sub READ {
121 249     249   38189 my $self = shift;
122 249         3593 POSIX::read( $self->{fd}, $_[0], $_[1] );
123             }
124              
125       0     sub CLOSE {}
126              
127             sub DESTROY {
128 314     314   84922 my $self = shift;
129            
130 314 50 66     549 if ($self->need_result && $self->{rs}) {
131 3         15 $self->{rs}->timedout($self->{fd});
132             }
133             }
134              
135             sub need_result {
136 625     625   954 my $self = shift;
137            
138 625 100       1323 unless (@_) {
139 314         1793 return $self->{need_result};
140             }
141            
142 311         668 $self->{need_result} = $_[0];
143             }
144              
145             1;
146              
147             __END__