feat: async dns resolving, new env SYS_DNS_RESOLVE_CHUNK_SIZE

This commit is contained in:
Rekryt
2024-09-03 20:09:39 +03:00
parent 21401bb284
commit c89cb6b4b3
3 changed files with 40 additions and 15 deletions

View File

@@ -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;
}
}

View File

@@ -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];