Initial Commit

This commit is contained in:
David Stone
2024-11-30 18:24:12 -07:00
commit e8f7955c1c
5432 changed files with 1397750 additions and 0 deletions

View File

@ -0,0 +1,445 @@
<?php
declare (strict_types=1);
/**
* Decodes raw network data to Message objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Decoder
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Decoder;
use WP_Ultimo\Dependencies\LibDNS\Messages\Message;
use WP_Ultimo\Dependencies\LibDNS\Messages\MessageFactory;
use WP_Ultimo\Dependencies\LibDNS\Packets\Packet;
use WP_Ultimo\Dependencies\LibDNS\Packets\PacketFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\Question;
use WP_Ultimo\Dependencies\LibDNS\Records\QuestionFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\Resource;
use WP_Ultimo\Dependencies\LibDNS\Records\ResourceBuilder;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Anything;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\BitMap;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Char;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\CharacterString;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\DomainName;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\IPv4Address;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\IPv6Address;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Long;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Short;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Type;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\TypeBuilder;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Types;
/**
* Decodes raw network data to Message objects
*
* @category LibDNS
* @package Decoder
* @author Chris Wright <https://github.com/DaveRandom>
*/
class Decoder
{
/**
* @var \LibDNS\Packets\PacketFactory
*/
private $packetFactory;
/**
* @var \LibDNS\Messages\MessageFactory
*/
private $messageFactory;
/**
* @var \LibDNS\Records\QuestionFactory
*/
private $questionFactory;
/**
* @var \LibDNS\Records\ResourceBuilder
*/
private $resourceBuilder;
/**
* @var \LibDNS\Records\Types\TypeBuilder
*/
private $typeBuilder;
/**
* @var \LibDNS\Decoder\DecodingContextFactory
*/
private $decodingContextFactory;
/**
* @var bool
*/
private $allowTrailingData;
/**
* Constructor
*
* @param \LibDNS\Packets\PacketFactory $packetFactory
* @param \LibDNS\Messages\MessageFactory $messageFactory
* @param \LibDNS\Records\QuestionFactory $questionFactory
* @param \LibDNS\Records\ResourceBuilder $resourceBuilder
* @param \LibDNS\Records\Types\TypeBuilder $typeBuilder
* @param \LibDNS\Decoder\DecodingContextFactory $decodingContextFactory
* @param bool $allowTrailingData
*/
public function __construct(PacketFactory $packetFactory, MessageFactory $messageFactory, QuestionFactory $questionFactory, ResourceBuilder $resourceBuilder, TypeBuilder $typeBuilder, DecodingContextFactory $decodingContextFactory, bool $allowTrailingData = \true)
{
$this->packetFactory = $packetFactory;
$this->messageFactory = $messageFactory;
$this->questionFactory = $questionFactory;
$this->resourceBuilder = $resourceBuilder;
$this->typeBuilder = $typeBuilder;
$this->decodingContextFactory = $decodingContextFactory;
$this->allowTrailingData = $allowTrailingData;
}
/**
* Read a specified number of bytes of data from a packet
*
* @param \LibDNS\Packets\Packet $packet
* @param int $length
* @return string
* @throws \UnexpectedValueException When the read operation does not result in the requested number of bytes
*/
private function readDataFromPacket(Packet $packet, int $length) : string
{
if ($packet->getBytesRemaining() < $length) {
throw new \UnexpectedValueException('Decode error: Incomplete packet (tried to read ' . $length . ' bytes from index ' . $packet->getPointer());
}
return $packet->read($length);
}
/**
* Decode the header section of the message
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Messages\Message $message
* @throws \UnexpectedValueException When the header section is invalid
*/
private function decodeHeader(DecodingContext $decodingContext, Message $message)
{
$header = \unpack('nid/nmeta/nqd/nan/nns/nar', $this->readDataFromPacket($decodingContext->getPacket(), 12));
if (!$header) {
throw new \UnexpectedValueException('Decode error: Header unpack failed');
}
$message->setID($header['id']);
$message->setType(($header['meta'] & 0b1000000000000000) >> 15);
$message->setOpCode(($header['meta'] & 0b111100000000000) >> 11);
$message->isAuthoritative((bool) (($header['meta'] & 0b10000000000) >> 10));
$message->isTruncated((bool) (($header['meta'] & 0b1000000000) >> 9));
$message->isRecursionDesired((bool) (($header['meta'] & 0b100000000) >> 8));
$message->isRecursionAvailable((bool) (($header['meta'] & 0b10000000) >> 7));
$message->setResponseCode($header['meta'] & 0b1111);
$decodingContext->setExpectedQuestionRecords($header['qd']);
$decodingContext->setExpectedAnswerRecords($header['an']);
$decodingContext->setExpectedAuthorityRecords($header['ns']);
$decodingContext->setExpectedAdditionalRecords($header['ar']);
}
/**
* Decode an Anything field
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Records\Types\Anything $anything The object to populate with the result
* @param int $length
* @return int The number of packet bytes consumed by the operation
* @throws \UnexpectedValueException When the packet data is invalid
*/
private function decodeAnything(DecodingContext $decodingContext, Anything $anything, int $length) : int
{
$anything->setValue($this->readDataFromPacket($decodingContext->getPacket(), $length));
return $length;
}
/**
* Decode a BitMap field
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Records\Types\BitMap $bitMap The object to populate with the result
* @param int $length
* @return int The number of packet bytes consumed by the operation
* @throws \UnexpectedValueException When the packet data is invalid
*/
private function decodeBitMap(DecodingContext $decodingContext, BitMap $bitMap, int $length) : int
{
$bitMap->setValue($this->readDataFromPacket($decodingContext->getPacket(), $length));
return $length;
}
/**
* Decode a Char field
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Records\Types\Char $char The object to populate with the result
* @return int The number of packet bytes consumed by the operation
* @throws \UnexpectedValueException When the packet data is invalid
*/
private function decodeChar(DecodingContext $decodingContext, Char $char) : int
{
$value = \unpack('C', $this->readDataFromPacket($decodingContext->getPacket(), 1))[1];
$char->setValue($value);
return 1;
}
/**
* Decode a CharacterString field
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Records\Types\CharacterString $characterString The object to populate with the result
* @return int The number of packet bytes consumed by the operation
* @throws \UnexpectedValueException When the packet data is invalid
*/
private function decodeCharacterString(DecodingContext $decodingContext, CharacterString $characterString) : int
{
$packet = $decodingContext->getPacket();
$length = \ord($this->readDataFromPacket($packet, 1));
$characterString->setValue($this->readDataFromPacket($packet, $length));
return $length + 1;
}
/**
* Decode a DomainName field
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Records\Types\DomainName $domainName The object to populate with the result
* @return int The number of packet bytes consumed by the operation
* @throws \UnexpectedValueException When the packet data is invalid
*/
private function decodeDomainName(DecodingContext $decodingContext, DomainName $domainName) : int
{
$packet = $decodingContext->getPacket();
$startIndex = '0x' . \dechex($packet->getPointer());
$labelRegistry = $decodingContext->getLabelRegistry();
$labels = [];
$totalLength = 0;
while (++$totalLength && ($length = \ord($this->readDataFromPacket($packet, 1)))) {
$labelType = $length & 0b11000000;
if ($labelType === 0b0) {
$index = $packet->getPointer() - 1;
$label = $this->readDataFromPacket($packet, $length);
\array_unshift($labels, [$index, $label]);
$totalLength += $length;
} else {
if ($labelType === 0b11000000) {
$index = ($length & 0b111111) << 8 | \ord($this->readDataFromPacket($packet, 1));
$ref = $labelRegistry->lookupLabel($index);
if ($ref === null) {
throw new \UnexpectedValueException('Decode error: Invalid compression pointer reference in domain name at position ' . $startIndex);
}
\array_unshift($labels, $ref);
$totalLength++;
break;
} else {
throw new \UnexpectedValueException('Decode error: Invalid label type ' . $labelType . 'in domain name at position ' . $startIndex);
}
}
}
$result = [];
foreach ($labels as $label) {
if (\is_int($label[0])) {
\array_unshift($result, $label[1]);
$labelRegistry->register($result, $label[0]);
} else {
$result = $label;
}
}
$domainName->setLabels($result);
return $totalLength;
}
/**
* Decode an IPv4Address field
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Records\Types\IPv4Address $ipv4Address The object to populate with the result
* @return int The number of packet bytes consumed by the operation
* @throws \UnexpectedValueException When the packet data is invalid
*/
private function decodeIPv4Address(DecodingContext $decodingContext, IPv4Address $ipv4Address) : int
{
$octets = \unpack('C4', $this->readDataFromPacket($decodingContext->getPacket(), 4));
$ipv4Address->setOctets($octets);
return 4;
}
/**
* Decode an IPv6Address field
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Records\Types\IPv6Address $ipv6Address The object to populate with the result
* @return int The number of packet bytes consumed by the operation
* @throws \UnexpectedValueException When the packet data is invalid
*/
private function decodeIPv6Address(DecodingContext $decodingContext, IPv6Address $ipv6Address) : int
{
$shorts = \unpack('n8', $this->readDataFromPacket($decodingContext->getPacket(), 16));
$ipv6Address->setShorts($shorts);
return 16;
}
/**
* Decode a Long field
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Records\Types\Long $long The object to populate with the result
* @return int The number of packet bytes consumed by the operation
* @throws \UnexpectedValueException When the packet data is invalid
*/
private function decodeLong(DecodingContext $decodingContext, Long $long) : int
{
$value = \unpack('N', $this->readDataFromPacket($decodingContext->getPacket(), 4))[1];
$long->setValue($value);
return 4;
}
/**
* Decode a Short field
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Records\Types\Short $short The object to populate with the result
* @return int The number of packet bytes consumed by the operation
* @throws \UnexpectedValueException When the packet data is invalid
*/
private function decodeShort(DecodingContext $decodingContext, Short $short) : int
{
$value = \unpack('n', $this->readDataFromPacket($decodingContext->getPacket(), 2))[1];
$short->setValue($value);
return 2;
}
/**
* Decode a Type field
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @param \LibDNS\Records\Types\Type $type The object to populate with the result
* @param int $length Expected data length
* @return int The number of packet bytes consumed by the operation
* @throws \UnexpectedValueException When the packet data is invalid
* @throws \InvalidArgumentException When the Type subtype is unknown
*/
private function decodeType(DecodingContext $decodingContext, Type $type, int $length) : int
{
if ($type instanceof Anything) {
$result = $this->decodeAnything($decodingContext, $type, $length);
} else {
if ($type instanceof BitMap) {
$result = $this->decodeBitMap($decodingContext, $type, $length);
} else {
if ($type instanceof Char) {
$result = $this->decodeChar($decodingContext, $type);
} else {
if ($type instanceof CharacterString) {
$result = $this->decodeCharacterString($decodingContext, $type);
} else {
if ($type instanceof DomainName) {
$result = $this->decodeDomainName($decodingContext, $type);
} else {
if ($type instanceof IPv4Address) {
$result = $this->decodeIPv4Address($decodingContext, $type);
} else {
if ($type instanceof IPv6Address) {
$result = $this->decodeIPv6Address($decodingContext, $type);
} else {
if ($type instanceof Long) {
$result = $this->decodeLong($decodingContext, $type);
} else {
if ($type instanceof Short) {
$result = $this->decodeShort($decodingContext, $type);
} else {
throw new \InvalidArgumentException('Unknown Type ' . \get_class($type));
}
}
}
}
}
}
}
}
}
return $result;
}
/**
* Decode a question record
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @return \LibDNS\Records\Question
* @throws \UnexpectedValueException When the record is invalid
*/
private function decodeQuestionRecord(DecodingContext $decodingContext) : Question
{
/** @var \LibDNS\Records\Types\DomainName $domainName */
$domainName = $this->typeBuilder->build(Types::DOMAIN_NAME);
$this->decodeDomainName($decodingContext, $domainName);
$meta = \unpack('ntype/nclass', $this->readDataFromPacket($decodingContext->getPacket(), 4));
$question = $this->questionFactory->create($meta['type']);
$question->setName($domainName);
$question->setClass($meta['class']);
return $question;
}
/**
* Decode a resource record
*
* @param \LibDNS\Decoder\DecodingContext $decodingContext
* @return \LibDNS\Records\Resource
* @throws \UnexpectedValueException When the record is invalid
* @throws \InvalidArgumentException When a type subtype is unknown
*/
private function decodeResourceRecord(DecodingContext $decodingContext) : Resource
{
/** @var \LibDNS\Records\Types\DomainName $domainName */
$domainName = $this->typeBuilder->build(Types::DOMAIN_NAME);
$this->decodeDomainName($decodingContext, $domainName);
$meta = \unpack('ntype/nclass/Nttl/nlength', $this->readDataFromPacket($decodingContext->getPacket(), 10));
$resource = $this->resourceBuilder->build($meta['type']);
$resource->setName($domainName);
$resource->setClass($meta['class']);
$resource->setTTL($meta['ttl']);
$data = $resource->getData();
$remainingLength = $meta['length'];
$fieldDef = $index = null;
foreach ($resource->getData()->getTypeDefinition() as $index => $fieldDef) {
$field = $this->typeBuilder->build($fieldDef->getType());
$remainingLength -= $this->decodeType($decodingContext, $field, $remainingLength);
$data->setField($index, $field);
}
if ($fieldDef->allowsMultiple()) {
while ($remainingLength) {
$field = $this->typeBuilder->build($fieldDef->getType());
$remainingLength -= $this->decodeType($decodingContext, $field, $remainingLength);
$data->setField(++$index, $field);
}
}
if ($remainingLength !== 0) {
throw new \UnexpectedValueException('Decode error: Invalid length for record data section');
}
return $resource;
}
/**
* Decode a Message from raw network data
*
* @param string $data The data string to decode
* @return \LibDNS\Messages\Message
* @throws \UnexpectedValueException When the packet data is invalid
* @throws \InvalidArgumentException When a type subtype is unknown
*/
public function decode(string $data) : Message
{
$packet = $this->packetFactory->create($data);
$decodingContext = $this->decodingContextFactory->create($packet);
$message = $this->messageFactory->create();
$this->decodeHeader($decodingContext, $message);
$questionRecords = $message->getQuestionRecords();
$expected = $decodingContext->getExpectedQuestionRecords();
for ($i = 0; $i < $expected; $i++) {
$questionRecords->add($this->decodeQuestionRecord($decodingContext));
}
$answerRecords = $message->getAnswerRecords();
$expected = $decodingContext->getExpectedAnswerRecords();
for ($i = 0; $i < $expected; $i++) {
$answerRecords->add($this->decodeResourceRecord($decodingContext));
}
$authorityRecords = $message->getAuthorityRecords();
$expected = $decodingContext->getExpectedAuthorityRecords();
for ($i = 0; $i < $expected; $i++) {
$authorityRecords->add($this->decodeResourceRecord($decodingContext));
}
$additionalRecords = $message->getAdditionalRecords();
$expected = $decodingContext->getExpectedAdditionalRecords();
for ($i = 0; $i < $expected; $i++) {
$additionalRecords->add($this->decodeResourceRecord($decodingContext));
}
if (!$this->allowTrailingData && $packet->getBytesRemaining() !== 0) {
throw new \UnexpectedValueException('Decode error: Unexpected data at end of packet');
}
return $message;
}
}

