line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package FusionInventory::Agent::Task::Deploy::P2P; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
27170915
|
use strict; |
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
83
|
|
4
|
1
|
|
|
1
|
|
7
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
73
|
|
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
9
|
use English qw(-no_match_vars); |
|
1
|
|
|
|
|
34
|
|
|
1
|
|
|
|
|
21
|
|
7
|
1
|
|
|
1
|
|
2335
|
use HTTP::Request::Common qw(GET); |
|
1
|
|
|
|
|
35364
|
|
|
1
|
|
|
|
|
125
|
|
8
|
1
|
|
|
1
|
|
1053
|
use Net::IP; |
|
1
|
|
|
|
|
49552
|
|
|
1
|
|
|
|
|
196
|
|
9
|
1
|
|
|
1
|
|
601
|
use POE qw(Component::Client::TCP Component::Client::Ping); |
|
1
|
|
|
|
|
41683
|
|
|
1
|
|
|
|
|
8
|
|
10
|
|
|
|
|
|
|
|
11
|
1
|
|
|
1
|
|
100730
|
use UNIVERSAL::require; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
20
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# POE Debug |
14
|
|
|
|
|
|
|
#sub POE::Kernel::TRACE_REFCNT () { 1 } |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
my %cache = ( |
17
|
|
|
|
|
|
|
date => 0, |
18
|
|
|
|
|
|
|
data => undef |
19
|
|
|
|
|
|
|
); |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub _computeIPToTest { |
22
|
0
|
|
|
0
|
|
|
my ($logger, $addresses, $ipLimit) = @_; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
# Max number of IP to pick from a network range |
25
|
0
|
0
|
|
|
|
|
$ipLimit = 255 unless $ipLimit; |
26
|
|
|
|
|
|
|
|
27
|
0
|
|
|
|
|
|
my @ipToTest; |
28
|
0
|
|
|
|
|
|
foreach my $address (@$addresses) { |
29
|
0
|
|
|
|
|
|
my @ip_bytes = split(/\./, $address->{ip}); |
30
|
0
|
|
|
|
|
|
my @mask_bytes = split(/\./, $address->{mask}); |
31
|
0
|
0
|
|
|
|
|
next if $ip_bytes[0] == 127; # Ignore 127.x.x.x addresses |
32
|
0
|
0
|
|
|
|
|
next if $ip_bytes[0] == 169; # Ignore 169.x.x.x range too |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# compute range |
35
|
0
|
|
|
|
|
|
my @start; |
36
|
|
|
|
|
|
|
my @end; |
37
|
|
|
|
|
|
|
|
38
|
0
|
|
|
|
|
|
foreach my $idx (0..3) { |
39
|
|
|
|
|
|
|
## no critic (ProhibitBitwise) |
40
|
0
|
|
|
|
|
|
push @start, $ip_bytes[$idx] & (255 & $mask_bytes[$idx]); |
41
|
0
|
|
|
|
|
|
push @end, $ip_bytes[$idx] | (255 - $mask_bytes[$idx]); |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
0
|
|
|
|
|
|
my $ipStart = join('.', @start); |
45
|
0
|
|
|
|
|
|
my $ipEnd = join('.', @end); |
46
|
|
|
|
|
|
|
|
47
|
0
|
|
0
|
|
|
|
my $ipInterval = Net::IP->new($ipStart.' - '.$ipEnd) || die Net::IP::Error(); |
48
|
|
|
|
|
|
|
|
49
|
0
|
0
|
|
|
|
|
next if $ipStart eq $ipEnd; |
50
|
|
|
|
|
|
|
|
51
|
0
|
0
|
|
|
|
|
if ($ipInterval->size() > 5000) { |
52
|
0
|
|
|
|
|
|
$logger->debug("Range to large: ".$ipInterval->size()." (max 5000)"); |
53
|
0
|
|
|
|
|
|
next; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
0
|
|
|
|
|
|
my $after = 0; |
57
|
0
|
|
|
|
|
|
my @newIPs; |
58
|
0
|
|
0
|
|
|
|
do { |
59
|
0
|
|
|
|
|
|
push @newIPs, $ipInterval->ip(); |
60
|
0
|
0
|
0
|
|
|
|
if ($after || $address->{ip} eq $ipInterval->ip()) { |
|
|
0
|
|
|
|
|
|
61
|
0
|
|
|
|
|
|
$after++; |
62
|
|
|
|
|
|
|
} elsif (@newIPs > ($ipLimit / 2)) { |
63
|
0
|
|
|
|
|
|
shift @newIPs; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
} while (++$ipInterval && ($after < ($ipLimit / 2))); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
|
68
|
0
|
0
|
|
|
|
|
$logger->debug("Scanning from ".$newIPs[0]." to ".$newIPs[@newIPs-1]) if $logger; |
69
|
|
|
|
|
|
|
|
70
|
0
|
|
|
|
|
|
push @ipToTest, @newIPs; |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
} |
73
|
0
|
|
|
|
|
|
return @ipToTest; |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub fisher_yates_shuffle { |
78
|
0
|
|
|
0
|
0
|
|
my $deck = shift; # $deck is a reference to an array |
79
|
|
|
|
|
|
|
|
80
|
0
|
0
|
|
|
|
|
return unless @$deck; # must not be empty! |
81
|
|
|
|
|
|
|
|
82
|
0
|
|
|
|
|
|
my $i = @$deck; |
83
|
0
|
|
|
|
|
|
while (--$i) { |
84
|
0
|
|
|
|
|
|
my $j = int rand ($i+1); |
85
|
0
|
|
|
|
|
|
@$deck[$i,$j] = @$deck[$j,$i]; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub findPeer { |
90
|
0
|
|
|
0
|
0
|
|
my ( $port, $logger ) = @_; |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# $logger->debug("cachedate: ".$cache{date}); |
93
|
0
|
|
|
|
|
|
$logger->info("looking for a peer in the network"); |
94
|
0
|
0
|
|
|
|
|
return $cache{data} if $cache{date} + 600 > time; |
95
|
|
|
|
|
|
|
|
96
|
0
|
|
|
|
|
|
my @interfaces; |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
|
99
|
0
|
0
|
|
|
|
|
if ($OSNAME eq 'linux') { |
|
|
0
|
|
|
|
|
|
100
|
0
|
|
|
|
|
|
FusionInventory::Agent::Tools::Linux->require(); |
101
|
0
|
|
|
|
|
|
@interfaces = FusionInventory::Agent::Tools::Linux::getInterfacesFromIfconfig(); |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
} elsif ($OSNAME eq 'MSWin32') { |
104
|
0
|
|
|
|
|
|
FusionInventory::Agent::Tools::Win32->require(); |
105
|
0
|
|
|
|
|
|
@interfaces = FusionInventory::Agent::Tools::Win32::getInterfaces(); |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
|
109
|
0
|
|
|
|
|
|
my @addresses; |
110
|
|
|
|
|
|
|
|
111
|
0
|
|
|
|
|
|
foreach my $interface (@interfaces) { |
112
|
|
|
|
|
|
|
#if interface has both ip and netmask setup then push the address |
113
|
0
|
0
|
|
|
|
|
next unless $interface->{IPADDRESS}; |
114
|
0
|
0
|
|
|
|
|
next unless $interface->{IPMASK}; |
115
|
0
|
0
|
|
|
|
|
next unless lc($interface->{STATUS}) eq 'up'; |
116
|
0
|
0
|
|
|
|
|
next if $interface->{IPADDRESS} =~ /^127\./; |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
|
119
|
0
|
|
|
|
|
|
push @addresses, { |
120
|
|
|
|
|
|
|
ip => $interface->{IPADDRESS}, |
121
|
|
|
|
|
|
|
mask => $interface->{IPMASK} |
122
|
|
|
|
|
|
|
}; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
|
126
|
0
|
0
|
|
|
|
|
if (!@addresses) { |
127
|
0
|
|
|
|
|
|
$logger->info("No network to scan..."); |
128
|
0
|
|
|
|
|
|
return; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
0
|
|
|
|
|
|
$cache{date}=time; |
132
|
0
|
|
|
|
|
|
$cache{data}=scan({logger => $logger, port => $port}, _computeIPToTest($logger, \@addresses)); |
133
|
0
|
|
|
|
|
|
return $cache{data}; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub scan { |
138
|
0
|
|
|
0
|
0
|
|
my ($params, @ipToTestList) = @_; |
139
|
0
|
|
|
|
|
|
my $port = $params->{port}; |
140
|
0
|
|
|
|
|
|
my $logger = $params->{logger}; |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
|
143
|
0
|
|
|
|
|
|
fisher_yates_shuffle(\@ipToTestList); |
144
|
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
|
POE::Component::Client::Ping->spawn( |
146
|
|
|
|
|
|
|
Timeout => 5, # defaults to 1 second |
147
|
|
|
|
|
|
|
); |
148
|
|
|
|
|
|
|
|
149
|
0
|
|
|
|
|
|
my $ipCpt = int(@ipToTestList); |
150
|
0
|
|
|
|
|
|
my @ipFound; |
151
|
|
|
|
|
|
|
POE::Session->create( |
152
|
|
|
|
|
|
|
inline_states => { |
153
|
|
|
|
|
|
|
_start => sub { |
154
|
0
|
|
|
0
|
|
|
$_[HEAP]->{shutdown_on_error}=1; |
155
|
0
|
|
|
|
|
|
$_[KERNEL]->yield( "add", 0 ); |
156
|
|
|
|
|
|
|
}, |
157
|
|
|
|
|
|
|
add => sub { |
158
|
0
|
|
|
0
|
|
|
my $ipToTest = shift @ipToTestList; |
159
|
|
|
|
|
|
|
|
160
|
0
|
0
|
|
|
|
|
return unless $ipToTest; |
161
|
|
|
|
|
|
|
|
162
|
0
|
|
|
|
|
|
print "."; |
163
|
|
|
|
|
|
|
|
164
|
0
|
|
|
|
|
|
$_[KERNEL]->post( |
165
|
|
|
|
|
|
|
"pinger", # Post the request to the "pingthing" component. |
166
|
|
|
|
|
|
|
"ping", # Ask it to "ping" an address. |
167
|
|
|
|
|
|
|
"pong", # Have it post an answer as a "pong" event. |
168
|
|
|
|
|
|
|
$ipToTest, # This is the address we want to ping. |
169
|
|
|
|
|
|
|
); |
170
|
|
|
|
|
|
|
|
171
|
0
|
0
|
0
|
|
|
|
if (@ipToTestList && @ipFound < 30) { |
172
|
0
|
|
|
|
|
|
$_[KERNEL]->delay(add => 0.1) |
173
|
|
|
|
|
|
|
} else { |
174
|
0
|
|
|
|
|
|
$_[KERNEL]->yield("shutdown"); |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
}, |
179
|
|
|
|
|
|
|
pong => sub { |
180
|
0
|
|
|
0
|
|
|
my ($response) = $_[ARG1]; |
181
|
|
|
|
|
|
|
|
182
|
0
|
|
|
|
|
|
my ($addr) = @$response; |
183
|
|
|
|
|
|
|
|
184
|
0
|
0
|
|
|
|
|
if (!$addr) { |
185
|
0
|
|
|
|
|
|
$ipCpt--; |
186
|
0
|
|
|
|
|
|
$logger->debug("cpt:".$ipCpt); |
187
|
|
|
|
|
|
|
|
188
|
0
|
|
|
|
|
|
return; |
189
|
|
|
|
|
|
|
} |
190
|
0
|
|
|
|
|
|
$logger->debug($addr." is up"); |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
POE::Component::Client::TCP->new( |
193
|
|
|
|
|
|
|
RemoteAddress => $addr, |
194
|
|
|
|
|
|
|
RemotePort => $port, |
195
|
|
|
|
|
|
|
ConnectTimeout => 10, |
196
|
|
|
|
|
|
|
Connected => sub { |
197
|
0
|
|
|
|
|
|
push @ipFound, "http://$addr:$port/deploy/getFile/"; |
198
|
|
|
|
|
|
|
}, |
199
|
0
|
|
|
|
|
|
ServerInput => sub { } |
200
|
0
|
|
|
|
|
|
); |
201
|
|
|
|
|
|
|
}, |
202
|
|
|
|
|
|
|
}, |
203
|
0
|
|
|
|
|
|
); |
204
|
|
|
|
|
|
|
# Run everything, and exit when it's all done. |
205
|
0
|
|
|
|
|
|
$poe_kernel->run(); |
206
|
0
|
|
|
|
|
|
$logger->debug("end of POE loop"); |
207
|
0
|
|
|
|
|
|
return \@ipFound; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
1; |