Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
dns: add resolvePtr to query for plain DNS PTR records
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().
  • Loading branch information
dturing committed Feb 8, 2016
commit a2a280cbb5f2b516d3405814c58600e06b4b3bd6
8 changes: 7 additions & 1 deletion doc/api/dns.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,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 @@ -244,6 +244,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 @@ -248,9 +248,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);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a IPv6 resolvePtr test too?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, and possibly also one for dns.resolvePtr('8.8.8.8') which should result in an error.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your comments. I will add the requested tests next week.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@silverwind - i dont think a IPv6 resolvePtr test makes sense, PTRs actually don't deal with addresses.

I could resolve PTR for "8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8.4.0.6.8.4.1.0.0.2.ip6.arpa", Google's v6 reverse, but really the test_relovePtr uses "8.8.8.8.in-addr.arpa" only because it's a readily available PTR record - that it's a in-addr.arpa entry is just a coincidence.

dns.reverse(), which deals with addresses, is tested in test-dns-ipv6.js already.

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