mirror of
https://github.com/danog/dns.git
synced 2025-01-23 05:51:11 +01:00
Merge branch '0.1' into 0.2
This commit is contained in:
commit
d4257d132f
@ -7,4 +7,5 @@ class AddressModes
|
|||||||
const INET4_ADDR = 1;
|
const INET4_ADDR = 1;
|
||||||
const INET6_ADDR = 2;
|
const INET6_ADDR = 2;
|
||||||
const PREFER_INET6 = 4;
|
const PREFER_INET6 = 4;
|
||||||
|
const CNAME = 8;
|
||||||
}
|
}
|
||||||
|
@ -206,24 +206,41 @@ class Client
|
|||||||
{
|
{
|
||||||
$packet = fread($this->socket, 512);
|
$packet = fread($this->socket, 512);
|
||||||
|
|
||||||
$response = $this->responseInterpreter->interpret($packet);
|
// Decode the response and clean up the pending requests list
|
||||||
if ($response === null) {
|
$decoded = $this->responseInterpreter->decode($packet);
|
||||||
|
if ($decoded === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list($id, $addr, $ttl) = $response;
|
list($id, $response) = $decoded;
|
||||||
$request = $this->pendingRequestsById[$id];
|
$request = $this->pendingRequestsById[$id];
|
||||||
$type = $request['type'];
|
|
||||||
$name = $request['name'];
|
$name = $request['name'];
|
||||||
|
|
||||||
$this->reactor->cancel($request['timeout_id']);
|
$this->reactor->cancel($request['timeout_id']);
|
||||||
unset($this->pendingRequestsById[$id], $this->pendingRequestsByNameAndType[$name][$type]);
|
unset($this->pendingRequestsById[$id], $this->pendingRequestsByNameAndType[$name][$request['type']]);
|
||||||
if (!$this->pendingRequestsById) {
|
if (!$this->pendingRequestsById) {
|
||||||
$this->reactor->cancel($this->readWatcherId);
|
$this->reactor->cancel($this->readWatcherId);
|
||||||
$this->readWatcherId = null;
|
$this->readWatcherId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($addr !== null) {
|
|
||||||
|
// Interpret the response and make sure we have at least one resource record
|
||||||
|
$interpreted = $this->responseInterpreter->interpret($response, $request['type']);
|
||||||
|
if ($interpreted === null) {
|
||||||
|
foreach ($request['lookups'] as $id => $lookup) {
|
||||||
|
$this->processPendingLookup($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Distribute the result to the appropriate lookup routine
|
||||||
|
list($type, $addr, $ttl) = $interpreted;
|
||||||
|
if ($type === AddressModes::CNAME) {
|
||||||
|
foreach ($request['lookups'] as $id => $lookup) {
|
||||||
|
$this->redirectPendingLookup($id, $addr);
|
||||||
|
}
|
||||||
|
} else if ($addr !== null) {
|
||||||
if ($this->cache) {
|
if ($this->cache) {
|
||||||
$this->cache->store($name, $addr, $type, $ttl);
|
$this->cache->store($name, $addr, $type, $ttl);
|
||||||
}
|
}
|
||||||
@ -289,6 +306,21 @@ class Client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect a lookup to search for another name
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
private function redirectPendingLookup($id, $name)
|
||||||
|
{
|
||||||
|
array_unshift($this->pendingLookups[$id]['requests'], $this->pendingLookups[$id]['last_type']);
|
||||||
|
$this->pendingLookups[$id]['last_type'] = null;
|
||||||
|
$this->pendingLookups[$id]['name'] = $name;
|
||||||
|
|
||||||
|
$this->processPendingLookup($id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve a name from a server
|
* Resolve a name from a server
|
||||||
*
|
*
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
namespace Addr;
|
namespace Addr;
|
||||||
|
|
||||||
use LibDNS\Decoder\Decoder,
|
use LibDNS\Decoder\Decoder,
|
||||||
LibDNS\Messages\MessageTypes;
|
LibDNS\Messages\Message,
|
||||||
|
LibDNS\Messages\MessageTypes,
|
||||||
|
LibDNS\Records\ResourceTypes;
|
||||||
|
|
||||||
class ResponseInterpreter
|
class ResponseInterpreter
|
||||||
{
|
{
|
||||||
@ -23,12 +25,12 @@ class ResponseInterpreter
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the message ID and response data from a DNS response packet
|
* Attempt to decode a data packet to a DNS response message
|
||||||
*
|
*
|
||||||
* @param string $packet
|
* @param string $packet
|
||||||
* @return array|null
|
* @return Message|null
|
||||||
*/
|
*/
|
||||||
public function interpret($packet)
|
public function decode($packet)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$message = $this->decoder->decode($packet);
|
$message = $this->decoder->decode($packet);
|
||||||
@ -40,13 +42,45 @@ class ResponseInterpreter
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return [$message->getID(), $message];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the message ID and response data from a DNS response packet
|
||||||
|
*
|
||||||
|
* @param Message $message
|
||||||
|
* @param int $expectedType
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
public function interpret($message, $expectedType)
|
||||||
|
{
|
||||||
|
static $typeMap = [
|
||||||
|
AddressModes::INET4_ADDR => ResourceTypes::A,
|
||||||
|
AddressModes::INET6_ADDR => ResourceTypes::AAAA,
|
||||||
|
];
|
||||||
|
|
||||||
$answers = $message->getAnswerRecords();
|
$answers = $message->getAnswerRecords();
|
||||||
if (!count($answers)) {
|
if (!count($answers)) {
|
||||||
return [$message->getID(), null];
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var \LibDNS\Records\Resource $record */
|
/** @var \LibDNS\Records\Resource $record */
|
||||||
$record = $answers->getRecordByIndex(0);
|
$cname = null;
|
||||||
return [$message->getID(), (string)$record->getData(), $record->getTTL()];
|
foreach ($answers as $record) {
|
||||||
|
switch ($record->getType()) {
|
||||||
|
case $typeMap[$expectedType]:
|
||||||
|
return [$expectedType, (string)$record->getData(), $record->getTTL()];
|
||||||
|
|
||||||
|
case ResourceTypes::CNAME:
|
||||||
|
$cname = (string)$record->getData();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cname) {
|
||||||
|
return [AddressModes::CNAME, $cname, null];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user