View File

@ -0,0 +1,52 @@
<?php
declare (strict_types=1);
/**
* Creates Decoder objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Decoder
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Decoder;
use WP_Ultimo\Dependencies\LibDNS\Packets\PacketFactory;
use WP_Ultimo\Dependencies\LibDNS\Messages\MessageFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\RecordCollectionFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\QuestionFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\ResourceBuilder;
use WP_Ultimo\Dependencies\LibDNS\Records\ResourceFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\RDataBuilder;
use WP_Ultimo\Dependencies\LibDNS\Records\RDataFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\TypeBuilder;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\TypeFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions\TypeDefinitionManager;
use WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions\TypeDefinitionFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions\FieldDefinitionFactory;
/**
* Creates Decoder objects
*
* @category LibDNS
* @package Decoder
* @author Chris Wright <https://github.com/DaveRandom>
*/
class DecoderFactory
{
/**
* Create a new Decoder object
*
* @param \LibDNS\Records\TypeDefinitions\TypeDefinitionManager $typeDefinitionManager
* @param bool $allowTrailingData
* @return Decoder
*/
public function create(TypeDefinitionManager $typeDefinitionManager = null, bool $allowTrailingData = \true) : Decoder
{
$typeBuilder = new TypeBuilder(new TypeFactory());
return new Decoder(new PacketFactory(), new MessageFactory(new RecordCollectionFactory()), new QuestionFactory(), new ResourceBuilder(new ResourceFactory(), new RDataBuilder(new RDataFactory(), $typeBuilder), $typeDefinitionManager ?: new TypeDefinitionManager(new TypeDefinitionFactory(), new FieldDefinitionFactory())), $typeBuilder, new DecodingContextFactory(), $allowTrailingData);
}
}

View File

@ -0,0 +1,154 @@
<?php
declare (strict_types=1);
/**
* Holds data associated with a decode operation
*
* PHP version 5.4
*
* @category LibDNS
* @package Decoder
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Decoder;
use WP_Ultimo\Dependencies\LibDNS\Packets\Packet;
use WP_Ultimo\Dependencies\LibDNS\Packets\LabelRegistry;
/**
* Holds data associated with a decode operation
*
* @category LibDNS
* @package Decoder
* @author Chris Wright <https://github.com/DaveRandom>
*/
class DecodingContext
{
/**
* @var \LibDNS\Packets\Packet
*/
private $packet;
/**
* @var \LibDNS\Packets\LabelRegistry
*/
private $labelRegistry;
/**
* @var int
*/
private $expectedQuestionRecords = 0;
/**
* @var int
*/
private $expectedAnswerRecords = 0;
/**
* @var int
*/
private $expectedAuthorityRecords = 0;
/**
* @var int
*/
private $expectedAdditionalRecords = 0;
/**
* Constructor
*
* @param \LibDNS\Packets\Packet $packet
* @param \LibDNS\Packets\LabelRegistry $labelRegistry
*/
public function __construct(Packet $packet, LabelRegistry $labelRegistry)
{
$this->packet = $packet;
$this->labelRegistry = $labelRegistry;
}
/**
* Get the packet
*
* @return \LibDNS\Packets\Packet
*/
public function getPacket() : Packet
{
return $this->packet;
}
/**
* Get the label registry
*
* @return \LibDNS\Packets\LabelRegistry
*/
public function getLabelRegistry() : LabelRegistry
{
return $this->labelRegistry;
}
/**
* Get the number of question records expected in the message
*
* @return int
*/
public function getExpectedQuestionRecords() : int
{
return $this->expectedQuestionRecords;
}
/**
* Get the number of question records expected in the message
*
* @param int $expectedQuestionRecords
*/
public function setExpectedQuestionRecords(int $expectedQuestionRecords)
{
$this->expectedQuestionRecords = $expectedQuestionRecords;
}
/**
* Get the number of answer records expected in the message
*
* @return int
*/
public function getExpectedAnswerRecords() : int
{
return $this->expectedAnswerRecords;
}
/**
* Set the number of answer records expected in the message
*
* @param int $expectedAnswerRecords
*/
public function setExpectedAnswerRecords(int $expectedAnswerRecords)
{
$this->expectedAnswerRecords = $expectedAnswerRecords;
}
/**
* Get the number of authority records expected in the message
*
* @return int
*/
public function getExpectedAuthorityRecords() : int
{
return $this->expectedAuthorityRecords;
}
/**
* Set the number of authority records expected in the message
*
* @param int $expectedAuthorityRecords
*/
public function setExpectedAuthorityRecords(int $expectedAuthorityRecords)
{
$this->expectedAuthorityRecords = $expectedAuthorityRecords;
}
/**
* Get the number of additional records expected in the message
*
* @return int
*/
public function getExpectedAdditionalRecords() : int
{
return $this->expectedAdditionalRecords;
}
/**
* Set the number of additional records expected in the message
*
* @param int $expectedAdditionalRecords
*/
public function setExpectedAdditionalRecords(int $expectedAdditionalRecords)
{
$this->expectedAdditionalRecords = $expectedAdditionalRecords;
}
}

View File

@ -0,0 +1,39 @@
<?php
declare (strict_types=1);
/**
* Creates DecodingContext objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Decoder
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Decoder;
use WP_Ultimo\Dependencies\LibDNS\Packets\Packet;
use WP_Ultimo\Dependencies\LibDNS\Packets\LabelRegistry;
/**
* Creates DecodingContext objects
*
* @category LibDNS
* @package Decoder
* @author Chris Wright <https://github.com/DaveRandom>
*/
class DecodingContextFactory
{
/**
* Create a new DecodingContext object
*
* @param \LibDNS\Packets\Packet $packet The packet to be decoded
* @return \LibDNS\Decoder\DecodingContext
*/
public function create(Packet $packet) : DecodingContext
{
return new DecodingContext($packet, new LabelRegistry());
}
}

View File

@ -0,0 +1,324 @@
<?php
declare (strict_types=1);
/**
* Encodes Message objects to raw network data
*
* PHP version 5.4
*
* @category LibDNS
* @package Encoder
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Encoder;
use WP_Ultimo\Dependencies\LibDNS\Packets\PacketFactory;
use WP_Ultimo\Dependencies\LibDNS\Messages\Message;
use WP_Ultimo\Dependencies\LibDNS\Records\Question;
use WP_Ultimo\Dependencies\LibDNS\Records\Resource;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Type;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Anything;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\BitMap;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Char;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\CharacterString;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\DomainName;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\IPv4Address;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\IPv6Address;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Long;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Short;
/**
* Encodes Message objects to raw network data
*
* @category LibDNS
* @package Encoder
* @author Chris Wright <https://github.com/DaveRandom>
*/
class Encoder
{
/**
* @var \LibDNS\Packets\PacketFactory
*/
private $packetFactory;
/**
* @var \LibDNS\Encoder\EncodingContextFactory
*/
private $encodingContextFactory;
/**
* Constructor
*
* @param \LibDNS\Packets\PacketFactory $packetFactory
* @param \LibDNS\Encoder\EncodingContextFactory $encodingContextFactory
*/
public function __construct(PacketFactory $packetFactory, EncodingContextFactory $encodingContextFactory)
{
$this->packetFactory = $packetFactory;
$this->encodingContextFactory = $encodingContextFactory;
}
/**
* Encode the header section of the message
*
* @param \LibDNS\Encoder\EncodingContext $encodingContext
* @param \LibDNS\Messages\Message $message
* @return string
* @throws \UnexpectedValueException When the header section is invalid
*/
private function encodeHeader(EncodingContext $encodingContext, Message $message) : string
{
$header = ['id' => $message->getID(), 'meta' => 0, 'qd' => $message->getQuestionRecords()->count(), 'an' => $message->getAnswerRecords()->count(), 'ns' => $message->getAuthorityRecords()->count(), 'ar' => $message->getAdditionalRecords()->count()];
$header['meta'] |= $message->getType() << 15;
$header['meta'] |= $message->getOpCode() << 11;
$header['meta'] |= (int) $message->isAuthoritative() << 10;
$header['meta'] |= (int) $encodingContext->isTruncated() << 9;
$header['meta'] |= (int) $message->isRecursionDesired() << 8;
$header['meta'] |= (int) $message->isRecursionAvailable() << 7;
$header['meta'] |= $message->getResponseCode();
return \pack('n*', $header['id'], $header['meta'], $header['qd'], $header['an'], $header['ns'], $header['ar']);
}
/**
* Encode an Anything field
*
* @param \LibDNS\Records\Types\Anything $anything
* @return string
*/
private function encodeAnything(Anything $anything) : string
{
return $anything->getValue();
}
/**
* Encode a BitMap field
*
* @param \LibDNS\Records\Types\BitMap $bitMap
* @return string
*/
private function encodeBitMap(BitMap $bitMap) : string
{
return $bitMap->getValue();
}
/**
* Encode a Char field
*
* @param \LibDNS\Records\Types\Char $char
* @return string
*/
private function encodeChar(Char $char) : string
{
return \chr($char->getValue());
}
/**
* Encode a CharacterString field
*
* @param \LibDNS\Records\Types\CharacterString $characterString
* @return string
*/
private function encodeCharacterString(CharacterString $characterString) : string
{
$data = $characterString->getValue();
return \chr(\strlen($data)) . $data;
}
/**
* Encode a DomainName field
*
* @param \LibDNS\Records\Types\DomainName $domainName
* @param \LibDNS\Encoder\EncodingContext $encodingContext
* @return string
*/
private function encodeDomainName(DomainName $domainName, EncodingContext $encodingContext) : string
{
$packetIndex = $encodingContext->getPacket()->getLength() + 12;
$labelRegistry = $encodingContext->getLabelRegistry();
$result = '';
$labels = $domainName->getLabels();
if ($encodingContext->useCompression()) {
do {
$part = \implode('.', $labels);
$index = $labelRegistry->lookupIndex($part);
if ($index === null) {
$labelRegistry->register($part, $packetIndex);
$label = \array_shift($labels);
$length = \strlen($label);
$result .= \chr($length) . $label;
$packetIndex += $length + 1;
} else {
$result .= \pack('n', 0b1100000000000000 | $index);
break;
}
} while ($labels);
if (!$labels) {
$result .= "\x00";
}
} else {
foreach ($labels as $label) {
$result .= \chr(\strlen($label)) . $label;
}
$result .= "\x00";
}
return $result;
}
/**
* Encode an IPv4Address field
*
* @param \LibDNS\Records\Types\IPv4Address $ipv4Address
* @return string
*/
private function encodeIPv4Address(IPv4Address $ipv4Address) : string
{
$octets = $ipv4Address->getOctets();
return \pack('C*', $octets[0], $octets[1], $octets[2], $octets[3]);
}
/**
* Encode an IPv6Address field
*
* @param \LibDNS\Records\Types\IPv6Address $ipv6Address
* @return string
*/
private function encodeIPv6Address(IPv6Address $ipv6Address) : string
{
$shorts = $ipv6Address->getShorts();
return \pack('n*', $shorts[0], $shorts[1], $shorts[2], $shorts[3], $shorts[4], $shorts[5], $shorts[6], $shorts[7]);
}
/**
* Encode a Long field
*
* @param \LibDNS\Records\Types\Long $long
* @return string
*/
private function encodeLong(Long $long) : string
{
return \pack('N', $long->getValue());
}
/**
* Encode a Short field
*
* @param \LibDNS\Records\Types\Short $short
* @return string
*/
private function encodeShort(Short $short) : string
{
return \pack('n', $short->getValue());
}
/**
* Encode a type object
*
* @param \LibDNS\Encoder\EncodingContext $encodingContext
* @param \LibDNS\Records\Types\Type $type
* @return string
*/
private function encodeType(EncodingContext $encodingContext, Type $type) : string
{
if ($type instanceof Anything) {
$result = $this->encodeAnything($type);
} else {
if ($type instanceof BitMap) {
$result = $this->encodeBitMap($type);
} else {
if ($type instanceof Char) {
$result = $this->encodeChar($type);
} else {
if ($type instanceof CharacterString) {
$result = $this->encodeCharacterString($type);
} else {
if ($type instanceof DomainName) {
$result = $this->encodeDomainName($type, $encodingContext);
} else {
if ($type instanceof IPv4Address) {
$result = $this->encodeIPv4Address($type);
} else {
if ($type instanceof IPv6Address) {
$result = $this->encodeIPv6Address($type);
} else {
if ($type instanceof Long) {
$result = $this->encodeLong($type);
} else {
if ($type instanceof Short) {
$result = $this->encodeShort($type);
} else {
throw new \InvalidArgumentException('Unknown Type ' . \get_class($type));
}
}
}
}
}
}
}
}
}
return $result;
}
/**
* Encode a question record
*
* @param \LibDNS\Encoder\EncodingContext $encodingContext
* @param \LibDNS\Records\Question $record
*/
private function encodeQuestionRecord(EncodingContext $encodingContext, Question $record)
{
if (!$encodingContext->isTruncated()) {
$packet = $encodingContext->getPacket();
$name = $this->encodeDomainName($record->getName(), $encodingContext);
$meta = \pack('n*', $record->getType(), $record->getClass());
if (12 + $packet->getLength() + \strlen($name) + 4 > 512) {
$encodingContext->isTruncated(\true);
} else {
$packet->write($name);
$packet->write($meta);
}
}
}
/**
* Encode a resource record
*
* @param \LibDNS\Encoder\EncodingContext $encodingContext
* @param \LibDNS\Records\Resource $record
*/
private function encodeResourceRecord(EncodingContext $encodingContext, Resource $record)
{
if (!$encodingContext->isTruncated()) {
$packet = $encodingContext->getPacket();
$name = $this->encodeDomainName($record->getName(), $encodingContext);
$data = '';
foreach ($record->getData() as $field) {
$data .= $this->encodeType($encodingContext, $field);
}
$meta = \pack('n2Nn', $record->getType(), $record->getClass(), $record->getTTL(), \strlen($data));
if (12 + $packet->getLength() + \strlen($name) + 10 + \strlen($data) > 512) {
$encodingContext->isTruncated(\true);
} else {
$packet->write($name);
$packet->write($meta);
$packet->write($data);
}
}
}
/**
* Encode a Message to raw network data
*
* @param \LibDNS\Messages\Message $message The Message to encode
* @param bool $compress Enable message compression
* @return string
*/
public function encode(Message $message, $compress = \true) : string
{
$packet = $this->packetFactory->create();
$encodingContext = $this->encodingContextFactory->create($packet, $compress);
foreach ($message->getQuestionRecords() as $record) {
/** @var \LibDNS\Records\Question $record */
$this->encodeQuestionRecord($encodingContext, $record);
}
foreach ($message->getAnswerRecords() as $record) {
/** @var \LibDNS\Records\Resource $record */
$this->encodeResourceRecord($encodingContext, $record);
}
foreach ($message->getAuthorityRecords() as $record) {
/** @var \LibDNS\Records\Resource $record */
$this->encodeResourceRecord($encodingContext, $record);
}
foreach ($message->getAdditionalRecords() as $record) {
/** @var \LibDNS\Records\Resource $record */
$this->encodeResourceRecord($encodingContext, $record);
}
return $this->encodeHeader($encodingContext, $message) . $packet->read($packet->getLength());
}
}

