Async DNS Direct Query Module.

dev-master 2019-07-17 00:28 UTC

This package is auto-updated.

Last update: 2024-04-14 00:33:47 UTC


README

Build StatuscodecovCodacy BadgeMaintainability

This package is under development, the asynchronous parts has not been implemented or added.

This API is intended to be a half-way house offering direct to-server queries, the ability to process the response in detail but still with a simple interface for the programmer.

Usage Guide

Using the Query API

You can use the DNS query API from within PHP (version 7 or later) and it requires no special raw socket permissions so should operate correctly in most environments.

To use the API you must create a Query object (with a DNS server hostname/IP and other optional parameters), perform a query (either a full query where you specify the type of result or a smart A lookup <#SmartALookup>) and deal with the answer.

The answer will either be false if an error occured (see the code below for an example error trap) or a Answer object containing a "count" property (the number of records returned as answers) and an array of Result objects containing each answer given to the query.

The following is an example script to perform an A record (IP address) lookup

// A simple DNS query example
require("vendor/autoload.php"); // Require API Source

use Async\Dns\Query;

// Your DNS Server
$dns_server = "ns.somehost.com"; 

// create Query object - there are other options we could pass here
$dns_query = new Query($dns_server);

// the question we will ask
$question = "www.somehost.com";

// the type of response(s) we want for this question
$type = "A";

// do the query
$result = $dns_query->query($question, $type); 

// Trap Errors
if ($dns_query->->hasError()) {
    // error occurred
    echo $dns_query->getLastError();
    exit();
}

//Process Results
$count = $result->count(); // number of results returned
foreach ($result as $result_count) {
    // only after A records
    if ($result_count->getTypeId() == "A") {
        echo $question." has IP address ".$result_count->getData()."<br>";
        echo $result_count->getString()."<br>";
    }
}

Which if all goes well should output something like...

The first output is from our script writing the question and the "data" result, the second when we output the "string" property of the answer which is the specific record in human-readable form (if the type is known).

A Note of Warning and Why Check the Answer Type Above

DNS is not an entirely straightforward protocol and things which on the surface may seem simple may not be when you delve deeper (if you already understand DNS then skip ahead).

For example an IP lookup (A record lookup) for a host on a specific DNS server may well not just return a single answer record containing the IP address. The host may be multi-honed and return multiple records any which may not be an IP address but a CNAME alias. The nameserver you are querying may not do a recursive or cache lookup for you and so return no answers even though the domain and host do exist.

For this reason we must actually process the results (unless of course we just want to see what data is provided for a query and not actually do anything with that answer).

Hosts with just a CNAME alias will not be resolved to an IP address in the answer section. If we ask for the A record of www.somehost.com we may just get back a CNAME of webhost.somehost.com. To turn this into an IP address we must then either hope it was provided in the additional answer section (and check - see below for details) or perform another A record lookup on webhost.somehost.com.

If you just want an IP address for a host then either PHP's inbuilt gethostbyname() http://www.php.net/ or this API's SmartALookup() <#SmartALookup> are probably what you're after rather than a full blown query.

Answer and Query Types

Record (query and result) types the API supports will should return sensible data for are: A, NS, PTR, MX, CNAME, TXT and SOA.

Asking for an unsupported type will cause the query to fail. Unsupported types which are returned as result records will have null "string" and "typeid" properties but will contain the binary data in "data" and the decimal record type in "type".

Answer Results

If a query succeeds it returns a Answer object containing a counter property "count" indicating the number of answer records returned and an array of Result objects containing each of these records in turn.

The Answer object breaks down as follows: $answer->count Number of answer records contained $answer->results[x]->typeid Textual record type ID (A, MX, CNAME etc) $answer->results[x]->type Numeric record type (decimal) $answer->results[x]->class Numeric class type (decimal) $answer->results[x]->data Data returned (i.e. IP address or hostname) $answer->results[x]->domain Domain name data is for $answer->results[x]->string String representation of the answer (i.e. www.fish.sea has address x.y.z) $answer->results[x]->extras Type-specific array of extra fields (i.e. "level" for MX exchanges) - see below

Type-specific Extras

Some result types have extended extra information which will be in array form in the "extras" property of a Result object.

MX record types have the decimal mail exchange priority in extas['level']

SOA record types have the responsible contact for the domain in extras['responsible'] as well as the following: extras['serial'] - domain serial extras['refresh'] - domain refresh extras['retry'] - domain retry extras['expiry'] - domain expiry extras['minttl'] - domain mimumum time-to-live (ttl)

Smart A Lookup

Because doing an A lookup won't always return an IP address and sometimes you're just after an IP address (not potentially a list of them and aliases etc) the Query class provides the SmartALookup() method.

This function simply takes a hostname and returns an IP address or a null string if lookup failed (you can then check the Query lasterror property to see if the query actually failed or just returned no results).

If the result data contains an IP address it will be returned (first preference). If no IP addresses were provided but an alias CNAME is given then this will be looked up (recursing up to a depth of five aliases).

In effect this is a nameserver-specific version of gethostbyname() but returns a null string rather than the unmodified IP on failure.

More Information

The technical documentation can be found here