sub checkForOpenProxy {
my($self, $ip) = @_;
# If we weren't passed an IP address, default to whatever
# the current IP address is.
if (!$ip && $ENV{GATEWAY_INTERFACE}) {
my $r = Apache->request;
$ip = $r->connection->remote_ip if $r;
}
# If we don't have an IP address, it can't be an open proxy.
return 0 if !$ip;
# Known secure IPs also don't count as open proxies.
my $constants = getCurrentStatic();
my $gSkin = getCurrentSkin();
my $secure_ip_regex = $constants->{admin_secure_ip_regex};
return 0 if $secure_ip_regex && $ip =~ /$secure_ip_regex/;
# If the IP address is already one we have listed, use the
# existing listing.
my $port = $self->getKnownOpenProxy($ip);
if (defined $port) {
#print STDERR scalar(localtime) . " cfop no need to check ip '$ip', port is '$port'\n";
return $port;
}
#print STDERR scalar(localtime) . " cfop ip '$ip' not known, checking\n";
# No known answer; probe the IP address and get an answer.
my $ports = $constants->{comments_portscan_ports} || '80 8080 8000 3128';
my @ports = grep /^\d+$/, split / /, $ports;
return 0 if !@ports;
my $timeout = $constants->{comments_portscan_timeout} || 5;
my $connect_timeout = int($timeout/scalar(@ports)+0.2);
my $ok_url = "$gSkin->{absolutedir}/ok.txt";
my $pua = Slash::Custom::ParUserAgent->new();
$pua->redirect(1);
$pua->max_redirect(3);
$pua->max_hosts(scalar(@ports));
$pua->max_req(scalar(@ports));
$pua->timeout($connect_timeout);
#use LWP::Debug;
#use Data::Dumper;
#LWP::Debug::level("+trace"); LWP::Debug::level("+debug");
my $start_time = Time::HiRes::time;
local $_proxy_port = undef;
sub _cfop_callback {
my($data, $response, $protocol) = @_;
#print STDERR scalar(localtime) . " _cfop_callback protocol '$protocol' port '$_proxy_port' succ '" . ($response->is_success()) . "' data '$data' content '" . ($response->is_success() ? $response->content() : "(fail)") . "'\n";
if ($response->is_success() && $data eq "ok\n") {
# We got a success, so the IP is a proxy.
# We should know the proxy's port at this
# point; if not, that's remarkable, so
# print an error.
my $orig_req = $response->request();
$_proxy_port = $orig_req->{_slash_proxytest_port};
if (!$_proxy_port) {
print STDERR scalar(localtime) . " _cfop_callback got data but no port, protocol '$protocol' port '$_proxy_port' succ '" . ($response->is_success()) . "' data '$data' content '" . $response->content() . "'\n";
}
$_proxy_port ||= 1;
# We can quit listening on any of the
# other ports that may have connected,
# returning immediately from the wait().
# So we want to return C_ENDALL. Except
# C_ENDALL doesn't seem to _work_, it
# crashes in _remove_current_connection.
# Argh. So we use C_LASTCON.
return LWP::Parallel::UserAgent::C_LASTCON;
}
#print STDERR scalar(localtime) . " _cfop_callback protocol '$protocol' succ '0'\n";
}
#print STDERR scalar(localtime) . " cfop beginning registering\n";
for my $port (@ports) {
# We switch to a new proxy every time thru.
$pua->proxy('http', "http://$ip:$port/");
my $req = HTTP::Request->new(GET => $ok_url);
$req->{_slash_proxytest_port} = $port;
#print STDERR scalar(localtime) . " cfop registering for proxy '$pua->{proxy}{http}'\n";
$pua->register($req, \&_cfop_callback);
}
#print STDERR scalar(localtime) . "pua: " . Dumper($pua);
my $elapsed = Time::HiRes::time - $start_time;
my $wait_timeout = int($timeout - $elapsed + 0.5);
$wait_timeout = 1 if $wait_timeout wait($wait_timeout);
#print STDERR scalar(localtime) . " cfop done with wait, returning " . (defined $_proxy_port ? 'undef' : "'$port'") . "\n";
$_proxy_port = 0 if !$_proxy_port;
$elapsed = Time::HiRes::time - $start_time;
# Store this value so we don't keep probing the IP.
$self->setKnownOpenProxy($ip, $_proxy_port, $elapsed);
return $_proxy_port;
}
(Score: 0) by Anonymous Coward on Wednesday April 09 2014, @08:14PM
Well yeah, we know, but that was beside this particular point. There's always a reason, and sometimes a benefit, but the point is that peer to peer can hardly be assumed. And in the classic client/server relationship of most web servers, probing your clients is rude.