View File

@ -0,0 +1,37 @@
<?php
declare (strict_types=1);
/**
* Creates Encoder objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Encoder
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Encoder;
use WP_Ultimo\Dependencies\LibDNS\Packets\PacketFactory;
/**
* Creates Encoder objects
*
* @category LibDNS
* @package Encoder
* @author Chris Wright <https://github.com/DaveRandom>
*/
class EncoderFactory
{
/**
* Create a new Encoder object
*
* @return \LibDNS\Encoder\Encoder
*/
public function create() : Encoder
{
return new Encoder(new PacketFactory(), new EncodingContextFactory());
}
}

View File

@ -0,0 +1,99 @@
<?php
declare (strict_types=1);
/**
* Holds data associated with an encode operation
*
* PHP version 5.4
*
* @category LibDNS
* @package Encoder
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Encoder;
use WP_Ultimo\Dependencies\LibDNS\Packets\Packet;
use WP_Ultimo\Dependencies\LibDNS\Packets\LabelRegistry;
/**
* Holds data associated with an encode operation
*
* @category LibDNS
* @package Encoder
* @author Chris Wright <https://github.com/DaveRandom>
*/
class EncodingContext
{
/**
* @var \LibDNS\Packets\Packet
*/
private $packet;
/**
* @var \LibDNS\Packets\LabelRegistry
*/
private $labelRegistry;
/**
* @var bool
*/
private $compress;
/**
* @var bool
*/
private $truncate = \false;
/**
* Constructor
*
* @param \LibDNS\Packets\Packet $packet
* @param \LibDNS\Packets\LabelRegistry $labelRegistry
* @param bool $compress
*/
public function __construct(Packet $packet, LabelRegistry $labelRegistry, bool $compress)
{
$this->packet = $packet;
$this->labelRegistry = $labelRegistry;
$this->compress = $compress;
}
/**
* Get the packet
*
* @return \LibDNS\Packets\Packet
*/
public function getPacket() : Packet
{
return $this->packet;
}
/**
* Get the label registry
*
* @return \LibDNS\Packets\LabelRegistry
*/
public function getLabelRegistry() : LabelRegistry
{
return $this->labelRegistry;
}
/**
* Determine whether compression is enabled
*
* @return bool
*/
public function useCompression() : bool
{
return $this->compress;
}
/**
* Determine or set whether the message is truncated
*
* @param bool $truncate
* @return bool
*/
public function isTruncated(bool $truncate = null) : bool
{
$result = $this->truncate;
if ($truncate !== null) {
$this->truncate = $truncate;
}
return $result;
}
}

View File

@ -0,0 +1,40 @@
<?php
declare (strict_types=1);
/**
* Creates EncodingContext objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Encoder
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Encoder;
use WP_Ultimo\Dependencies\LibDNS\Packets\Packet;
use WP_Ultimo\Dependencies\LibDNS\Packets\LabelRegistry;
/**
* Creates EncodingContext objects
*
* @category LibDNS
* @package Encoder
* @author Chris Wright <https://github.com/DaveRandom>
*/
class EncodingContextFactory
{
/**
* Create a new EncodingContext object
*
* @param \LibDNS\Packets\Packet $packet The packet to be decoded
* @param bool $compress Whether message compression is enabled
* @return \LibDNS\Encoder\EncodingContext
*/
public function create(Packet $packet, bool $compress) : EncodingContext
{
return new EncodingContext($packet, new LabelRegistry(), $compress);
}
}

View File

@ -0,0 +1,31 @@
<?php
declare (strict_types=1);
/**
* Base class for enumerations to prevent instantiation
*
* PHP version 5.4
*
* @category LibDNS
* @package LibDNS
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS;
/**
* Base class for enumerations to prevent instantiation
*
* @category LibDNS
* @package LibDNS
* @author Chris Wright <https://github.com/DaveRandom>
*/
abstract class Enumeration
{
protected final function __construct()
{
throw new \LogicException('Enumerations cannot be instantiated');
}
}

View File

@ -0,0 +1,275 @@
<?php
declare (strict_types=1);
/**
* Represents a DNS protocol message
*
* PHP version 5.4
*
* @category LibDNS
* @package Messages
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Messages;
use WP_Ultimo\Dependencies\LibDNS\Records\RecordCollection;
use WP_Ultimo\Dependencies\LibDNS\Records\RecordCollectionFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\RecordTypes;
/**
* Represents a DNS protocol message
*
* @category LibDNS
* @package Messages
* @author Chris Wright <https://github.com/DaveRandom>
*/
class Message
{
/**
* @var int Unsigned short that identifies the DNS transaction
*/
private $id = 0;
/**
* @var int Indicates the type of the message, can be indicated using the MessageTypes enum
*/
private $type = -1;
/**
* @var int Message opcode, can be indicated using the MessageOpCodes enum
*/
private $opCode = MessageOpCodes::QUERY;
/**
* @var bool Whether a response message is authoritative
*/
private $authoritative = \false;
/**
* @var bool Whether the message is truncated
*/
private $truncated = \false;
/**
* @var bool Whether a query desires the server to recurse the lookup
*/
private $recursionDesired = \true;
/**
* @var bool Whether a server could provide recursion in a response
*/
private $recursionAvailable = \false;
/**
* @var int Message response code, can be indicated using the MessageResponseCodes enum
*/
private $responseCode = MessageResponseCodes::NO_ERROR;
/**
* @var \LibDNS\Records\RecordCollection Collection of question records
*/
private $questionRecords;
/**
* @var \LibDNS\Records\RecordCollection Collection of question records
*/
private $answerRecords;
/**
* @var \LibDNS\Records\RecordCollection Collection of authority records
*/
private $authorityRecords;
/**
* @var \LibDNS\Records\RecordCollection Collection of authority records
*/
private $additionalRecords;
/**
* Constructor
*
* @param \LibDNS\Records\RecordCollectionFactory $recordCollectionFactory Factory which makes RecordCollection objects
* @param int $type Value of the message type field
* @throws \RangeException When the supplied message type is outside the valid range 0 - 1
*/
public function __construct(RecordCollectionFactory $recordCollectionFactory, int $type = null)
{
$this->questionRecords = $recordCollectionFactory->create(RecordTypes::QUESTION);
$this->answerRecords = $recordCollectionFactory->create(RecordTypes::RESOURCE);
$this->authorityRecords = $recordCollectionFactory->create(RecordTypes::RESOURCE);
$this->additionalRecords = $recordCollectionFactory->create(RecordTypes::RESOURCE);
if ($type !== null) {
$this->setType($type);
}
}
/**
* Get the value of the message ID field
*
* @return int
*/
public function getID() : int
{
return $this->id;
}
/**
* Set the value of the message ID field
*
* @param int $id The new value
* @throws \RangeException When the supplied value is outside the valid range 0 - 65535
*/
public function setID(int $id)
{
if ($id < 0 || $id > 65535) {
throw new \RangeException('Message ID must be in the range 0 - 65535');
}
$this->id = $id;
}
/**
* Get the value of the message type field
*
* @return int
*/
public function getType() : int
{
return $this->type;
}
/**
* Set the value of the message type field
*
* @param int $type The new value
* @throws \RangeException When the supplied value is outside the valid range 0 - 1
*/
public function setType(int $type)
{
if ($type < 0 || $type > 1) {
throw new \RangeException('Message type must be in the range 0 - 1');
}
$this->type = $type;
}
/**
* Get the value of the message opcode field
*
* @return int
*/
public function getOpCode() : int
{
return $this->opCode;
}
/**
* Set the value of the message opcode field
*
* @param int $opCode The new value
* @throws \RangeException When the supplied value is outside the valid range 0 - 15
*/
public function setOpCode(int $opCode)
{
if ($opCode < 0 || $opCode > 15) {
throw new \RangeException('Message opcode must be in the range 0 - 15');
}
$this->opCode = $opCode;
}
/**
* Inspect the value of the authoritative field and optionally set a new value
*
* @param bool $newValue The new value
* @return bool The old value
*/
public function isAuthoritative(bool $newValue = null) : bool
{
$result = $this->authoritative;
if ($newValue !== null) {
$this->authoritative = $newValue;
}
return $result;
}
/**
* Inspect the value of the truncated field and optionally set a new value
*
* @param bool $newValue The new value
* @return bool The old value
*/
public function isTruncated(bool $newValue = null) : bool
{
$result = $this->truncated;
if ($newValue !== null) {
$this->truncated = $newValue;
}
return $result;
}
/**
* Inspect the value of the recusion desired field and optionally set a new value
*
* @param bool $newValue The new value
* @return bool The old value
*/
public function isRecursionDesired(bool $newValue = null) : bool
{
$result = $this->recursionDesired;
if ($newValue !== null) {
$this->recursionDesired = $newValue;
}
return $result;
}
/**
* Inspect the value of the recursion available field and optionally set a new value
*
* @param bool $newValue The new value
* @return bool The old value
*/
public function isRecursionAvailable(bool $newValue = null) : bool
{
$result = $this->recursionAvailable;
if ($newValue !== null) {
$this->recursionAvailable = $newValue;
}
return $result;
}
/**
* Get the value of the message response code field
*
* @return int
*/
public function getResponseCode() : int
{
return $this->responseCode;
}
/**
* Set the value of the message response code field
*
* @param int $responseCode The new value
* @throws \RangeException When the supplied value is outside the valid range 0 - 15
*/
public function setResponseCode(int $responseCode)
{
if ($responseCode < 0 || $responseCode > 15) {
throw new \RangeException('Message response code must be in the range 0 - 15');
}
$this->responseCode = $responseCode;
}
/**
* Get the question records collection
*
* @return \LibDNS\Records\RecordCollection
*/
public function getQuestionRecords() : RecordCollection
{
return $this->questionRecords;
}
/**
* Get the answer records collection
*
* @return \LibDNS\Records\RecordCollection
*/
public function getAnswerRecords() : RecordCollection
{
return $this->answerRecords;
}
/**
* Get the authority records collection
*
* @return \LibDNS\Records\RecordCollection
*/
public function getAuthorityRecords() : RecordCollection
{
return $this->authorityRecords;
}
/**
* Get the additional records collection
*
* @return \LibDNS\Records\RecordCollection
*/
public function getAdditionalRecords() : RecordCollection
{
return $this->additionalRecords;
}
}

