chg: [correlations] Use faster algorithm for IPv6 correlations

pull/5889/head
Jakub Onderka 2020-05-08 21:16:33 +02:00
parent f8b8b8b713
commit 91139482cf
1 changed files with 13 additions and 31 deletions

View File

@ -1935,42 +1935,24 @@ class Attribute extends AppModel
return ($ip & $mask) == $subnet;
}
// using Snifff's solution from http://stackoverflow.com/questions/7951061/matching-ipv6-address-to-a-cidr-subnet
// Using solution from https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/IpUtils.php
private function __ipv6InCidr($ip, $cidr)
{
$ip = $this->__expandIPv6Notation($ip);
$binaryip = $this->__inet_to_bits($ip);
list($net, $maskbits) = explode('/', $cidr);
$net = $this->__expandIPv6Notation($net);
if (substr($net, -1) == ':') {
$net .= '0';
}
$binarynet = $this->__inet_to_bits($net);
$ip_net_bits = substr($binaryip, 0, $maskbits);
$net_bits = substr($binarynet, 0, $maskbits);
return ($ip_net_bits === $net_bits);
}
list($address, $netmask) = explode('/', $cidr);
private function __expandIPv6Notation($ip)
{
if (strpos($ip, '::') !== false) {
$ip = str_replace('::', str_repeat(':0', 8 - substr_count($ip, ':')).':', $ip);
}
if (strpos($ip, ':') === 0) {
$ip = '0'.$ip;
}
return $ip;
}
$bytesAddr = unpack('n*', inet_pton($address));
$bytesTest = unpack('n*', inet_pton($ip));
private function __inet_to_bits($inet)
{
$unpacked = unpack('A16', $inet);
$unpacked = str_split($unpacked[1]);
$binaryip = '';
foreach ($unpacked as $char) {
$binaryip .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT);
for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
$left = $netmask - 16 * ($i - 1);
$left = ($left <= 16) ? $left : 16;
$mask = ~(0xffff >> $left) & 0xffff;
if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
return false;
}
}
return $binaryip;
return true;
}
private function __cidrCorrelation($a)