New geturl param to force IPv4 or IPv6

This will be used by the upcoming `webv4` and `webv6` options to
ensure that the checkip service returns the desired type of IP
address.

Addresses #172
This commit is contained in:
Richard Hansen 2020-06-11 13:23:25 -04:00
parent 323a873b22
commit 39bd6fce9e

View file

@ -2005,6 +2005,7 @@ sub geturl {
my $url = $params->{url} // '';
my $login = $params->{login} // '';
my $password = $params->{password} // '';
my $ipversion = $params->{ipversion} // '';
my $headers = $params->{headers} // '';
my $method = $params->{method} // 'GET';
my $data = $params->{data} // '';
@ -2027,7 +2028,6 @@ sub geturl {
if ($force_ssl || ($globals{'ssl'} and (caller(1))[3] ne 'main::get_ip')) {
$use_ssl = 1;
$default_port = 443;
load_ssl_support;
} else {
$use_ssl = 0;
$default_port = 80;
@ -2036,6 +2036,7 @@ sub geturl {
debug("protocol = %s", $use_ssl ? "https" : "http");
debug("server = %s", $server);
debug("url = %s", $url);
debug("ip ver = %s", $ipversion);
## determine peer and port to use.
$peer = $proxy || $server;
@ -2045,9 +2046,6 @@ sub geturl {
$port = $default_port unless $port =~ /^\d+$/;
$peer =~ s%:.*$%%;
my $to = sprintf "%s%s", $server, $proxy ? " via proxy $peer:$port" : "";
verbose("CONNECT:", "%s", $to);
$request = "$method ";
if (!$use_ssl) {
$request .= "http://$server" if $proxy;
@ -2073,57 +2071,61 @@ sub geturl {
$request .= $data;
$rq .= $data;
$0 = sprintf("%s - connecting to %s port %s", $program, $peer, $port);
if (!opt('exec')) {
debug("skipped network connection");
verbose("SENDING:", "%s", $request);
} elsif ($use_ssl) {
$sd = IO::Socket::SSL->new(
PeerAddr => $peer,
PeerPort => $port,
Proto => 'tcp',
MultiHomed => 1,
Timeout => opt('timeout'),
);
defined $sd or warning("cannot connect to %s:%s socket: %s %s", $peer, $port, $@, IO::Socket::SSL::errstr());
} elsif ($globals{'ipv6'}) {
my $socket_class = 'IO::Socket::INET';
if ($use_ssl) {
# IO::Socket::SSL will load IPv6 support if available on the system.
load_ssl_support;
$socket_class = 'IO::Socket::SSL';
} elsif ($globals{'ipv6'} || $ipversion eq '6') {
load_ipv6_support;
$sd = IO::Socket::INET6->new(
$socket_class = 'IO::Socket::INET6';
}
my %socket_args = (
PeerAddr => $peer,
PeerPort => $port,
Proto => 'tcp',
MultiHomed => 1,
Timeout => opt('timeout'),
);
defined $sd or warning("cannot connect to %s:%s socket: %s", $peer, $port, $@);
} else {
$sd = IO::Socket::INET->new(
PeerAddr => $peer,
PeerPort => $port,
Proto => 'tcp',
MultiHomed => 1,
Timeout => opt('timeout'),
);
defined $sd or warning("cannot connect to %s:%s socket: %s", $peer, $port, $@);
if ($ipversion eq '4') {
$socket_args{Domain} = PF_INET;
$socket_args{Family} = AF_INET;
} elsif ($ipversion eq '6') {
$socket_args{Domain} = PF_INET6;
$socket_args{Family} = AF_INET6;
} elsif ($ipversion ne '') {
fatal("geturl passed unsupported 'ipversion' value %s", $ipversion);
}
my $ipv = $ipversion eq '' ? '' : sprintf(" (IPv%s)", $ipversion);
my $peer_port_ipv = sprintf("%s:%s%s", $peer, $port, $ipv);
my $to = sprintf("%s%s%s", $server, $proxy ? " via proxy $peer:$port" : "", $ipv);
verbose("CONNECT:", "%s", $to);
$0 = sprintf("%s - connecting to %s", $program, $peer_port_ipv);
if (opt('exec')) {
$sd = $socket_class->new(%socket_args);
defined($sd) or warning("cannot connect to %s socket: %s%s", $peer_port_ipv, $@,
$use_ssl ? ' ' . IO::Socket::SSL::errstr() : '');
} else {
debug("skipped network connection");
verbose("SENDING:", "%s", $request);
}
if (defined $sd) {
## send the request to the http server
verbose("CONNECTED: ", $use_ssl ? 'using SSL' : 'using HTTP');
verbose("SENDING:", "%s", $request);
$0 = sprintf("%s - sending to %s port %s", $program, $peer, $port);
$0 = sprintf("%s - sending to %s", $program, $peer_port_ipv);
my $result = syswrite $sd, $rq;
if ($result != length($rq)) {
warning("cannot send to %s:%s (%s).", $peer, $port, $!);
warning("cannot send to %s (%s).", $peer_port_ipv, $!);
} else {
$0 = sprintf("%s - reading from %s port %s", $program, $peer, $port);
$0 = sprintf("%s - reading from %s", $program, $peer_port_ipv);
eval {
local $SIG{'ALRM'} = sub { die "timeout"; };
alarm(opt('timeout')) if opt('timeout') > 0;
while ($_ = <$sd>) {
$0 = sprintf("%s - read from %s port %s", $program, $peer, $port);
$0 = sprintf("%s - read from %s", $program, $peer_port_ipv);
verbose("RECEIVE:", "%s", define($_, "<undefined>"));
$reply .= $_ if defined $_;
}
@ -2140,7 +2142,7 @@ sub geturl {
$reply = '' if !defined $reply;
}
}
$0 = sprintf("%s - closed %s port %s", $program, $peer, $port);
$0 = sprintf("%s - closed %s", $program, $peer_port_ipv);
## during testing simulate reading the URL
if (opt('test')) {