View File

@ -0,0 +1,38 @@
<?php
declare (strict_types=1);
/**
* Factory which creates Message objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Messages
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Messages;
use WP_Ultimo\Dependencies\LibDNS\Records\RecordCollectionFactory;
/**
* Factory which creates Message objects
*
* @category LibDNS
* @package Messages
* @author Chris Wright <https://github.com/DaveRandom>
*/
class MessageFactory
{
/**
* Create a new Message object
*
* @param int $type Value of the message type field
* @return \LibDNS\Messages\Message
*/
public function create(int $type = null) : Message
{
return new Message(new RecordCollectionFactory(), $type);
}
}

View File

@ -0,0 +1,31 @@
<?php
declare (strict_types=1);
/**
* Enumeration of possible message opcodes
*
* PHP version 5.4
*
* @category LibDNS
* @package Messages
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Messages;
use WP_Ultimo\Dependencies\LibDNS\Enumeration;
/**
* Enumeration of possible message types
*
* @category LibDNS
* @package Messages
* @author Chris Wright <https://github.com/DaveRandom>
*/
final class MessageOpCodes extends Enumeration
{
const QUERY = 0;
const IQUERY = 1;
const STATUS = 2;
}

View File

@ -0,0 +1,34 @@
<?php
declare (strict_types=1);
/**
* Enumeration of possible message response codes
*
* PHP version 5.4
*
* @category LibDNS
* @package Messages
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Messages;
use WP_Ultimo\Dependencies\LibDNS\Enumeration;
/**
* Enumeration of possible message types
*
* @category LibDNS
* @package Messages
* @author Chris Wright <https://github.com/DaveRandom>
*/
final class MessageResponseCodes extends Enumeration
{
const NO_ERROR = 0;
const FORMAT_ERROR = 1;
const SERVER_FAILURE = 2;
const NAME_ERROR = 3;
const NOT_IMPLEMENTED = 4;
const REFUSED = 5;
}

View File

@ -0,0 +1,30 @@
<?php
declare (strict_types=1);
/**
* Enumeration of possible message types
*
* PHP version 5.4
*
* @category LibDNS
* @package Messages
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Messages;
use WP_Ultimo\Dependencies\LibDNS\Enumeration;
/**
* Enumeration of possible message types
*
* @category LibDNS
* @package Messages
* @author Chris Wright <https://github.com/DaveRandom>
*/
final class MessageTypes extends Enumeration
{
const QUERY = 0;
const RESPONSE = 1;
}

View File

@ -0,0 +1,76 @@
<?php
declare (strict_types=1);
/**
* Maintains a list of the relationships between domain name labels and the first point at
* which they appear in a packet
*
* PHP version 5.4
*
* @category LibDNS
* @package Packets
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Packets;
/**
* Creates Packet objects
*
* @category LibDNS
* @package Packets
* @author Chris Wright <https://github.com/DaveRandom>
*/
class LabelRegistry
{
/**
* @var int[] Map of labels to indexes
*/
private $labels = [];
/**
* @var string[][] Map of indexes to labels
*/
private $indexes = [];
/**
* Register a new relationship
*
* @param string|string[] $labels
* @param int $index
*/
public function register($labels, int $index)
{
if (\is_array($labels)) {
$labelsArr = $labels;
$labelsStr = \implode('.', $labels);
} else {
$labelsArr = \explode('.', $labels);
$labelsStr = (string) $labels;
}
if (!isset($this->labels[$labelsStr]) || $index < $this->labels[$labelsStr]) {
$this->labels[$labelsStr] = $index;
}
$this->indexes[$index] = $labelsArr;
}
/**
* Lookup the index of a label
*
* @param string $label
* @return int|null
*/
public function lookupIndex(string $label)
{
return $this->labels[$label] ?? null;
}
/**
* Lookup the label at an index
*
* @param int $index
* @return string[]|null
*/
public function lookupLabel(int $index)
{
return $this->indexes[$index] ?? null;
}
}

View File

@ -0,0 +1,120 @@
<?php
declare (strict_types=1);
/**
* Represents a raw network data packet
*
* PHP version 5.4
*
* @category LibDNS
* @package Packets
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Packets;
/**
* Represents a raw network data packet
*
* @category LibDNS
* @package Packets
* @author Chris Wright <https://github.com/DaveRandom>
*/
class Packet
{
/**
* @var string
*/
private $data;
/**
* @var int Data length
*/
private $length;
/**
* @var int Read pointer
*/
private $pointer = 0;
/**
* Constructor
*
* @param string $data The initial packet raw data
*/
public function __construct(string $data = '')
{
$this->data = $data;
$this->length = \strlen($this->data);
}
/**
* Read bytes from the packet data
*
* @param int $length The number of bytes to read
* @return string
* @throws \OutOfBoundsException When the pointer position is invalid or the supplied length is negative
*/
public function read(int $length = null) : string
{
if ($this->pointer > $this->length) {
throw new \OutOfBoundsException('Pointer position invalid');
}
if ($length === null) {
$result = \substr($this->data, $this->pointer);
$this->pointer = $this->length;
} else {
if ($length < 0) {
throw new \OutOfBoundsException('Length must be a positive integer');
}
$result = \substr($this->data, $this->pointer, $length);
$this->pointer += $length;
}
return $result;
}
/**
* Append data to the packet
*
* @param string $data The data to append
* @return int The number of bytes written
*/
public function write(string $data) : int
{
$length = \strlen($data);
$this->data .= $data;
$this->length += $length;
return $length;
}
/**
* Reset the read pointer
*/
public function reset()
{
$this->pointer = 0;
}
/**
* Get the pointer index
*
* @return int
*/
public function getPointer() : int
{
return $this->pointer;
}
/**
* Get the data length
*
* @return int
*/
public function getLength() : int
{
return $this->length;
}
/**
* Get the number of remaining bytes from the pointer position
*
* @return int
*/
public function getBytesRemaining() : int
{
return $this->length - $this->pointer;
}
}

View File

@ -0,0 +1,37 @@
<?php
declare (strict_types=1);
/**
* Creates Packet objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Packets
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Packets;
/**
* Creates Packet objects
*
* @category LibDNS
* @package Packets
* @author Chris Wright <https://github.com/DaveRandom>
*/
class PacketFactory
{
/**
* Create a new Packet object
*
* @param string $data
* @return \LibDNS\Packets\Packet
*/
public function create(string $data = '') : Packet
{
return new Packet($data);
}
}

View File

@ -0,0 +1,39 @@
<?php
declare (strict_types=1);
/**
* Represents a DNS question record
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\TypeFactory;
/**
* Represents a DNS question record
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class Question extends Record
{
/**
* Constructor
*
* @param \LibDNS\Records\Types\TypeFactory $typeFactory
* @param int $type Resource type being requested, can be indicated using the ResourceQTypes enum
*/
public function __construct(TypeFactory $typeFactory, int $type)
{
$this->typeFactory = $typeFactory;
$this->type = $type;
}
}

View File

@ -0,0 +1,38 @@
<?php
declare (strict_types=1);
/**
* Creates Question objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\TypeFactory;
/**
* Creates Question objects
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class QuestionFactory
{
/**
* Create a new Question object
*
* @param int $type The resource type
* @return \LibDNS\Records\Question
*/
public function create(int $type) : Question
{
return new Question(new TypeFactory(), $type);
}
}

View File

@ -0,0 +1,138 @@
<?php
declare (strict_types=1);
/**
* Represents the RDATA section of a resource record
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Type;
use WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions\TypeDefinition;
/**
* Represents a data type comprising multiple simple types
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class RData implements \IteratorAggregate, \Countable
{
/**
* @var \LibDNS\Records\Types\Type[] The items that make up the complex type
*/
private $fields = [];
/**
* @var \LibDNS\Records\TypeDefinitions\TypeDefinition Structural definition of the fields
*/
private $typeDef;
/**
* Constructor
*
* @param \LibDNS\Records\TypeDefinitions\TypeDefinition $typeDef
*/
public function __construct(TypeDefinition $typeDef)
{
$this->typeDef = $typeDef;
}
/**
* Magic method for type coersion to string
*
* @return string
*/
public function __toString()
{
if ($handler = $this->typeDef->getToStringFunction()) {
$result = \call_user_func_array($handler, $this->fields);
} else {
$result = \implode(',', $this->fields);
}
return $result;
}
/**
* Get the field indicated by the supplied index
*
* @param int $index
* @return \LibDNS\Records\Types\Type
* @throws \OutOfBoundsException When the supplied index does not refer to a valid field
*/
public function getField(int $index)
{
if (!isset($this->fields[$index])) {
throw new \OutOfBoundsException('Index ' . $index . ' does not refer to a valid field');
}
return $this->fields[$index];
}
/**
* Set the field indicated by the supplied index
*
* @param int $index
* @param \LibDNS\Records\Types\Type $value
* @throws \InvalidArgumentException When the supplied index/value pair does not match the type definition
*/
public function setField(int $index, Type $value)
{
if (!$this->typeDef->getFieldDefinition($index)->assertDataValid($value)) {
throw new \InvalidArgumentException('The supplied value is not valid for the specified index');
}
$this->fields[$index] = $value;
}
/**
* Get the field indicated by the supplied name
*
* @param string $name
* @return \LibDNS\Records\Types\Type
* @throws \OutOfBoundsException When the supplied name does not refer to a valid field
*/
public function getFieldByName(string $name) : Type
{
return $this->getField($this->typeDef->getFieldIndexByName($name));
}
/**
* Set the field indicated by the supplied name
*
* @param string $name
* @param \LibDNS\Records\Types\Type $value
* @throws \OutOfBoundsException When the supplied name does not refer to a valid field
* @throws \InvalidArgumentException When the supplied value does not match the type definition
*/
public function setFieldByName(string $name, Type $value)
{
$this->setField($this->typeDef->getFieldIndexByName($name), $value);
}
/**
* Get the structural definition of the fields
*
* @return \LibDNS\Records\TypeDefinitions\TypeDefinition
*/
public function getTypeDefinition() : TypeDefinition
{
return $this->typeDef;
}
/**
* Retrieve an iterator (IteratorAggregate interface)
*
* @return \Iterator
*/
public function getIterator() : \Iterator
{
return new \ArrayIterator($this->fields);
}
/**
* Get the number of fields (Countable interface)
*
* @return int
*/
public function count() : int
{
return \count($this->fields);
}
}

View File

@ -0,0 +1,62 @@
<?php
declare (strict_types=1);
/**
* Builds RData objects from a type definition
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions\TypeDefinition;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\TypeBuilder;
/**
* Creates RData objects
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class RDataBuilder
{
/**
* @var \LibDNS\Records\RDataFactory
*/
private $rDataFactory;
/**
* @var \LibDNS\Records\Types\TypeBuilder
*/
private $typeBuilder;
/**
* Constructor
*
* @param \LibDNS\Records\RDataFactory $rDataFactory
* @param \LibDNS\Records\Types\TypeBuilder $typeBuilder
*/
public function __construct(RDataFactory $rDataFactory, TypeBuilder $typeBuilder)
{
$this->rDataFactory = $rDataFactory;
$this->typeBuilder = $typeBuilder;
}
/**
* Create a new RData object
*
* @param \LibDNS\Records\TypeDefinitions\TypeDefinition $typeDefinition
* @return \LibDNS\Records\RData
*/
public function build(TypeDefinition $typeDefinition) : RData
{
$rData = $this->rDataFactory->create($typeDefinition);
foreach ($typeDefinition as $index => $type) {
$rData->setField($index, $this->typeBuilder->build($type->getType()));
}
return $rData;
}
}

View File

