mirror of
https://github.com/rekryt/iplist.git
synced 2025-10-12 16:39:35 +03:00
fix: Merge adjacent CIDRs
This commit is contained in:
@@ -145,15 +145,15 @@ final class Site {
|
||||
|
||||
if (isset($this->external->cidr4) && $this->isUseIpv4) {
|
||||
foreach ($this->external->cidr4 as $url) {
|
||||
$this->cidr4 = SiteFactory::normalize(
|
||||
array_merge($this->cidr4, explode("\n", file_get_contents($url))),
|
||||
true
|
||||
$this->cidr4 = IP4Helper::minimizeSubnets(
|
||||
SiteFactory::normalize(array_merge($this->cidr4, explode("\n", file_get_contents($url))), true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->external->cidr6) && $this->isUseIpv6) {
|
||||
foreach ($this->external->cidr6 as $url) {
|
||||
// todo IP6Helper::minimizeSubnets
|
||||
$this->cidr6 = SiteFactory::normalize(
|
||||
array_merge($this->cidr6, explode("\n", file_get_contents($url))),
|
||||
true
|
||||
|
@@ -3,10 +3,12 @@
|
||||
namespace OpenCCK\Domain\Factory;
|
||||
|
||||
use OpenCCK\Domain\Entity\Site;
|
||||
use OpenCCK\Domain\Helper\IP4Helper;
|
||||
use OpenCCK\Domain\Helper\IP6Helper;
|
||||
use OpenCCK\Infrastructure\API\App;
|
||||
use stdClass;
|
||||
|
||||
use function \OpenCCK\getEnv;
|
||||
use function OpenCCK\getEnv;
|
||||
|
||||
class SiteFactory {
|
||||
// prettier-ignore
|
||||
@@ -78,8 +80,8 @@ class SiteFactory {
|
||||
$domains = self::normalize($domains);
|
||||
$ip4 = self::normalize($ip4, true);
|
||||
$ip6 = self::normalize($ip6, true);
|
||||
$cidr4 = self::normalize($cidr4, true);
|
||||
$cidr6 = self::normalize($cidr6, true);
|
||||
$cidr4 = IP4Helper::minimizeSubnets(self::normalize($cidr4, true));
|
||||
$cidr6 = self::normalize($cidr6, true); //$cidr6 = IP6Helper::minimizeSubnets(self::normalize($cidr6, true));
|
||||
|
||||
return new Site($name, $group, $domains, $dns, $timeout, $ip4, $ip6, $cidr4, $cidr6, $external);
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@ class IP4Helper {
|
||||
|
||||
if (CIDRStorage::getInstance()->has($ip)) {
|
||||
$searchArray = CIDRStorage::getInstance()->get($ip);
|
||||
$results = array_merge($results, self::trimCIDRs($searchArray));
|
||||
$results = array_merge($results, $searchArray);
|
||||
|
||||
App::getLogger()->debug($ip . ' -> ' . json_encode($searchArray), [
|
||||
$i + 1 . '/' . $count,
|
||||
@@ -72,8 +72,12 @@ class IP4Helper {
|
||||
explode(' ', strtr($search, ' ', '')),
|
||||
fn(string $cidr) => strlen($cidr) > 0
|
||||
);
|
||||
$searchArray = array_values(
|
||||
array_filter(self::trimCIDRs($searchArray), fn($cidr) => self::isInCIDR($ip, $cidr))
|
||||
);
|
||||
|
||||
CIDRStorage::getInstance()->set($ip, $searchArray);
|
||||
$results = array_merge($results, self::trimCIDRs($searchArray));
|
||||
$results = array_merge($results, $searchArray);
|
||||
|
||||
App::getLogger()->debug($ip . ' -> ' . json_encode($searchArray), [$i + 1 . '/' . $count, 'found']);
|
||||
} else {
|
||||
@@ -135,10 +139,17 @@ class IP4Helper {
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function isInCIDR(string $ip, string $cidr): bool {
|
||||
[$subnet, $mask] = explode('/', $cidr);
|
||||
if ((ip2long($ip) & ~((1 << 32 - $mask) - 1)) === ip2long($subnet)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function isInRange(string $ip, array $cidrs): bool {
|
||||
foreach ($cidrs as $cidr) {
|
||||
[$subnet, $mask] = explode('/', $cidr);
|
||||
if ((ip2long($ip) & ~((1 << 32 - $mask) - 1)) === ip2long($subnet)) {
|
||||
if (self::isInCIDR($ip, $cidr)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@ class IP6Helper {
|
||||
|
||||
if (CIDRStorage::getInstance()->has($ip)) {
|
||||
$searchArray = CIDRStorage::getInstance()->get($ip);
|
||||
$results = array_merge($results, self::trimCIDRs($searchArray));
|
||||
$results = array_merge($results, $searchArray);
|
||||
|
||||
App::getLogger()->debug($ip . ' -> ' . json_encode($searchArray), [
|
||||
$i + 1 . '/' . $count,
|
||||
@@ -72,8 +72,12 @@ class IP6Helper {
|
||||
explode(' ', strtr($search, ' ', '')),
|
||||
fn(string $cidr) => strlen($cidr) > 0
|
||||
);
|
||||
$searchArray = array_values(
|
||||
array_filter(self::trimCIDRs($searchArray), fn($cidr) => self::isInCIDR($ip, $cidr))
|
||||
);
|
||||
|
||||
CIDRStorage::getInstance()->set($ip, $searchArray);
|
||||
$results = array_merge($results, self::trimCIDRs($searchArray));
|
||||
$results = array_merge($results, $searchArray);
|
||||
|
||||
App::getLogger()->debug($ip . ' -> ' . json_encode($searchArray), [$i + 1 . '/' . $count, 'found']);
|
||||
} else {
|
||||
@@ -160,30 +164,38 @@ class IP6Helper {
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function isInRange(string $ip, array $cidrs): bool {
|
||||
public static function isInCidr(string $ip, string $cidr): bool {
|
||||
$ip = inet_pton($ip);
|
||||
|
||||
[$subnet, $mask] = explode('/', $cidr);
|
||||
$subnet = inet_pton($subnet);
|
||||
|
||||
$mask = intval($mask);
|
||||
$binaryMask = str_repeat('f', $mask >> 2);
|
||||
switch ($mask % 4) {
|
||||
case 1:
|
||||
$binaryMask .= '8';
|
||||
break;
|
||||
case 2:
|
||||
$binaryMask .= 'c';
|
||||
break;
|
||||
case 3:
|
||||
$binaryMask .= 'e';
|
||||
break;
|
||||
}
|
||||
$binaryMask = str_pad($binaryMask, 32, '0');
|
||||
$mask = pack('H*', $binaryMask);
|
||||
|
||||
if (($ip & $mask) === ($subnet & $mask)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function isInRange(string $ip, array $cidrs): bool {
|
||||
foreach ($cidrs as $cidr) {
|
||||
[$subnet, $mask] = explode('/', $cidr);
|
||||
$subnet = inet_pton($subnet);
|
||||
|
||||
$mask = intval($mask);
|
||||
$binaryMask = str_repeat('f', $mask >> 2);
|
||||
switch ($mask % 4) {
|
||||
case 1:
|
||||
$binaryMask .= '8';
|
||||
break;
|
||||
case 2:
|
||||
$binaryMask .= 'c';
|
||||
break;
|
||||
case 3:
|
||||
$binaryMask .= 'e';
|
||||
break;
|
||||
}
|
||||
$binaryMask = str_pad($binaryMask, 32, '0');
|
||||
$mask = pack('H*', $binaryMask);
|
||||
|
||||
if (($ip & $mask) === ($subnet & $mask)) {
|
||||
if (self::isInCIDR($ip, $cidr)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user