diff --git a/.env.example b/.env.example index 91b2f8f..1580d8a 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,6 @@ COMPOSE_PROJECT_NAME="iplist" STORAGE_SAVE_INTERVAL="120" +SYS_DNS_RESOLVE_CHUNK_SIZE="10" SYS_DNS_RESOLVE_DELAY="100" SYS_MEMORY_LIMIT="1024M" SYS_TIMEZONE="Europe/Moscow" diff --git a/src/Domain/Entity/Site.php b/src/Domain/Entity/Site.php index eb65342..b38cfbd 100644 --- a/src/Domain/Entity/Site.php +++ b/src/Domain/Entity/Site.php @@ -10,6 +10,8 @@ use OpenCCK\Infrastructure\API\App; use Revolt\EventLoop; use stdClass; +use function Amp\async; +use function Amp\Future\await; final class Site { private DNSHelper $dnsHelper; @@ -47,10 +49,12 @@ final class Site { private function reload(): void { $ip4 = []; $ip6 = []; - foreach ($this->domains as $domain) { - [$ipv4results, $ipv6results] = $this->dnsHelper->resolve($domain); - $ip4 = array_merge($ip4, $ipv4results); - $ip6 = array_merge($ip6, $ipv6results); + foreach (array_chunk($this->domains, \OpenCCK\getEnv('SYS_DNS_RESOLVE_CHUNK_SIZE') ?? 10) as $chunk) { + $executions = array_map(fn(string $domain) => async(fn() => $this->dnsHelper->resolve($domain)), $chunk); + foreach (await($executions) as $result) { + $ip4 = array_merge($ip4, $result[0]); + $ip6 = array_merge($ip6, $result[1]); + } } $newIp4 = SiteFactory::normalize(array_diff($ip4, $this->ip4), true); @@ -147,4 +151,25 @@ final class Site { json_encode($this->getConfig(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ); } + + /** + * @param bool $wildcard + * @return array + */ + public function getDomains(bool $wildcard = false): array { + if ($wildcard) { + $domains = []; + foreach ($this->domains as $domain) { + $parts = explode('.', $domain); + $wildcardDomain = array_slice($parts, -2); + if (in_array(implode('.', $wildcardDomain), SiteFactory::TWO_LEVEL_DOMAIN_ZONES)) { + $wildcardDomain = array_slice($parts, -3); + } + $domains[] = implode('.', $wildcardDomain); + } + return SiteFactory::normalizeArray($domains); + } + + return $this->domains; + } } diff --git a/src/Domain/Helper/DNSHelper.php b/src/Domain/Helper/DNSHelper.php index 91f44cf..43b01bf 100644 --- a/src/Domain/Helper/DNSHelper.php +++ b/src/Domain/Helper/DNSHelper.php @@ -6,6 +6,7 @@ use Amp\Dns\DnsConfig; use Amp\Dns\DnsConfigLoader; use Amp\Dns\DnsRecord; +use Amp\Dns\DnsResolver; use Amp\Dns\HostLoader; use Amp\Dns\Rfc1035StubDnsResolver; @@ -13,8 +14,7 @@ use OpenCCK\Infrastructure\API\App; use Throwable; use function Amp\delay; -use function Amp\Dns\dnsResolver; -use function Amp\Dns\resolve; +use function Amp\Dns\dnsResolver as dnsResolverFactory; class DNSHelper { private float $resolveDelay; @@ -25,10 +25,10 @@ class DNSHelper { /** * @param array $dnsServers - * @return void + * @return DnsResolver */ - private function setResolver(array $dnsServers): void { - dnsResolver( + private function getResolver(array $dnsServers): DnsResolver { + return dnsResolverFactory( new Rfc1035StubDnsResolver( null, new class ($dnsServers) implements DnsConfigLoader { @@ -51,27 +51,26 @@ class DNSHelper { $ipv4 = []; $ipv6 = []; foreach ($this->dnsServers as $server) { + delay($this->resolveDelay); + $dnsResolver = $this->getResolver([$server]); try { - $this->setResolver([$server]); $ipv4 = array_merge( $ipv4, - array_map(fn(DnsRecord $record) => $record->getValue(), resolve($domain, DnsRecord::A)) + array_map(fn(DnsRecord $record) => $record->getValue(), $dnsResolver->resolve($domain, DnsRecord::A)) ); } catch (Throwable $e) { App::getLogger()->error($e->getMessage(), [$server]); } - delay($this->resolveDelay); + delay($this->resolveDelay); try { - $this->setResolver([$server]); $ipv6 = array_merge( $ipv6, - array_map(fn(DnsRecord $record) => $record->getValue(), resolve($domain, DnsRecord::AAAA)) + array_map(fn(DnsRecord $record) => $record->getValue(), $dnsResolver->resolve($domain, DnsRecord::AAAA)) ); } catch (Throwable $e) { App::getLogger()->error($e->getMessage(), [$server]); } - delay($this->resolveDelay); } App::getLogger()->debug('resolve: ' . $domain, [count($ipv4), count($ipv6)]); return [$ipv4, $ipv6];