@ -0,0 +1,38 @@
<?php
declare (strict_types=1);
/**
* Creates RData objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions\TypeDefinition;
/**
* Creates RData objects
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class RDataFactory
{
/**
* Create a new RData object
*
* @param \LibDNS\Records\TypeDefinitions\TypeDefinition $typeDefinition
* @return \LibDNS\Records\RData
*/
public function create(TypeDefinition $typeDefinition) : RData
{
return new RData($typeDefinition);
}
}

View File

@ -0,0 +1,97 @@
<?php
declare (strict_types=1);
/**
* Represents a DNS record
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\DomainName;
/**
* Represents a DNS record
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
abstract class Record
{
/**
* @var \LibDNS\Records\Types\TypeFactory
*/
protected $typeFactory;
/**
* @var \LibDNS\Records\Types\DomainName
*/
protected $name;
/**
* @var int
*/
protected $type;
/**
* @var int
*/
protected $class = ResourceClasses::IN;
/**
* Get the value of the record name field
*
* @return \LibDNS\Records\Types\DomainName
*/
public function getName() : DomainName
{
return $this->name;
}
/**
* Set the value of the record name field
*
* @param string|\LibDNS\Records\Types\DomainName $name
* @throws \UnexpectedValueException When the supplied value is not a valid domain name
*/
public function setName($name)
{
if (!$name instanceof DomainName) {
$name = $this->typeFactory->createDomainName((string) $name);
}
$this->name = $name;
}
/**
* Get the value of the record type field
*
* @return int
*/
public function getType() : int
{
return $this->type;
}
/**
* Get the value of the record class field
*
* @return int
*/
public function getClass() : int
{
return $this->class;
}
/**
* Set the value of the record class field
*
* @param int $class The new value, can be indicated using the ResourceClasses/ResourceQClasses enums
* @throws \RangeException When the supplied value is outside the valid range 0 - 65535
*/
public function setClass(int $class)
{
if ($class < 0 || $class > 65535) {
throw new \RangeException('Record class must be in the range 0 - 65535');
}
$this->class = $class;
}
}

View File

@ -0,0 +1,219 @@
<?php
declare (strict_types=1);
/**
* Collection of Record objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
/**
* Collection of Record objects
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class RecordCollection implements \IteratorAggregate, \Countable
{
/**
* @var \LibDNS\Records\Record[] List of records held in the collection
*/
private $records = [];
/**
* @var \LibDNS\Records\Record[][] Map of Records in the collection grouped by record name
*/
private $nameMap = [];
/**
* @var int Number of Records in the collection
*/
private $length = 0;
/**
* @var int Whether the collection holds question or resource records
*/
private $type;
/**
* Constructor
*
* @param int $type Can be indicated using the RecordTypes enum
* @throws \InvalidArgumentException When the specified record type is invalid
*/
public function __construct($type)
{
if ($type !== RecordTypes::QUESTION && $type !== RecordTypes::RESOURCE) {
throw new \InvalidArgumentException('Record type must be QUESTION or RESOURCE');
}
$this->type = $type;
}
/**
* Add a record to the correct bucket in the name map
*
* @param \LibDNS\Records\Record $record The record to add
*/
private function addToNameMap(Record $record)
{
if (!isset($this->nameMap[$name = (string) $record->getName()])) {
$this->nameMap[$name] = [];
}
$this->nameMap[$name][] = $record;
}
/**
* Remove a record from the name map
*
* @param \LibDNS\Records\Record $record The record to remove
*/
private function removeFromNameMap(Record $record)
{
if (!empty($this->nameMap[$name = (string) $record->getName()])) {
foreach ($this->nameMap[$name] as $key => $item) {
if ($item === $record) {
\array_splice($this->nameMap[$name], $key, 1);
break;
}
}
}
if (empty($this->nameMap[$name])) {
unset($this->nameMap[$name]);
}
}
/**
* Add a record to the collection
*
* @param \LibDNS\Records\Record $record The record to add
* @throws \InvalidArgumentException When the wrong record type is supplied
*/
public function add(Record $record)
{
if ($this->type === RecordTypes::QUESTION && !$record instanceof Question || $this->type === RecordTypes::RESOURCE && !$record instanceof Resource) {
throw new \InvalidArgumentException('Incorrect record type for this collection');
}
$this->records[] = $record;
$this->addToNameMap($record);
$this->length++;
}
/**
* Remove a record from the collection
*
* @param \LibDNS\Records\Record $record The record to remove
*/
public function remove(Record $record)
{
foreach ($this->records as $key => $item) {
if ($item === $record) {
\array_splice($this->records, $key, 1);
$this->removeFromNameMap($record);
$this->length--;
return;
}
}
throw new \InvalidArgumentException('The supplied record is not a member of this collection');
}
/**
* Test whether the collection contains a specific record
*
* @param \LibDNS\Records\Record $record The record to search for
* @param bool $sameInstance Whether to perform strict comparisons in search
* @return bool
*/
public function contains(Record $record, bool $sameInstance = \false) : bool
{
return \in_array($record, $this->records, $sameInstance);
}
/**
* Get all records in the collection that refer to the specified name
*
* @param string $name The name to match records against
* @return \LibDNS\Records\Record[]
*/
public function getRecordsByName(string $name) : array
{
return $this->nameMap[\strtolower($name)] ?? [];
}
/**
* Get a record from the collection by index
*
* @param int $index Record index
* @return \LibDNS\Records\Record
* @throws \OutOfBoundsException When the supplied index does not refer to a valid record
*/
public function getRecordByIndex(int $index) : Record
{
if (isset($this->records[$index])) {
return $this->records[$index];
}
throw new \OutOfBoundsException('The specified index ' . $index . ' does not exist in the collection');
}
/**
* Remove all records in the collection that refer to the specified name
*
* @param string $name The name to match records against
* @return int The number of records removed
*/
public function clearRecordsByName(string $name) : int
{
$count = 0;
if (isset($this->nameMap[$name = \strtolower($name)])) {
unset($this->nameMap[$name]);
foreach ($this->records as $index => $record) {
if ($record->getName() === $name) {
unset($this->records[$index]);
$count++;
}
}
$this->records = \array_values($this->records);
}
return $count;
}
/**
* Remove all records from the collection
*/
public function clear()
{
$this->records = $this->nameMap = [];
$this->length = 0;
}
/**
* Get a list of all names referenced by records in the collection
*
* @return string[]
*/
public function getNames() : array
{
return \array_keys($this->nameMap);
}
/**
* Get whether the collection holds question or resource records
*
* @return int
*/
public function getType() : int
{
return $this->type;
}
/**
* Retrieve an iterator (IteratorAggregate interface)
*
* @return \Iterator
*/
public function getIterator() : \Iterator
{
return new \ArrayIterator($this->records);
}
/**
* Get the number of records in the collection (Countable interface)
*
* @return int
*/
public function count() : int
{
return $this->length;
}
}

View File

@ -0,0 +1,38 @@
<?php
declare (strict_types=1);
/**
* Creates RecordCollection objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
/**
* Creates RecordCollection objects
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class RecordCollectionFactory
{
/**
* Create a new RecordCollection object
*
* @param int $type Can be indicated using the RecordTypes enum
* @return \LibDNS\Records\RecordCollection
* @throws \InvalidArgumentException When the specified record type is invalid
*/
public function create(int $type) : RecordCollection
{
return new RecordCollection($type);
}
}

View File

@ -0,0 +1,30 @@
<?php
declare (strict_types=1);
/**
* Enumeration of possible record types
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Enumeration;
/**
* Enumeration of possible record types
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
final class RecordTypes extends Enumeration
{
const QUESTION = 0;
const RESOURCE = 1;
}

View File

@ -0,0 +1,80 @@
<?php
declare (strict_types=1);
/**
* Represents a DNS resource record
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\TypeFactory;
/**
* Represents a DNS resource record
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class Resource extends Record
{
/**
* @var int Value of the resource's time-to-live property
*/
private $ttl;
/**
* @var \LibDNS\Records\RData
*/
private $data;
/**
* Constructor
*
* @param \LibDNS\Records\Types\TypeFactory $typeFactory
* @param int $type Can be indicated using the ResourceTypes enum
* @param \LibDNS\Records\RData $data
*/
public function __construct(TypeFactory $typeFactory, int $type, RData $data)
{
$this->typeFactory = $typeFactory;
$this->type = $type;
$this->data = $data;
}
/**
* Get the value of the record TTL field
*
* @return int
*/
public function getTTL() : int
{
return $this->ttl;
}
/**
* Set the value of the record TTL field
*
* @param int $ttl The new value
* @throws \RangeException When the supplied value is outside the valid range 0 - 4294967296
*/
public function setTTL(int $ttl)
{
if ($ttl < 0 || $ttl > 4294967296) {
throw new \RangeException('Record class must be in the range 0 - 4294967296');
}
$this->ttl = $ttl;
}
/**
* Get the value of the resource data field
*
* @return \LibDNS\Records\RData
*/
public function getData() : RData
{
return $this->data;
}
}

View File

@ -0,0 +1,65 @@
<?php
declare (strict_types=1);
/**
* Builds Resource objects of a specific type
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions\TypeDefinitionManager;
/**
* Builds Resource objects of a specific type
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class ResourceBuilder
{
/**
* @var \LibDNS\Records\ResourceFactory
*/
private $resourceFactory;
/**
* @var \LibDNS\Records\RDataBuilder
*/
private $rDataBuilder;
/**
* @var \LibDNS\Records\TypeDefinitions\TypeDefinitionManager
*/
private $typeDefinitionManager;
/**
* Constructor
*
* @param \LibDNS\Records\ResourceFactory $resourceFactory
* @param \LibDNS\Records\RDataBuilder $rDataBuilder
* @param \LibDNS\Records\TypeDefinitions\TypeDefinitionManager $typeDefinitionManager
*/
public function __construct(ResourceFactory $resourceFactory, RDataBuilder $rDataBuilder, TypeDefinitionManager $typeDefinitionManager)
{
$this->resourceFactory = $resourceFactory;
$this->rDataBuilder = $rDataBuilder;
$this->typeDefinitionManager = $typeDefinitionManager;
}
/**
* Create a new Resource object
*
* @param int $type Type of the resource, can be indicated using the ResourceTypes enum
* @return \LibDNS\Records\Resource
*/
public function build(int $type) : Resource
{
$typeDefinition = $this->typeDefinitionManager->getTypeDefinition($type);
$rData = $this->rDataBuilder->build($typeDefinition);
return $this->resourceFactory->create($type, $rData);
}
}

View File

@ -0,0 +1,42 @@
<?php
declare (strict_types=1);
/**
* Creates ResourceBuilder objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\TypeBuilder;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\TypeFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions\TypeDefinitionManager;
use WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions\TypeDefinitionFactory;
use WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions\FieldDefinitionFactory;
/**
* Creates ResourceBuilder objects
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class ResourceBuilderFactory
{
/**
* Create a new ResourceBuilder object
*
* @param \LibDNS\Records\TypeDefinitions\TypeDefinitionManager $typeDefinitionManager
* @return \LibDNS\Records\ResourceBuilder
*/
public function create(TypeDefinitionManager $typeDefinitionManager = null) : ResourceBuilder
{
return new ResourceBuilder(new ResourceFactory(), new RDataBuilder(new RDataFactory(), new TypeBuilder(new TypeFactory())), $typeDefinitionManager ?: new TypeDefinitionManager(new TypeDefinitionFactory(), new FieldDefinitionFactory()));
}
}

View File

@ -0,0 +1,32 @@
<?php
declare (strict_types=1);
/**
* Enumeration of possible resource CLASS values
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Enumeration;
/**
* Enumeration of possible resource CLASS values
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
abstract class ResourceClasses extends Enumeration
{
const IN = 1;
const CS = 2;
const CH = 3;
const HS = 4;
}

View File

@ -0,0 +1,39 @@
<?php
declare (strict_types=1);
/**
* Creates Resource objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\TypeFactory;
/**
* Creates Resource objects
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
class ResourceFactory
{
/**
* Create a new Resource object
*
* @param int $type Can be indicated using the ResourceTypes enum
* @param \LibDNS\Records\RData $data
* @return \LibDNS\Records\Resource
*/
public function create(int $type, RData $data) : Resource
{
return new Resource(new TypeFactory(), $type, $data);
}
}

View File

