services: hybrid approach to previous

Finally, this makes sense and avoids probing already global
addresses...

1. If a private IPv4 or link-local IPv6 we can try to
   use the web test.

2. If anything else just pass it through, it should be
   reachable if configured correctly.
This commit is contained in:
Franco Fichtner 2018-04-20 10:49:00 +02:00
parent 1547ecce67
commit 9f4837d11a

View File

@ -1591,36 +1591,28 @@ function get_dyndns_ip($int, $ipver = 4)
return 'down';
}
if ($ipver == 4 && is_private_ip($ip_address)) {
if (is_private_ip($ip_address) || is_linklocal($ip_address)) {
/* Chinese alternative is http://ip.3322.net/ */
$hosttocheck = 'http://checkip.dyndns.org';
$hosttocheck = $ipver == 6 ? 'http://checkipv6.dyndns.org' : 'http://checkip.dyndns.org';
$ip_ch = curl_init($hosttocheck);
curl_setopt($ip_ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ip_ch, CURLOPT_INTERFACE, $ip_address);
curl_setopt($ip_ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ip_ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ip_ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ip_ch, CURLOPT_IPRESOLVE, $ipver == 6 ? CURL_IPRESOLVE_V6 : CURL_IPRESOLVE_V4);
$ip_result = curl_exec($ip_ch);
if ($ip_result !== false) {
preg_match('=<body>Current IP Address: (.*)</body>=siU', $ip_result, $matches);
$ip_address = trim($matches[1]);
} else {
log_error('Aborted IPv4 detection: ' . curl_error($ip_ch));
log_error("Aborted IPv{$ipver} detection: " . curl_error($ip_ch));
$ip_address = '';
}
curl_close($ip_ch);
if (!is_ipaddrv4($ip_address)) {
return 'down';
}
} elseif ($ipver == 6) {
/* link-local cannot establish a connection to a global address */
$local = is_linklocal($ip_address);
if (!is_ipaddrv6($ip_address) || $local) {
if ($local) {
log_error('Aborted IPv6 detection: link-local address');
}
return 'down';
}
}
if (($ipver == 6 && !is_ipaddrv6($ip_address)) || ($ipver != 6 && !is_ipaddrv4($ip_address))) {
return 'down';
}
return $ip_address;