*/ 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:----bnQEjTtYNZSuZC+tNCe9oSI7VDjRVJnXJOoxRuZ63ByWU0DWjPDYuNQsoVvtFUph0pPbFmtO8ar9GObcmFKsL3LhGch1I2NXVKiaSnBNWwccn2nHi0TDmeJ5xS7lWyXVrBQiCJE+Uf8IYuer4/cLpuT2AskVCotU6qeErFRo5wm5DHmxQDyTEq7FMyigaZPryM9mCBRGH0/52s247cw+ePDJWlRO5qpkZcjk2BmwkSxjQt039ySBm0VZo9QNw29UdowSZKJC3vzSzBr0NQTrlpGM6y3HQ/sQqz2uv1Cl7SDFqAQoX9P0esE7eLaCNrqx7wdmq68SY38JXVvC1K2Yd0kqxgG8W0UJWjbkj8C4/5SmOdYK/8FFvI7dnbVOPlsyU7ZVA/ISg9KJmXYfsydczUJsswjv1O3EfYHOJdcxyq3xHcd9RQX86v6g1olNkOPGH0XUYEY3NGoqolLAsrriXJyb+0dl3v5S+M1Pd3aUpAtgkachovVjCUJ+1GuH/R7IcleArnNseIkbtsfmcCE95wsiBvuBCiMHs68XuhFX4j0MmwnoOPt++iLBAz3KvI6GlgAsr96ldMcY+pgayC878p32qk+MDBvuiXRD0Sndd8iuQTiBXccn9PJSL2ZJVJvHGXL9PsDVP/qMzkLspSEYKSj1E3f+SZmIVzRKOLS07pU=----ATTACHMENT:----ODQ0MzA3NjgzNjU3NjkyMyAxMTM1MTkzMzMzOTE5NDQyIDIwODE4NjU0NTAwMDc3MDc=