@ -0,0 +1,28 @@
<?php
declare (strict_types=1);
/**
* Enumeration of possible resource QCLASS values
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
/**
* Enumeration of possible resource QCLASS values
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
final class ResourceQClasses extends ResourceClasses
{
const ANY = 255;
}

View File

@ -0,0 +1,31 @@
<?php
declare (strict_types=1);
/**
* Enumeration of possible resource QTYPE values
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
/**
* Enumeration of possible resource QTYPE values
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
final class ResourceQTypes extends ResourceTypes
{
const AXFR = 252;
const MAILB = 253;
const MAILA = 254;
const ALL = 255;
}

View File

@ -0,0 +1,71 @@
<?php
declare (strict_types=1);
/**
* Enumeration of possible resource TYPE values
*
* PHP version 5.4
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records;
use WP_Ultimo\Dependencies\LibDNS\Enumeration;
/**
* Enumeration of possible resource TYPE values
*
* @category LibDNS
* @package Records
* @author Chris Wright <https://github.com/DaveRandom>
*/
abstract class ResourceTypes extends Enumeration
{
const A = 1;
const AAAA = 28;
const AFSDB = 18;
// const APL = 42;
const CAA = 257;
const CERT = 37;
const CNAME = 5;
const DHCID = 49;
const DLV = 32769;
const DNAME = 39;
const DNSKEY = 48;
const DS = 43;
const HINFO = 13;
// const HIP = 55;
// const IPSECKEY = 45;
const KEY = 25;
const KX = 36;
const ISDN = 20;
const LOC = 29;
const MB = 7;
const MD = 3;
const MF = 4;
const MG = 8;
const MINFO = 14;
const MR = 9;
const MX = 15;
const NAPTR = 35;
const NS = 2;
// const NSEC = 47;
// const NSEC3 = 50;
// const NSEC3PARAM = 50;
const NULL = 10;
const PTR = 12;
const RP = 17;
// const RRSIG = 46;
const RT = 21;
const SIG = 24;
const SOA = 6;
const SPF = 99;
const SRV = 33;
const TXT = 16;
const WKS = 11;
const X25 = 19;
}

View File

@ -0,0 +1,130 @@
<?php
declare (strict_types=1);
/**
* Defines a field in a type
*
* PHP version 5.4
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Type;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Anything;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\BitMap;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Char;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\CharacterString;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\DomainName;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\IPv4Address;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\IPv6Address;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Long;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Short;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Types;
/**
* Defines a field in a type
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
*/
class FieldDefinition
{
/**
* @var int
*/
private $index;
/**
* @var string
*/
private $name;
/**
* @var int
*/
private $type;
/**
* @var bool
*/
private $allowsMultiple;
/**
* @var int
*/
private $minimumValues;
/**
* Constructor
*
* @param int $index
* @param string $name
* @param int $type
* @param bool $allowsMultiple
* @param int $minimumValues
*/
public function __construct(int $index, string $name, int $type, bool $allowsMultiple, int $minimumValues)
{
$this->index = $index;
$this->name = $name;
$this->type = $type;
$this->allowsMultiple = $allowsMultiple;
$this->minimumValues = $minimumValues;
}
/**
* Get the index of the field in the containing type
*
* @return int
*/
public function getIndex() : int
{
return $this->index;
}
/**
* Get the name of the field
*
* @return string
*/
public function getName() : string
{
return $this->name;
}
/**
* Get the type of the field
*
* @return int
*/
public function getType() : int
{
return $this->type;
}
/**
* Determine whether the field allows multiple values
*
* @return bool
*/
public function allowsMultiple() : bool
{
return $this->allowsMultiple;
}
/**
* Get the minimum number of values for the field
*
* @return int
*/
public function getMinimumValues() : int
{
return $this->minimumValues;
}
/**
* Assert that a Type object is valid for this field
*
* @param \LibDNS\Records\Types\Type
* @return bool
*/
public function assertDataValid(Type $value) : bool
{
return $this->type & Types::ANYTHING && $value instanceof Anything || $this->type & Types::BITMAP && $value instanceof BitMap || $this->type & Types::CHAR && $value instanceof Char || $this->type & Types::CHARACTER_STRING && $value instanceof CharacterString || $this->type & Types::DOMAIN_NAME && $value instanceof DomainName || $this->type & Types::IPV4_ADDRESS && $value instanceof IPv4Address || $this->type & Types::IPV6_ADDRESS && $value instanceof IPv6Address || $this->type & Types::LONG && $value instanceof Long || $this->type & Types::SHORT && $value instanceof Short;
}
}

View File

@ -0,0 +1,41 @@
<?php
declare (strict_types=1);
/**
* Creates FieldDefinition objects
*
* PHP version 5.4
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions;
/**
* Creates FieldDefinition objects
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
*/
class FieldDefinitionFactory
{
/**
* Create a new FieldDefinition object
*
* @param int $index
* @param string $name
* @param int $type
* @param bool $allowsMultiple
* @param int $minimumValues
* @return \LibDNS\Records\TypeDefinitions\FieldDefinition
*/
public function create(int $index, string $name, int $type, bool $allowsMultiple, int $minimumValues) : FieldDefinition
{
return new FieldDefinition($index, $name, $type, $allowsMultiple, $minimumValues);
}
}

View File

@ -0,0 +1,177 @@
<?php
declare (strict_types=1);
/**
* Defines a data type comprising multiple fields
*
* PHP version 5.4
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions;
/**
* Defines a data type comprising multiple fields
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
*/
class TypeDefinition implements \IteratorAggregate, \Countable
{
/**
* @var FieldDefinitionFactory Creates FieldDefinition objects
*/
private $fieldDefFactory;
/**
* @var int Number of fields in the type
*/
private $fieldCount;
/**
* @var \LibDNS\Records\TypeDefinitions\FieldDefinition The last field defined by the type
*/
private $lastField;
/**
* @var int[] Map of field indexes to type identifiers
*/
private $fieldDefs = [];
/**
* @var int[] Map of field names to indexes
*/
private $fieldNameMap = [];
/**
* @var callable Custom implementation for __toString() handling
*/
private $toStringFunction;
/**
* Constructor
*
* @param FieldDefinitionFactory $fieldDefFactory
* @param array $definition Structural definition of the fields
* @throws \InvalidArgumentException When the type definition is invalid
*/
public function __construct(FieldDefinitionFactory $fieldDefFactory, array $definition)
{
$this->fieldDefFactory = $fieldDefFactory;
if (isset($definition['__toString'])) {
if (!\is_callable($definition['__toString'])) {
throw new \InvalidArgumentException('Invalid type definition: __toString() implementation is not callable');
}
$this->toStringFunction = $definition['__toString'];
unset($definition['__toString']);
}
$this->fieldCount = \count($definition);
$index = 0;
foreach ($definition as $name => $type) {
$this->registerField($index++, $name, $type);
}
}
/**
* Register a field from the type definition
*
* @param int $index
* @param string $name
* @param int $type
* @throws \InvalidArgumentException When the field definition is invalid
*/
private function registerField(int $index, string $name, int $type)
{
if (!\preg_match('/^(?P<name>[\\w\\-]+)(?P<quantifier>\\+|\\*)?(?P<minimum>(?<=\\+)\\d+)?$/', \strtolower($name), $matches)) {
throw new \InvalidArgumentException('Invalid field definition ' . $name . ': Syntax error');
}
if (isset($matches['quantifier'])) {
if ($index !== $this->fieldCount - 1) {
throw new \InvalidArgumentException('Invalid field definition ' . $name . ': Quantifiers only allowed in last field');
}
if (!isset($matches['minimum'])) {
$matches['minimum'] = $matches['quantifier'] === '+' ? 1 : 0;
}
$allowsMultiple = \true;
$minimumValues = (int) $matches['minimum'];
} else {
$allowsMultiple = \false;
$minimumValues = 0;
}
$this->fieldDefs[$index] = $this->fieldDefFactory->create($index, $matches['name'], $type, $allowsMultiple, $minimumValues);
if ($index === $this->fieldCount - 1) {
$this->lastField = $this->fieldDefs[$index];
}
$this->fieldNameMap[$matches['name']] = $index;
}
/**
* Get the field definition indicated by the supplied index
*
* @param int $index
* @return \LibDNS\Records\TypeDefinitions\FieldDefinition
* @throws \OutOfBoundsException When the supplied index does not refer to a valid field
*/
public function getFieldDefinition(int $index) : FieldDefinition
{
if (isset($this->fieldDefs[$index])) {
$fieldDef = $this->fieldDefs[$index];
} else {
if ($index >= 0 && $this->lastField->allowsMultiple()) {
$fieldDef = $this->lastField;
} else {
throw new \OutOfBoundsException('Index ' . $index . ' does not refer to a valid field');
}
}
return $fieldDef;
}
/**
* Get the field index indicated by the supplied name
*
* @param string $name
* @return int
* @throws \OutOfBoundsException When the supplied name does not refer to a valid field
*/
public function getFieldIndexByName($name) : int
{
$fieldName = \strtolower($name);
if (!isset($this->fieldNameMap[$fieldName])) {
throw new \OutOfBoundsException('Name ' . $name . ' does not refer to a valid field');
}
return $this->fieldNameMap[$fieldName];
}
/**
* Get the __toString() implementation
*
* @return callable|null
*/
public function getToStringFunction()
{
return $this->toStringFunction;
}
/**
* Set the __toString() implementation
*
* @param callable $function
*/
public function setToStringFunction(callable $function)
{
$this->toStringFunction = $function;
}
/**
* Retrieve an iterator (IteratorAggregate interface)
*
* @return \Iterator
*/
public function getIterator() : \Iterator
{
return new \ArrayIterator($this->fieldDefs);
}
/**
* Get the number of fields (Countable interface)
*
* @return int
*/
public function count() : int
{
return $this->fieldCount;
}
}

View File

@ -0,0 +1,39 @@
<?php
declare (strict_types=1);
/**
* Creates TypeDefinition objects
*
* PHP version 5.4
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions;
/**
* Creates TypeDefinition objects
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
*/
class TypeDefinitionFactory
{
/**
* Create a new TypeDefinition object
*
* @param FieldDefinitionFactory $fieldDefinitionFactory
* @param int[] $definition Structural definition of the fields
* @return \LibDNS\Records\TypeDefinitions\TypeDefinition
* @throws \InvalidArgumentException When the type definition is invalid
*/
public function create(FieldDefinitionFactory $fieldDefinitionFactory, array $definition) : TypeDefinition
{
return new TypeDefinition($fieldDefinitionFactory, $definition);
}
}

View File

