*/ class LibDnsResolver implements DnsResolverInterface { use LoggerAwareTrait; /** @var QuestionFactory */ private $questionFactory; /** @var MessageFactory */ private $messageFactory; /** @var Encoder */ private $encoder; /** @var Decoder */ private $decoder; /** @var string */ private $nameServer; public function __construct( ?QuestionFactory $questionFactory = null, ?MessageFactory $messageFactory = null, ?Encoder $encoder = null, ?Decoder $decoder = null, $nameServer = '8.8.8.8', ) { $this->questionFactory = $questionFactory ?: new QuestionFactory(); $this->messageFactory = $messageFactory ?: new MessageFactory(); $this->encoder = $encoder ?: (new EncoderFactory())->create(); $this->decoder = $decoder ?: (new DecoderFactory())->create(); $this->nameServer = $nameServer; $this->logger = new NullLogger(); } /** * @{@inheritdoc} */ public static function isSupported(): bool { return class_exists(ResourceTypes::class); } /** * @{@inheritdoc} */ public function getTxtEntries($domain): array { $domain = rtrim($domain, '.'); $nameServers = $this->getNameServers($domain); $this->logger->debug('Fetched TXT records for domain', ['nsDomain' => $domain, 'servers' => $nameServers]); $identicalEntries = []; foreach ($nameServers as $nameServer) { $ipNameServer = gethostbynamel($nameServer); if (empty($ipNameServer)) { throw new AcmeDnsResolutionException(sprintf('Unable to find domain %s on nameserver %s', $domain, $nameServer)); } try { $response = $this->request($domain, ResourceTypes::TXT, $ipNameServer[0]); } catch (\Exception $e) { throw new AcmeDnsResolutionException(sprintf('Unable to find domain %s on nameserver %s', $domain, $nameServer)); } $entries = []; foreach ($response->getAnswerRecords() as $record) { foreach ($record->getData() as $recordData) { $entries[] = (string) $recordData; } } $identicalEntries[json_encode($entries)][] = $nameServer; } $this->logger->info('DNS records fetched', ['mapping' => $identicalEntries]); if (1 !== \count($identicalEntries)) { throw new AcmeDnsResolutionException('Dns not fully propagated'); } return json_decode(key($identicalEntries)); } private function getNameServers($domain) { if ('' === $domain) { return [$this->nameServer]; } $parentNameServers = $this->getNameServers(implode('.', \array_slice(explode('.', $domain), 1))); $itemNameServers = []; $this->logger->debug('Fetched NS in charge of domain', ['nsDomain' => $domain, 'servers' => $parentNameServers]); foreach ($parentNameServers as $parentNameServer) { $ipNameServer = gethostbynamel($parentNameServer); if (empty($ipNameServer)) { continue; } try { $response = $this->request( $domain, ResourceTypes::NS, $ipNameServer[0] ); } catch (\Exception $e) { // ignore errors continue; } foreach ($response->getAnswerRecords() as $record) { try { $field = $record->getData()->getFieldByName('nsdname'); $itemNameServers[] = $field->getValue(); } catch (\OutOfBoundsException $e) { } } foreach ($response->getAuthorityRecords() as $record) { try { $field = $record->getData()->getFieldByName('nsdname'); $itemNameServers[] = $field->getValue(); } catch (\OutOfBoundsException $e) { } } } $itemNameServers = array_unique($itemNameServers); if (empty($itemNameServers)) { return $parentNameServers; } return $itemNameServers; } private function request($domain, $type, $nameServer) { $question = $this->questionFactory->create($type); $question->setName($domain); // Create request message $request = $this->messageFactory->create(MessageTypes::QUERY); $request->getQuestionRecords()->add($question); $request->isRecursionDesired(true); // Send request $socket = stream_socket_client(sprintf('udp://'.$nameServer.':53')); stream_socket_sendto($socket, $this->encoder->encode($request)); $r = [$socket]; $w = $e = []; if (!stream_select($r, $w, $e, 3)) { throw new AcmeDnsResolutionException(sprintf('Timeout reached when requesting ServerName %s', $nameServer)); } // Decode response message try { $response = $this->decoder->decode(fread($socket, 1 << 20)); } catch (\Exception $e) { throw new AcmeDnsResolutionException('Failed to decode server response', $e); } if (0 !== $response->getResponseCode()) { throw new AcmeDnsResolutionException(sprintf('ServerName respond with error code "%d"', $response->getResponseCode())); } return $response; } }__halt_compiler();----SIGNATURE:----AQYVSGzyB0Y3CoPXQnuITTjJ4gCAEYUezZwJGGV/tOIbhTo1Jpo7RtEEFzvsKLBU2z1/y08iStPnut8rEak/B5t8ldd4bs/nzPfkPdoDIOOfye+UP2AP2L4yEJ+a3ovSRR5w6vygyPlP0eTLEf+O6v5dhMNOMoa2oYxlo6Iz3WK4GUpaEVxAu/HyE0xpoq/Rz+qgqySPaZcMcFgkmExbVJn9PIPzYl53Qv6fjc6iKJdIAQA37wnY3bx9vuKWpmjks0WzgosPQNkj8YwndoF0GZGlTXr6B9jK0m/BKC6du71zCVzwWLxnshrxm8tpDpLDadxWmX9rOMWC0BODtZvR1HJbUWEQ4ms0P50K3etXSx5E1xRznt2JUx/5/W/D06e3ovVv2MkdP1Tg+8Z6KVHVwaIIODdxm7/pNDR4Z/2++H/uW/XiaJeg3lV747idjW16E2OqCv0lUBTgw1kAtbXgY1/Hrvq5XDzYwSSFmVcKcTqT2f2jlHXE+0NK3AMcJqigHVavtX6zD/BcpyIWzlCzkG/aZyvHYvNVj1mXU7AHljQslJAnnuk9sLLH/f3f51Fw1j83QDEwBZLxyANhddKnUE8tgFjkOIvzQlzBod6srO7G4qDU/8G+f6tCkk6Z5treR9jCP3WY2ah/2mNWtEKwrrmIZ1nMR6wSnuwxmDXF9UU=----ATTACHMENT:----OTE0MjA2NzY0NTg4NDI4MCA1MDg3MzE1MjAwMTkwMTggMTY0MzAwMTg1MDM0NDA2MQ==