Skip to content

Commit

Permalink
dns: add resolvePtr to query plain DNS PTR records
Browse files Browse the repository at this point in the history
Resolving plain PTR records is used beyond reverse DNS, most
prominently with DNS-SD (RFC6763). This adds dns.resolvePtr(),
and uses it (instead of dns.reverse()) in dns.resolve().

PR-URL: nodejs#4921
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Brian White <mscdex@mscdex.net>
  • Loading branch information
dturing authored and Michael Scovetta committed Apr 2, 2016
1 parent 8cabd9e commit 0fd9638
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 3 deletions.
8 changes: 7 additions & 1 deletion doc/api/dns.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ Valid values for `rrtype` are:
* `'MX'` - mail exchange records
* `'TXT'` - text records
* `'SRV'` - SRV records
* `'PTR'` - used for reverse IP lookups
* `'PTR'` - PTR records
* `'NS'` - name server records
* `'CNAME'` - canonical name records
* `'SOA'` - start of authority record
Expand Down Expand Up @@ -248,6 +248,12 @@ be an array of objects with the following properties:
}
```

## dns.resolvePtr(hostname, callback)

Uses the DNS protocol to resolve pointer records (`PTR` records) for the
`hostname`. The `addresses` argument passed to the `callback` function will
be an array of strings containing the reply records.

## dns.resolveTxt(hostname, callback)

Uses the DNS protocol to resolve text queries (`TXT` records) for the
Expand Down
3 changes: 2 additions & 1 deletion lib/dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,10 @@ exports.resolveMx = resolveMap.MX = resolver('queryMx');
exports.resolveNs = resolveMap.NS = resolver('queryNs');
exports.resolveTxt = resolveMap.TXT = resolver('queryTxt');
exports.resolveSrv = resolveMap.SRV = resolver('querySrv');
exports.resolvePtr = resolveMap.PTR = resolver('queryPtr');
exports.resolveNaptr = resolveMap.NAPTR = resolver('queryNaptr');
exports.resolveSoa = resolveMap.SOA = resolver('querySoa');
exports.reverse = resolveMap.PTR = resolver('getHostByAddr');
exports.reverse = resolver('getHostByAddr');


exports.resolve = function(hostname, type_, callback_) {
Expand Down
44 changes: 44 additions & 0 deletions src/cares_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,49 @@ class QuerySrvWrap: public QueryWrap {
}
};

class QueryPtrWrap: public QueryWrap {
public:
explicit QueryPtrWrap(Environment* env, Local<Object> req_wrap_obj)
: QueryWrap(env, req_wrap_obj) {
}

int Send(const char* name) override {
ares_query(env()->cares_channel(),
name,
ns_c_in,
ns_t_ptr,
Callback,
GetQueryArg());
return 0;
}

size_t self_size() const override { return sizeof(*this); }

protected:
void Parse(unsigned char* buf, int len) override {
HandleScope handle_scope(env()->isolate());
Context::Scope context_scope(env()->context());

struct hostent* host;

int status = ares_parse_ptr_reply(buf, len, NULL, 0, AF_INET, &host);
if (status != ARES_SUCCESS) {
ParseError(status);
return;
}

Local<Array> aliases = Array::New(env()->isolate());

for (uint32_t i = 0; host->h_aliases[i] != NULL; i++) {
aliases->Set(i, OneByteString(env()->isolate(), host->h_aliases[i]));
}

ares_free_hostent(host);

this->CallOnComplete(aliases);
}
};

class QueryNaptrWrap: public QueryWrap {
public:
explicit QueryNaptrWrap(Environment* env, Local<Object> req_wrap_obj)
Expand Down Expand Up @@ -1276,6 +1319,7 @@ static void Initialize(Local<Object> target,
env->SetMethod(target, "queryNs", Query<QueryNsWrap>);
env->SetMethod(target, "queryTxt", Query<QueryTxtWrap>);
env->SetMethod(target, "querySrv", Query<QuerySrvWrap>);
env->SetMethod(target, "queryPtr", Query<QueryPtrWrap>);
env->SetMethod(target, "queryNaptr", Query<QueryNaptrWrap>);
env->SetMethod(target, "querySoa", Query<QuerySoaWrap>);
env->SetMethod(target, "getHostByAddr", Query<GetHostByAddrWrap>);
Expand Down
31 changes: 31 additions & 0 deletions test/internet/test-dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,37 @@ TEST(function test_resolveSrv_failure(done) {
checkWrap(req);
});

TEST(function test_resolvePtr(done) {
var req = dns.resolvePtr('8.8.8.8.in-addr.arpa', function(err, result) {
if (err) throw err;

assert.ok(result.length > 0);

for (var i = 0; i < result.length; i++) {
var item = result[i];
assert.ok(item);
assert.ok(typeof item === 'string');
}

done();
});

checkWrap(req);
});

TEST(function test_resolvePtr_failure(done) {
var req = dns.resolvePtr('something.invalid', function(err, result) {
assert.ok(err instanceof Error);
assert.strictEqual(err.errno, 'ENOTFOUND');

assert.ok(result == undefined);

done();
});

checkWrap(req);
});

TEST(function test_resolveNaptr(done) {
var req = dns.resolveNaptr('sip2sip.info', function(err, result) {
if (err) throw err;
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-c-ares.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ assert.throws(function() {
// C:\Windows\System32\drivers\etc\hosts
// so we disable this test on Windows.
if (!common.isWindows) {
dns.resolve('127.0.0.1', 'PTR', function(error, domains) {
dns.reverse('127.0.0.1', function(error, domains) {
if (error) throw error;
assert.ok(Array.isArray(domains));
});
Expand Down
1 change: 1 addition & 0 deletions test/parallel/test-dns-cares-domains.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ var methods = [
'resolveNs',
'resolveTxt',
'resolveSrv',
'resolvePtr',
'resolveNaptr',
'resolveSoa'
];
Expand Down

0 comments on commit 0fd9638

Please sign in to comment.