@ -0,0 +1,264 @@
<?php
declare (strict_types=1);
/**
* Holds data about how the RDATA sections of known resource record types are structured
*
* PHP version 5.4
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions;
use WP_Ultimo\Dependencies\LibDNS\Records\ResourceTypes;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\Types;
use WP_Ultimo\Dependencies\LibDNS\Records\Types\DomainName;
/**
* Holds data about how the RDATA sections of known resource record types are structured
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
*/
class TypeDefinitionManager
{
/**
* @var array[] How the RDATA sections of known resource record types are structured
*/
private $definitions = [];
/**
* @var array Cache of created definitions
*/
private $typeDefs = [];
/**
* @var \LibDNS\Records\TypeDefinitions\TypeDefinitionFactory
*/
private $typeDefFactory;
/**
* @var \LibDNS\Records\TypeDefinitions\FieldDefinitionFactory
*/
private $fieldDefFactory;
/**
* Constructor
*
* @param \LibDNS\Records\TypeDefinitions\TypeDefinitionFactory $typeDefFactory
* @param \LibDNS\Records\TypeDefinitions\FieldDefinitionFactory $fieldDefFactory
*/
public function __construct(TypeDefinitionFactory $typeDefFactory, FieldDefinitionFactory $fieldDefFactory)
{
$this->typeDefFactory = $typeDefFactory;
$this->fieldDefFactory = $fieldDefFactory;
$this->setDefinitions();
}
/**
* Set the internal definitions structure
*/
private function setDefinitions()
{
// This is defined in a method because PHP doesn't let you define properties with
// expressions at the class level. If anyone has a better way to do this I am open
// to any and all suggestions.
$this->definitions = [ResourceTypes::A => [
// RFC 1035
'address' => Types::IPV4_ADDRESS,
], ResourceTypes::AAAA => [
// RFC 3596
'address' => Types::IPV6_ADDRESS,
], ResourceTypes::AFSDB => [
// RFC 1183
'subtype' => Types::SHORT,
'hostname' => Types::DOMAIN_NAME,
], ResourceTypes::CAA => [
// RFC 6844
'flags' => Types::DOMAIN_NAME,
'tag' => Types::CHARACTER_STRING,
'value' => Types::ANYTHING,
], ResourceTypes::CERT => [
// RFC 4398
'type' => Types::SHORT,
'key-tag' => Types::SHORT,
'algorithm' => Types::CHAR,
'certificate' => Types::ANYTHING,
], ResourceTypes::CNAME => [
// RFC 1035
'cname' => Types::DOMAIN_NAME,
], ResourceTypes::DHCID => [
// RFC 4701
'identifier-type' => Types::SHORT,
'digest-type' => Types::CHAR,
'digest' => Types::ANYTHING,
], ResourceTypes::DLV => [
// RFC 4034
'key-tag' => Types::SHORT,
'algorithm' => Types::CHAR,
'digest-type' => Types::CHAR,
'digest' => Types::ANYTHING,
], ResourceTypes::DNAME => [
// RFC 4034
'target' => Types::DOMAIN_NAME,
], ResourceTypes::DNSKEY => [
// RFC 6672
'flags' => Types::SHORT,
'protocol' => Types::CHAR,
'algorithm' => Types::CHAR,
'public-key' => Types::ANYTHING,
], ResourceTypes::DS => [
// RFC 4034
'key-tag' => Types::SHORT,
'algorithm' => Types::CHAR,
'digest-type' => Types::CHAR,
'digest' => Types::ANYTHING,
], ResourceTypes::HINFO => [
// RFC 1035
'cpu' => Types::CHARACTER_STRING,
'os' => Types::CHARACTER_STRING,
], ResourceTypes::ISDN => [
// RFC 1183
'isdn-address' => Types::CHARACTER_STRING,
'sa' => Types::CHARACTER_STRING,
], ResourceTypes::KEY => [
// RFC 2535
'flags' => Types::SHORT,
'protocol' => Types::CHAR,
'algorithm' => Types::CHAR,
'public-key' => Types::ANYTHING,
], ResourceTypes::KX => [
// RFC 2230
'preference' => Types::SHORT,
'exchange' => Types::DOMAIN_NAME,
], ResourceTypes::LOC => [
// RFC 1876
'version' => Types::CHAR,
'size' => Types::CHAR,
'horizontal-precision' => Types::CHAR,
'vertical-precision' => Types::CHAR,
'latitude' => Types::LONG,
'longitude' => Types::LONG,
'altitude' => Types::LONG,
], ResourceTypes::MB => [
// RFC 1035
'madname' => Types::DOMAIN_NAME,
], ResourceTypes::MD => [
// RFC 1035
'madname' => Types::DOMAIN_NAME,
], ResourceTypes::MF => [
// RFC 1035
'madname' => Types::DOMAIN_NAME,
], ResourceTypes::MG => [
// RFC 1035
'mgmname' => Types::DOMAIN_NAME,
], ResourceTypes::MINFO => [
// RFC 1035
'rmailbx' => Types::DOMAIN_NAME,
'emailbx' => Types::DOMAIN_NAME,
], ResourceTypes::MR => [
// RFC 1035
'newname' => Types::DOMAIN_NAME,
], ResourceTypes::MX => [
// RFC 1035
'preference' => Types::SHORT,
'exchange' => Types::DOMAIN_NAME,
], ResourceTypes::NAPTR => [
// RFC 3403
'order' => Types::SHORT,
'preference' => Types::SHORT,
'flags' => Types::CHARACTER_STRING,
'services' => Types::CHARACTER_STRING,
'regexp' => Types::CHARACTER_STRING,
'replacement' => Types::DOMAIN_NAME,
], ResourceTypes::NS => [
// RFC 1035
'nsdname' => Types::DOMAIN_NAME,
], ResourceTypes::NULL => [
// RFC 1035
'data' => Types::ANYTHING,
], ResourceTypes::PTR => [
// RFC 1035
'ptrdname' => Types::DOMAIN_NAME,
], ResourceTypes::RP => [
// RFC 1183
'mbox-dname' => Types::DOMAIN_NAME,
'txt-dname' => Types::DOMAIN_NAME,
], ResourceTypes::RT => [
// RFC 1183
'preference' => Types::SHORT,
'intermediate-host' => Types::DOMAIN_NAME,
], ResourceTypes::SIG => [
// RFC 4034
'type-covered' => Types::SHORT,
'algorithm' => Types::CHAR,
'labels' => Types::CHAR,
'original-ttl' => Types::LONG,
'signature-expiration' => Types::LONG,
'signature-inception' => Types::LONG,
'key-tag' => Types::SHORT,
'signers-name' => Types::DOMAIN_NAME,
'signature' => Types::ANYTHING,
], ResourceTypes::SOA => [
// RFC 1035
'mname' => Types::DOMAIN_NAME,
'rname' => Types::DOMAIN_NAME,
'serial' => Types::LONG,
'refresh' => Types::LONG,
'retry' => Types::LONG,
'expire' => Types::LONG,
'minimum' => Types::LONG,
], ResourceTypes::SPF => [
// RFC 4408
'data+' => Types::CHARACTER_STRING,
], ResourceTypes::SRV => [
// RFC 2782
'priority' => Types::SHORT,
'weight' => Types::SHORT,
'port' => Types::SHORT,
'name' => Types::DOMAIN_NAME | DomainName::FLAG_NO_COMPRESSION,
], ResourceTypes::TXT => [
// RFC 1035
'txtdata+' => Types::CHARACTER_STRING,
], ResourceTypes::WKS => [
// RFC 1035
'address' => Types::IPV4_ADDRESS,
'protocol' => Types::SHORT,
'bit-map' => Types::BITMAP,
], ResourceTypes::X25 => [
// RFC 1183
'psdn-address' => Types::CHARACTER_STRING,
]];
}
/**
* Get a type definition for a record type if it is known
*
* @param int $recordType Resource type, can be indicated using the ResourceTypes enum
* @return \LibDNS\Records\TypeDefinitions\TypeDefinition
*/
public function getTypeDefinition(int $recordType)
{
if (!isset($this->typeDefs[$recordType])) {
$definition = isset($this->definitions[$recordType]) ? $this->definitions[$recordType] : ['data' => Types::ANYTHING];
$this->typeDefs[$recordType] = $this->typeDefFactory->create($this->fieldDefFactory, $definition);
}
return $this->typeDefs[$recordType];
}
/**
* Register a custom type definition
*
* @param int $recordType Resource type, can be indicated using the ResourceTypes enum
* @param int[]|\LibDNS\Records\TypeDefinitions\TypeDefinition $definition
* @throws \InvalidArgumentException When the type definition is invalid
*/
public function registerTypeDefinition(int $recordType, $definition)
{
if (!$definition instanceof TypeDefinition) {
if (!\is_array($definition)) {
throw new \InvalidArgumentException('Definition must be an array or an instance of ' . __NAMESPACE__ . '\\TypeDefinition');
}
$definition = $this->typeDefFactory->create($this->fieldDefFactory, $definition);
}
$this->typeDefs[$recordType] = $definition;
}
}

View File

@ -0,0 +1,36 @@
<?php
declare (strict_types=1);
/**
* Creates TypeDefinitionManager objects
*
* PHP version 5.4
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\TypeDefinitions;
/**
* Creates TypeDefinitionManager objects
*
* @category LibDNS
* @package TypeDefinitions
* @author Chris Wright <https://github.com/DaveRandom>
*/
class TypeDefinitionManagerFactory
{
/**
* Create a new TypeDefinitionManager object
*
* @return \LibDNS\Records\TypeDefinitions\TypeDefinitionManager
*/
public function create() : TypeDefinitionManager
{
return new TypeDefinitionManager(new TypeDefinitionFactory(), new FieldDefinitionFactory());
}
}

View File

@ -0,0 +1,45 @@
<?php
declare (strict_types=1);
/**
* Represents a generic binary data string
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Represents a generic binary data string
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class Anything extends Type
{
/**
* @var string
*/
protected $value = '';
/**
* Set the internal value
*
* @param string $value The new value
* @throws \UnexpectedValueException When the supplied value is outside the valid length range 0 - 65535
*/
public function setValue($value)
{
$value = (string) $value;
if (\strlen($value) > 65535) {
throw new \UnexpectedValueException('Untyped string length must be in the range 0 - 65535');
}
$this->value = $value;
}
}

View File

@ -0,0 +1,63 @@
<?php
declare (strict_types=1);
/**
* Represents a bit map
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Represents a bit map
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class BitMap extends Type
{
/**
* @var string
*/
protected $value = '';
/**
* Set the internal value
*
* @param string $value The new value
*/
public function setValue($value)
{
$this->value = (string) $value;
}
/**
* Inspect the value of the bit at the specific index and optionally set a new value
*
* @param int $index
* @param bool $newValue The new value
* @return bool The old value
*/
public function isBitSet(int $index, bool $newValue = null) : bool
{
$charIndex = (int) ($index / 8);
$bitMask = 0b10000000 >> $index % 8;
$result = \false;
if (isset($this->value[$charIndex])) {
$result = (bool) (\ord($this->value[$charIndex]) & $bitMask);
}
if (isset($newValue) && $newValue != $result) {
if (!isset($this->value[$charIndex])) {
$this->value = \str_pad($this->value, $charIndex + 1, "\x00", \STR_PAD_RIGHT);
}
$this->value[$charIndex] = \chr(\ord($this->value[$charIndex]) & ~$bitMask | ($newValue ? $bitMask : 0));
}
return $result;
}
}

View File

@ -0,0 +1,50 @@
<?php
declare (strict_types=1);
/**
* Represents an 8-bit unsigned integer
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Represents an 8-bit unsigned integer
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class Char extends Type
{
/**
* @var int
*/
protected $value = 0;
/**
* Set the internal value
*
* @param string $value The new value
* @throws \UnderflowException When the supplied value is less than 0
* @throws \OverflowException When the supplied value is greater than 255
*/
public function setValue($value)
{
$value = (int) $value;
if ($value < 0) {
throw new \UnderflowException('Char value must be in the range 0 - 255');
} else {
if ($value > 255) {
throw new \OverflowException('Char value must be in the range 0 - 255');
}
}
$this->value = $value;
}
}

View File

@ -0,0 +1,45 @@
<?php
declare (strict_types=1);
/**
* Represents a binary character string
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Represents a binary character string
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class CharacterString extends Type
{
/**
* @var string
*/
protected $value = '';
/**
* Set the internal value
*
* @param string $value The new value
* @throws \UnexpectedValueException When the supplied value is outside the valid length range 0 - 255
*/
public function setValue($value)
{
$value = (string) $value;
if (\strlen($value) > 255) {
throw new \UnexpectedValueException('Character string length must be in the range 0 - 255');
}
$this->value = $value;
}
}

View File

@ -0,0 +1,104 @@
<?php
declare (strict_types=1);
/**
* Represents a fully qualified domain name
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Represents a fully qualified domain name
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class DomainName extends Type
{
const FLAG_NO_COMPRESSION = \PHP_INT_SIZE === 4 ? -2147483648 : 0x80000000;
/**
* @var string
*/
protected $value = '';
/**
* @var string[] The value as a list of labels
*/
private $labels = [];
/**
* Constructor
*
* @param string|string[] $value
* @throws \UnexpectedValueException When the supplied value is not a valid domain name
*/
public function __construct($value = null)
{
if (\is_array($value)) {
$this->setLabels($value);
} else {
parent::__construct($value);
}
}
/**
* Set the internal value
*
* @param string $value The new value
* @throws \UnexpectedValueException When the supplied value is not a valid domain name
*/
public function setValue($value)
{
$this->setLabels(\explode('.', (string) $value));
}
/**
* Get the domain name labels
*
* @param bool $tldFirst Whether to return the label list ordered with the TLD label first
* @return string[]
*/
public function getLabels($tldFirst = \false) : array
{
return $tldFirst ? \array_reverse($this->labels) : $this->labels;
}
/**
* Set the domain name labels
*
* @param string[] $labels The new label list
* @param bool $tldFirst Whether the supplied label list is ordered with the TLD label first
* @throws \UnexpectedValueException When the supplied label list is not a valid domain name
*/
public function setLabels(array $labels, $tldFirst = \false)
{
if (!$labels) {
$this->labels = [];
$this->value = '';
return;
}
$length = $count = 0;
foreach ($labels as &$label) {
$label = \WP_Ultimo\Dependencies\LibDNS\normalize_name($label);
$labelLength = \strlen($label);
if ($labelLength > 63) {
throw new \InvalidArgumentException('Label list is not a valid domain name: Label ' . $label . ' length exceeds 63 byte limit');
}
$length += $labelLength + 1;
$count++;
}
$tld = $tldFirst ? $labels[0] : $labels[$count - 1];
if ($tld === '') {
$length--;
}
if ($length + 1 > 255) {
throw new \InvalidArgumentException('Label list is not a valid domain name: Total length exceeds 255 byte limit');
}
$this->labels = $tldFirst ? \array_reverse($labels) : $labels;
$this->value = \implode('.', $this->labels);
}
}

View File

@ -0,0 +1,88 @@
<?php
declare (strict_types=1);
/**
* Represents an IPv4 address
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Represents an IPv4 address
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class IPv4Address extends Type
{
/**
* @var string
*/
protected $value = '0.0.0.0';
/**
* @var int[] The octets of the address
*/
private $octets = [0, 0, 0, 0];
/**
* Constructor
*
* @param string|int[] $value String representation or octet list
* @throws \UnexpectedValueException When the supplied value is not a valid IPv4 address
*/
public function __construct($value = null)
{
if (\is_array($value)) {
$this->setOctets($value);
} else {
parent::__construct($value);
}
}
/**
* Set the internal value
*
* @param string $value The new value
* @throws \UnexpectedValueException When the supplied value is outside the valid length range 0 - 65535
*/
public function setValue($value)
{
$this->setOctets(\explode('.', (string) $value));
}
/**
* Get the address octets
*
* @return int[]
*/
public function getOctets() : array
{
return $this->octets;
}
/**
* Set the address octets
*
* @param int[] $octets The new address octets
* @throws \UnexpectedValueException When the supplied octet list is not a valid IPv4 address
*/
public function setOctets(array $octets)
{
if (\count($octets) !== 4) {
throw new \UnexpectedValueException('Octet list is not a valid IPv4 address: invalid octet count');
}
foreach ($octets as &$octet) {
if (!\is_int($octet) && !\ctype_digit((string) $octet) || $octet < 0x0 || $octet > 0xff) {
throw new \UnexpectedValueException('Octet list is not a valid IPv4 address: invalid octet value ' . $octet);
}
$octet = (int) $octet;
}
$this->octets = \array_values($octets);
$this->value = \implode('.', $this->octets);
}
}

