dns: add resolvePtr to query 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(). PR-URL: https://github.com/nodejs/node/pull/4921 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Brian White <mscdex@mscdex.net>
This commit is contained in:
parent
c4ab861a49
commit
dbdbdd4998
@ -155,7 +155,7 @@ Valid values for `rrtype` are:
|
|||||||
* `'MX'` - mail exchange records
|
* `'MX'` - mail exchange records
|
||||||
* `'TXT'` - text records
|
* `'TXT'` - text records
|
||||||
* `'SRV'` - SRV records
|
* `'SRV'` - SRV records
|
||||||
* `'PTR'` - used for reverse IP lookups
|
* `'PTR'` - PTR records
|
||||||
* `'NS'` - name server records
|
* `'NS'` - name server records
|
||||||
* `'CNAME'` - canonical name records
|
* `'CNAME'` - canonical name records
|
||||||
* `'SOA'` - start of authority record
|
* `'SOA'` - start of authority record
|
||||||
@ -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)
|
## dns.resolveTxt(hostname, callback)
|
||||||
|
|
||||||
Uses the DNS protocol to resolve text queries (`TXT` records) for the
|
Uses the DNS protocol to resolve text queries (`TXT` records) for the
|
||||||
|
@ -251,9 +251,10 @@ exports.resolveMx = resolveMap.MX = resolver('queryMx');
|
|||||||
exports.resolveNs = resolveMap.NS = resolver('queryNs');
|
exports.resolveNs = resolveMap.NS = resolver('queryNs');
|
||||||
exports.resolveTxt = resolveMap.TXT = resolver('queryTxt');
|
exports.resolveTxt = resolveMap.TXT = resolver('queryTxt');
|
||||||
exports.resolveSrv = resolveMap.SRV = resolver('querySrv');
|
exports.resolveSrv = resolveMap.SRV = resolver('querySrv');
|
||||||
|
exports.resolvePtr = resolveMap.PTR = resolver('queryPtr');
|
||||||
exports.resolveNaptr = resolveMap.NAPTR = resolver('queryNaptr');
|
exports.resolveNaptr = resolveMap.NAPTR = resolver('queryNaptr');
|
||||||
exports.resolveSoa = resolveMap.SOA = resolver('querySoa');
|
exports.resolveSoa = resolveMap.SOA = resolver('querySoa');
|
||||||
exports.reverse = resolveMap.PTR = resolver('getHostByAddr');
|
exports.reverse = resolver('getHostByAddr');
|
||||||
|
|
||||||
|
|
||||||
exports.resolve = function(hostname, type_, callback_) {
|
exports.resolve = function(hostname, type_, callback_) {
|
||||||
|
@ -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 {
|
class QueryNaptrWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
explicit QueryNaptrWrap(Environment* env, Local<Object> req_wrap_obj)
|
explicit QueryNaptrWrap(Environment* env, Local<Object> req_wrap_obj)
|
||||||
@ -1276,6 +1319,7 @@ static void Initialize(Local<Object> target,
|
|||||||
env->SetMethod(target, "queryNs", Query<QueryNsWrap>);
|
env->SetMethod(target, "queryNs", Query<QueryNsWrap>);
|
||||||
env->SetMethod(target, "queryTxt", Query<QueryTxtWrap>);
|
env->SetMethod(target, "queryTxt", Query<QueryTxtWrap>);
|
||||||
env->SetMethod(target, "querySrv", Query<QuerySrvWrap>);
|
env->SetMethod(target, "querySrv", Query<QuerySrvWrap>);
|
||||||
|
env->SetMethod(target, "queryPtr", Query<QueryPtrWrap>);
|
||||||
env->SetMethod(target, "queryNaptr", Query<QueryNaptrWrap>);
|
env->SetMethod(target, "queryNaptr", Query<QueryNaptrWrap>);
|
||||||
env->SetMethod(target, "querySoa", Query<QuerySoaWrap>);
|
env->SetMethod(target, "querySoa", Query<QuerySoaWrap>);
|
||||||
env->SetMethod(target, "getHostByAddr", Query<GetHostByAddrWrap>);
|
env->SetMethod(target, "getHostByAddr", Query<GetHostByAddrWrap>);
|
||||||
|
@ -166,6 +166,37 @@ TEST(function test_resolveSrv_failure(done) {
|
|||||||
checkWrap(req);
|
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) {
|
TEST(function test_resolveNaptr(done) {
|
||||||
var req = dns.resolveNaptr('sip2sip.info', function(err, result) {
|
var req = dns.resolveNaptr('sip2sip.info', function(err, result) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
@ -31,7 +31,7 @@ assert.throws(function() {
|
|||||||
// C:\Windows\System32\drivers\etc\hosts
|
// C:\Windows\System32\drivers\etc\hosts
|
||||||
// so we disable this test on Windows.
|
// so we disable this test on Windows.
|
||||||
if (!common.isWindows) {
|
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;
|
if (error) throw error;
|
||||||
assert.ok(Array.isArray(domains));
|
assert.ok(Array.isArray(domains));
|
||||||
});
|
});
|
||||||
|
@ -12,6 +12,7 @@ var methods = [
|
|||||||
'resolveNs',
|
'resolveNs',
|
||||||
'resolveTxt',
|
'resolveTxt',
|
||||||
'resolveSrv',
|
'resolveSrv',
|
||||||
|
'resolvePtr',
|
||||||
'resolveNaptr',
|
'resolveNaptr',
|
||||||
'resolveSoa'
|
'resolveSoa'
|
||||||
];
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user