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   229191 use strict;
  5         53  
  5         145  
4 5     5   25 use warnings;
  5         10  
  5         135  
5 5     5   29 use DynaLoader;
  5         10  
  5         191  
6 5     5   3119 use Socket ();
  5         19564  
  5         146  
7 5     5   2319 use Symbol ();
  5         3399  
  5         122  
8 5     5   2443 use POSIX ();
  5         34854  
  5         145  
9 5     5   35 use Config;
  5         8  
  5         726  
10              
11             our $VERSION = '0.20';
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     5240 !($Config{usethreads} || $Config{libs} =~ /-l?pthread\b/ || $Config{ldflags} =~ /-l?pthread\b/)
20 5     5   39 };
  5         9  
21              
22             our @ISA = 'DynaLoader';
23             sub dl_load_flags {
24 5     5 1 14 if (NEED_RTLD_GLOBAL) {
25             return 0x01;
26             }
27            
28 5         1266 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   1874 my $sock = Symbol::gensym();
43 314         9663 tie *$sock, 'Net::DNS::Native::Handle', $_[1], $_[0];
44 314         1288 $sock;
45             }
46              
47             sub getaddrinfo {
48 233     233 1 295300 my $self = shift;
49 233         48440 _fd2socket $self, $self->_getaddrinfo($_[0], $_[1], $_[2], GETADDRINFO);
50             }
51              
52             sub inet_aton {
53 18     18 1 27048 my $self = shift;
54 18         1653 _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 408 my $self = shift;
59 18         2298 _fd2socket $self, $self->_getaddrinfo($_[1], undef, {family => $_[0], socktype => Socket::SOCK_STREAM}, INET_PTON);
60             }
61              
62             sub gethostbyname {
63 45     45 1 2655 my $self = shift;
64 45         3750 _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 13245 my ($self, $sock) = @_;
69            
70 317         930 my ($type, $err, @res) = $self->_get_result(fileno($sock));
71            
72 305         1696 tied(*$sock)->need_result(0);
73            
74 305 100       799 if ($type == GETADDRINFO) {
75 233         1369 return ($err, @res);
76             }
77            
78 72 100 100     654 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       657 Net::DNS::Native::unpack_sockaddr_in6($res[0]{addr}) )[1];
    100          
84             }
85            
86 6 50       33 if ($type == GETHOSTBYNAME) {
87             return
88             $err ? () :
89 6 100       36 ($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 2418 my ($self, $sock) = @_;
95            
96 9 50 33     105 return if defined ${^GLOBAL_PHASE} && ${^GLOBAL_PHASE} eq 'DESTRUCT';
97            
98 9 100       45 if (ref $sock) {
99 6         36 tied(*$sock)->need_result(0);
100 6         60 $sock = fileno $sock;
101             }
102            
103 9         108 $self->_timedout($sock);
104             }
105              
106             package Net::DNS::Native::Handle;
107              
108 5     5   57 use strict;
  5         11  
  5         145  
109 5     5   26 use warnings;
  5         10  
  5         1391  
110              
111             sub TIEHANDLE {
112 314     314   928 my ($class, $fd, $resolver) = @_;
113 314         1595 bless { fd => $fd, rs => $resolver, need_result => 1 }, $class;
114             }
115              
116             sub FILENO {
117 516     516   828470 return $_[0]->{fd};
118             }
119              
120             sub READ {
121 249     249   45186 my $self = shift;
122 249         3955 POSIX::read( $self->{fd}, $_[0], $_[1] );
123             }
124              
125       0     sub CLOSE {}
126              
127             sub DESTROY {
128 314     314   91206 my $self = shift;
129            
130 314 50 66     592 if ($self->need_result && $self->{rs}) {
131 3         15 $self->{rs}->timedout($self->{fd});
132             }
133             }
134              
135             sub need_result {
136 625     625   1028 my $self = shift;
137            
138 625 100       1537 unless (@_) {
139 314         2051 return $self->{need_result};
140             }
141            
142 311         758 $self->{need_result} = $_[0];
143             }
144              
145             1;
146              
147             __END__