File Coverage

blib/lib/Socket/More/Resolver/Worker.pm
Criterion Covered Total %
statement 116 132 87.8
branch 46 82 56.1
path n/a
condition 0 2 0.0
subroutine 14 14 100.0
pod n/a
total 176 230 76.5


line stmt bran path cond sub pod time code
1               package Socket::More::Resolver::Worker;
2 2       2   7112 use strict;
  2           4  
  2           60  
3 2       2   8 use warnings;
  2           2  
  2           88  
4 2       2   10 use feature "say";
  2           6  
  2           284  
5 2 50         214868 unless(caller){
6 2           18 $0="S::M::R::T";
7 2           6 my $gai_data_pack="l> l> l> l> l>/a* l>/a*";
8 2           4 my $gai_pack="($gai_data_pack)*";
9                
10               package main;
11 2       2   8 use feature "say";
  2           6  
  2           292  
12               #use POSIX ":sys_wait_h";
13               #use constant::more DEBUG=>0;
14               #use constant::more qw;
15               BEGIN {
16 2       2   8 *DEBUG=sub {0};
  71       71   610  
17 2       8   6 *CMD_GAI=sub {0};
  8           45  
18 2       6   4 *CMD_GNI=sub {1};
  6           48  
19 2       10   12 *CMD_SPAWN=sub {2};
  10           80  
20 2       4   6 *CMD_KILL=sub {3};
  4           23  
21 2       4   4 *CMD_REAP=sub {4};
  4           34  
22 2       2   1208 *WNOHANG=sub {1};
  2           38  
23               }
24                
25               # process any command line arguments for input and output FDs
26 2           4 my $run=1;
27 2           4 my @in_fds;
28               my @out_fds;
29 2           4 my $use_core=0;#=1;
30 2           8 while(@ARGV){
31 4           6 local $_=shift;
32 4 100         14 if(/--in/){
33 2           6 @in_fds=split ",", shift;
34 2           6 next;
35               }
36 2 50         6 if(/--out/){
37 2           6 @out_fds=split ",", shift;
38 2           4 next;
39               }
40               }
41              
42 2 50         6 DEBUG and say STDERR "TEMPLATE: ins: @in_fds";
43 2 50         6 DEBUG and say STDERR "TEMPLATE: outs: @out_fds";
44                
45               # Pipes back to the API
46               #
47 2 50         56 open my $in, "<&=$in_fds[0]" or die $!;
48 2 50         22 open my $out, ">&=$out_fds[0]" or die $!;
49               #$out->autoflush;
50                
51               #Simply loop over inputs and outputs
52 2 50         6 DEBUG and say STDERR "Worker waiting for line ...";
53 2           2 my $counter=0;
54 2           36 while(<$in>){
55                
56 10 50         74 DEBUG and say STDERR "Worker got line...";
57 10           151 $0="S::M::R::W-".$counter++;
58               #parse
59               # Host, port, hints
60 10           42 chomp;
61                
62 10           96 my $bin=pack "H*", $_;
63 10           74 my ($cmd, $req_id)=unpack "l> l>", $bin;
64 10           65 $bin=substr $bin, 8;
65                
66 10 50         26 DEBUG and say STDERR "WORKER $$ REQUEST, ID: $req_id";
67                
68 10           77 my $return_out=pack "l> l>", $cmd, $req_id;
69 10 100         78 if($cmd == CMD_SPAWN){
    100            
    100            
    50            
    50            
70               #Fork from me. Presumably the template
71 2           3496 my $pid=fork;
72 2 100         193 if($pid){
73               #Parent
74               # return message back to API with PID of offspring
75 1 50         90 DEBUG and say STDERR "FORKED WORKER... in parent child is $pid";
76 1           52 $return_out.=pack "l>", $pid;
77               }
78               else {
79               #child.
80                
81 1           68 $0="S::M::R::W";
82 1 50         49 DEBUG and say STDERR "FORKED WORKER... child with fds";
83 1           27 my ($in_fd, $out_fd)=unpack "l> l>", $bin;
84 1           92 close $in;
85 1           55 close $out;
86              
87 1 50         9 DEBUG and say STDERR "infd $in_fd, out_fd $out_fd";
88 1 50         134 open $in, "<&=$in_fd" or die $!;
89 1 50         66 open $out, ">&=$out_fd" or die $!;
90                
91 1           25526 next; #Do not respond.
92               }
93                
94               }
95               elsif($cmd== CMD_GAI){
96               #Assume a request
97 2           33 my @e =unpack $gai_pack, $bin;
98 2           10 my @results;
99 2           21 my $port=pop @e;
100 2           8 my $host=pop @e;
101 2 50         6 DEBUG and say STDERR "WORKER $$ PROCESSIG GAI REQUEST, id: $req_id";
102 2           5 my $rc;
103                
104                
105 2 50         7 if($use_core){
106 0           0 require Socket;
107 0           0 my %hints=@e;
108 0           0 ($rc, @results)=Socket::getaddrinfo($host, $port, \%hints);
109 0 0         0 if($rc){
110 0           0 my $a=[$rc+0, -1, -1, -1, "", ""];
111 0           0 $return_out.=pack($gai_data_pack, @$a);
112               }
113               else {
114 0           0 for(@results){
115 0     0     0 my $a=[$rc, $_->{family}, $_->{socktype}, $_->{protocol}, $_->{addr}, $_->{cannonname}//""];
116 0           0 $return_out.=pack($gai_data_pack, @$a);
117               }
118               }
119               }
120               else {
121 2       2   1042 use Data::Dumper;
  2           13158  
  2           322  
122 2           1883 require Socket::More::Lookup;
123 2 50         5547 DEBUG and say STDERR "host $host, port $port";
124 2           10457 $rc=Socket::More::Lookup::getaddrinfo($host, $port, \@e, \@results);
125 2 50         75 unless (defined $rc){
126 0           0 $results[0]=[$!, -1, -1, -1, "", ""];
127               }
128                
129 2           10 for(@results){
130 42           164 $return_out.=pack($gai_data_pack, @$_);
131               }
132               }
133 2       2   12 use Data::Dumper;
  2           2  
  2           3280  
134 2 50         9 DEBUG and say STDERR Dumper @results;
135               }
136                
137               elsif($cmd==CMD_GNI){
138 2 50         7 DEBUG and say STDERR "WORKER $$ PROCESSIG GNI REQUEST, id: $req_id";
139 2           24 my @e=unpack "l>/a* l>", $bin;
140 2 50         29 if($use_core){
141 0           0 require Socket;
142 0           0 my($rc, $host, $service)=Socket::getnameinfo(@e);
143 0           0 $return_out.=pack "l> l>/a* l>/a*",$rc, $host, $service;
144               }
145               else {
146 2           43 require Socket::More::Lookup;
147 2           7866 my $rc=Socket::More::Lookup::getnameinfo($e[0],my $host="", my $service="", $e[1]);
148                
149 2 50         17 DEBUG and say STDERR "worker side rc $rc";
150 2 50         9 DEBUG and say STDERR "worker side host $host";
151 2 50         7 DEBUG and say STDERR "worker side service Service $service";
152                
153 2 50         10 unless (defined $rc){
154 0           0 $return_out.=pack "l> l>/a* l>/a*",$!, $host, $service;
155                
156               }
157               else {
158                
159 2           20 $return_out.=pack "l> l>/a* l>/a*",0, $host, $service;
160               }
161               }
162               }
163                
164               elsif($cmd==CMD_KILL){
165               # worker needs to exit
166               #
167 0           0 $run=undef;
168               }
169               elsif($cmd==CMD_REAP){
170               #
171 4           41 my @pids=unpack "l>/l>*", $bin;
172 4 50         25 DEBUG and say STDERR "WORKER $$ REAP HANDLER @pids";
173 4           23 my @reaped;
174 4           53 for(@pids){
175 20           45 my $ret;
176 20 100         52 if($_){
177               # Only do the syscall if the pid is non zero
178 2           23 $ret=waitpid $_, WNOHANG;
179               }
180               else {
181 18           27 $ret=0;
182               }
183 20           44 push @reaped, $ret;
184               }
185 4 50         9 DEBUG and say STDERR "WORKER Reaped @reaped";
186 4           26 $return_out.=pack "l>/l>*", @reaped;
187               }
188                
189               else {
190 0           0 die "Unkown command";
191               }
192                
193 9 50         35 DEBUG and say STDERR "** BEFORE WORKER WRITE $$";
194 9 50         247 syswrite $out, unpack("H*", $return_out)."\n" or say $!;
195 9 50         45 DEBUG and say STDERR "** AFTER WORKER WRITE $$";
196                
197 9 50         1818446 last unless $run;
198               }
199                
200 2 50         28 DEBUG and say STDERR "** EXITING WORKER $$";
201               }
202                
203               1;