View File

@ -0,0 +1,152 @@
<?php
declare (strict_types=1);
/**
* Represents an IPv6 address
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Represents an IPv6 address
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class IPv6Address extends Type
{
/**
* @var string
*/
protected $value = '::';
/**
* @var int[] The shorts of the address
*/
private $shorts = [0, 0, 0, 0, 0, 0, 0, 0];
/**
* Create a compressed string representation of an IPv6 address
*
* @param int[] $shorts Address shorts
* @return string
*/
private function createCompressedString($shorts)
{
$compressLen = $compressPos = $currentLen = $currentPos = 0;
$inBlock = \false;
for ($i = 0; $i < 8; $i++) {
if ($shorts[$i] === 0) {
if (!$inBlock) {
$inBlock = \true;
$currentPos = $i;
}
$currentLen++;
} else {
if ($inBlock) {
if ($currentLen > $compressLen) {
$compressLen = $currentLen;
$compressPos = $currentPos;
}
$inBlock = \false;
$currentPos = $currentLen = 0;
}
}
$shorts[$i] = \dechex($shorts[$i]);
}
if ($inBlock) {
$compressLen = $currentLen;
$compressPos = $currentPos;
}
if ($compressLen > 1) {
if ($compressLen === 8) {
$replace = ['', '', ''];
} else {
if ($compressPos === 0 || $compressPos + $compressLen === 8) {
$replace = ['', ''];
} else {
$replace = [''];
}
}
\array_splice($shorts, $compressPos, $compressLen, $replace);
}
return \implode(':', $shorts);
}
/**
* Constructor
*
* @param string|int[] $value String representation or shorts list
* @throws \UnexpectedValueException When the supplied value is not a valid IPv6 address
*/
public function __construct($value = null)
{
if (\is_array($value)) {
$this->setShorts($value);
} else {
parent::__construct($value);
}
}
/**
* Set the internal value
*
* @param string $value The new value
* @throws \UnexpectedValueException When the supplied value is outside the valid length range 0 - 65535
*/
public function setValue($value)
{
$shorts = \explode(':', (string) $value);
$count = \count($shorts);
if ($count < 3 || $count > 8) {
throw new \UnexpectedValueException('Value is not a valid IPv6 address: invalid short count');
} else {
if ($shorts[0] === '' && $shorts[1] === '') {
$shorts = \array_pad($shorts, -8, '0');
} else {
if ($shorts[$count - 2] === '' && $shorts[$count - 1] === '') {
$shorts = \array_pad($shorts, 8, '0');
} else {
if (\false !== ($pos = \array_search('', $shorts, \true))) {
\array_splice($shorts, $pos, 1, \array_fill(0, 8 - ($count - 1), '0'));
}
}
}
}
$this->setShorts(\array_map('hexdec', $shorts));
}
/**
* Get the address shorts
*
* @return int[]
*/
public function getShorts() : array
{
return $this->shorts;
}
/**
* Set the address shorts
*
* @param int[] $shorts The new address shorts
* @throws \UnexpectedValueException When the supplied short list is not a valid IPv6 address
*/
public function setShorts(array $shorts)
{
if (\count($shorts) !== 8) {
throw new \UnexpectedValueException('Short list is not a valid IPv6 address: invalid short count');
}
foreach ($shorts as &$short) {
if (!\is_int($short) && !\ctype_digit((string) $short) || $short < 0x0 || $short > 0xffff) {
throw new \UnexpectedValueException('Short list is not a valid IPv6 address: invalid short value ' . $short);
}
$short = (int) $short;
}
$this->shorts = \array_values($shorts);
$this->value = $this->createCompressedString($this->shorts);
}
}

View File

@ -0,0 +1,52 @@
<?php
declare (strict_types=1);
/**
* Represents a 32-bit unsigned integer
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Represents a 32-bit unsigned integer
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class Long extends Type
{
/**
* @var int
*/
protected $value = 0;
/**
* Set the internal value
*
* @param string $value The new value
* @throws \UnderflowException When the supplied value is less than 0
* @throws \OverflowException When the supplied value is greater than 4294967296
*/
public function setValue($value)
{
$value = (int) $value;
if (\PHP_INT_SIZE > 4) {
if ($value < 0) {
throw new \UnderflowException('Long integer value must be in the range 0 - 4294967296');
} else {
if ($value > 0xffffffff) {
throw new \OverflowException('Long integer value must be in the range 0 - 4294967296');
}
}
}
$this->value = $value;
}
}

View File

@ -0,0 +1,50 @@
<?php
declare (strict_types=1);
/**
* Represents a 16-bit unsigned integer
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Represents a 16-bit unsigned integer
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class Short extends Type
{
/**
* @var int
*/
protected $value = 0;
/**
* Set the internal value
*
* @param string $value The new value
* @throws \UnderflowException When the supplied value is less than 0
* @throws \OverflowException When the supplied value is greater than 65535
*/
public function setValue($value)
{
$value = (int) $value;
if ($value < 0) {
throw new \UnderflowException('Short integer value must be in the range 0 - 65535');
} else {
if ($value > 0xffff) {
throw new \OverflowException('Short integer value must be in the range 0 - 65535');
}
}
$this->value = $value;
}
}

View File

@ -0,0 +1,68 @@
<?php
declare (strict_types=1);
/**
* Base class for simple data types
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Base class for simple data types
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
abstract class Type
{
/**
* @var mixed The internal value
*/
protected $value;
/**
* Constructor
*
* @param string $value Internal value
* @throws \RuntimeException When the supplied value is invalid
*/
public function __construct(string $value = null)
{
if (isset($value)) {
$this->setValue($value);
}
}
/**
* Magic method for type coercion to string
*
* @return string
*/
public function __toString() : string
{
return (string) $this->value;
}
/**
* Get the internal value
*
* @return mixed
*/
public function getValue()
{
return $this->value;
}
/**
* Set the internal value
*
* @param string $value The new value
* @throws \RuntimeException When the supplied value is invalid
*/
public abstract function setValue($value);
}

View File

@ -0,0 +1,54 @@
<?php
declare (strict_types=1);
/**
* Builds Types from type definitions
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Builds Types from type definitions
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class TypeBuilder
{
/**
* @var \LibDNS\Records\Types\TypeFactory
*/
private $typeFactory;
/**
* Constructor
*
* @param \LibDNS\Records\Types\TypeFactory $typeFactory
*/
public function __construct(TypeFactory $typeFactory)
{
$this->typeFactory = $typeFactory;
}
/**
* Build a new Type object corresponding to a resource record type
*
* @param int $type Data type, can be indicated using the Types enum
* @return \LibDNS\Records\Types\Type
*/
public function build(int $type) : Type
{
static $typeMap = [Types::ANYTHING => 'createAnything', Types::BITMAP => 'createBitMap', Types::CHAR => 'createChar', Types::CHARACTER_STRING => 'createCharacterString', Types::DOMAIN_NAME => 'createDomainName', Types::IPV4_ADDRESS => 'createIPv4Address', Types::IPV6_ADDRESS => 'createIPv6Address', Types::LONG => 'createLong', Types::SHORT => 'createShort'];
if (!isset($typeMap[$type])) {
throw new \InvalidArgumentException('Invalid Type identifier ' . $type);
}
return $this->typeFactory->{$typeMap[$type]}();
}
}

View File

@ -0,0 +1,117 @@
<?php
declare (strict_types=1);
/**
* Creates Type objects
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
/**
* Creates Type objects
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
class TypeFactory
{
/**
* Create a new Anything object
*
* @param string $value
* @return \LibDNS\Records\Types\Anything
*/
public function createAnything(string $value = null)
{
return new Anything($value);
}
/**
* Create a new BitMap object
*
* @param string $value
* @return \LibDNS\Records\Types\BitMap
*/
public function createBitMap(string $value = null)
{
return new BitMap($value);
}
/**
* Create a new Char object
*
* @param int $value
* @return \LibDNS\Records\Types\Char
*/
public function createChar(int $value = null)
{
return new Char((string) $value);
}
/**
* Create a new CharacterString object
*
* @param string $value
* @return \LibDNS\Records\Types\CharacterString
*/
public function createCharacterString(string $value = null)
{
return new CharacterString($value);
}
/**
* Create a new DomainName object
*
* @param string|string[] $value
* @return \LibDNS\Records\Types\DomainName
*/
public function createDomainName($value = null)
{
return new DomainName($value);
}
/**
* Create a new IPv4Address object
*
* @param string|int[] $value
* @return \LibDNS\Records\Types\IPv4Address
*/
public function createIPv4Address($value = null)
{
return new IPv4Address($value);
}
/**
* Create a new IPv6Address object
*
* @param string|int[] $value
* @return \LibDNS\Records\Types\IPv6Address
*/
public function createIPv6Address($value = null)
{
return new IPv6Address($value);
}
/**
* Create a new Long object
*
* @param int $value
* @return \LibDNS\Records\Types\Long
*/
public function createLong(int $value = null)
{
return new Long((string) $value);
}
/**
* Create a new Short object
*
* @param int $value
* @return \LibDNS\Records\Types\Short
*/
public function createShort(int $value = null)
{
return new Short((string) $value);
}
}

View File

@ -0,0 +1,37 @@
<?php
declare (strict_types=1);
/**
* Enumeration of simple data types
*
* PHP version 5.4
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 2.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Records\Types;
use WP_Ultimo\Dependencies\LibDNS\Enumeration;
/**
* Enumeration of simple data types
*
* @category LibDNS
* @package Types
* @author Chris Wright <https://github.com/DaveRandom>
*/
final class Types extends Enumeration
{
const ANYTHING = 0b1;
const BITMAP = 0b10;
const CHAR = 0b100;
const CHARACTER_STRING = 0b1000;
const DOMAIN_NAME = 0b10000;
const IPV4_ADDRESS = 0b100000;
const IPV6_ADDRESS = 0b1000000;
const LONG = 0b10000000;
const SHORT = 0b100000000;
}

View File

@ -0,0 +1,22 @@
<?php
declare (strict_types=1);
namespace WP_Ultimo\Dependencies\LibDNS;
if (\function_exists('idn_to_ascii')) {
function normalize_name(string $label) : string
{
if (\false === ($result = \idn_to_ascii($label, 0, \INTL_IDNA_VARIANT_UTS46))) {
throw new \InvalidArgumentException("Label '{$label}' could not be processed for IDN");
}
return $result;
}
} else {
function normalize_name(string $label) : string
{
if (\preg_match('/[\\x80-\\xff]/', $label)) {
throw new \InvalidArgumentException("Label '{$label}' contains non-ASCII characters and IDN support is not available." . " Verify that ext/intl is installed for IDN support.");
}
return \strtolower($label);
}
}

View File

@ -0,0 +1,81 @@
<?php
/**
* Generates a class-map based autoloader file for the examples directory
*
* PHP version 5.4
*
* @category LibDNS
* @package Tools
* @author Chris Wright <https://github.com/DaveRandom>
* @copyright Copyright (c) Chris Wright <https://github.com/DaveRandom>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 1.0.0
*/
namespace WP_Ultimo\Dependencies\LibDNS\Tools;
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
use FilesystemIterator;
\error_reporting(0);
\ini_set('display_errors', 0);
if (!isset($argv[1])) {
$srcDir = \getcwd();
} else {
if (\in_array(\strtolower($argv[1]), ['--help', '?', '/?'])) {
exit("Syntax: " . __FILE__ . " [source directory]\n");
} else {
if (!\is_dir($srcDir = $argv[1])) {
exit("Invalid source directory\n\nSyntax: " . __FILE__ . " [source directory]\n");
}
}
}
$srcDir = \str_replace('\\', '/', $srcDir);
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($srcDir, FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS));
$items = [];
$stripLength = \strlen($srcDir) + 1;
$maxLength = 0;
foreach ($iterator as $item) {
if ($item->isFile() && $item->getFilename() !== 'autoload.php' && \strtolower($item->getExtension()) === 'php') {
$classPath = \substr($item->getPath() . '\\' . $item->getBasename('.' . $item->getExtension()), $stripLength);
$lookupName = \strtolower(\str_replace('/', '\\', $classPath));
$loadPath = "__DIR__ . '/{$srcDir}/" . \str_replace('\\', '/', $classPath) . ".php'";
$length = \strlen($classPath);
if ($length > $maxLength) {
$maxLength = $length;
}
$items[$lookupName] = $loadPath;
}
}
unset($iterator);
$output = <<<'PHP'
<?php
/**
* This file was automatically generated by autoload_generator.php
*
* Do not edit this file directly
*/
spl_autoload_register(function($className) {
static $classMap;
if (!isset($classMap)) {
$classMap = [
PHP;
$maxLength += 2;
foreach ($items as $lookupName => $loadPath) {
$output .= "\n " . \str_pad("'" . $lookupName . "'", $maxLength, ' ', \STR_PAD_RIGHT) . " => {$loadPath},";
}
$output .= <<<'PHP'
];
}
$className = strtolower($className);
if (isset($classMap[$className])) {
/** @noinspection PhpIncludeInspection */
require $classMap[$className];
}
});
PHP;
\file_put_contents(\getcwd() . '/autoload.php', $output);