Пример #1
0
 /**
  * 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)
 {
     $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);
             }
         }
     }
     if (!$labels) {
         throw new \UnexpectedValueException('Decode error: Empty 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;
 }
Пример #2
0
 /**
  * Encode a DomainName field
  *
  * @param \LibDNS\Records\Types\DomainName $domainName
  * @param \LibDNS\Encoder\EncodingContext $encodingContext
  * @return string
  */
 private function encodeDomainName(DomainName $domainName, EncodingContext $encodingContext)
 {
     $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 .= "";
         }
     } else {
         foreach ($labels as $label) {
             $result .= chr(strlen($label)) . $label;
         }
         $result .= "";
     }
     return $result;
 }