diff options
author | Tuğrul Topuz <tugrultopuz@gmail.com> | 2013-10-21 16:47:57 +0300 |
---|---|---|
committer | Timothy J Fontaine <tjfontaine@gmail.com> | 2013-12-31 14:30:40 -0800 |
commit | bddea032b7f2b0f2854faa18855249286bd99428 (patch) | |
tree | 09d538558d9c670f7c34ced6407e08efe85179fc | |
parent | 13de0f1d278a49b2bafac6471bec6c14c3c9376b (diff) | |
download | nodejs-bddea032b7f2b0f2854faa18855249286bd99428.tar.gz nodejs-bddea032b7f2b0f2854faa18855249286bd99428.tar.bz2 nodejs-bddea032b7f2b0f2854faa18855249286bd99428.zip |
dns: add resolveSoa and 'SOA' rrtype
You can now query for SOA records by either passing 'SOA' to `resolve`
or by using the new `resolveSoa`
-rw-r--r-- | doc/api/dns.markdown | 36 | ||||
-rw-r--r-- | lib/dns.js | 1 | ||||
-rw-r--r-- | src/cares_wrap.cc | 54 | ||||
-rw-r--r-- | test/internet/test-dns.js | 34 |
4 files changed, 121 insertions, 4 deletions
diff --git a/doc/api/dns.markdown b/doc/api/dns.markdown index 60dbfe206..b9b1502a2 100644 --- a/doc/api/dns.markdown +++ b/doc/api/dns.markdown @@ -52,10 +52,19 @@ such as no available file descriptors. ## dns.resolve(hostname, [rrtype], callback) Resolves a hostname (e.g. `'google.com'`) into an array of the record types -specified by rrtype. Valid rrtypes are `'A'` (IPV4 addresses, default), -`'AAAA'` (IPV6 addresses), `'MX'` (mail exchange records), `'TXT'` (text -records), `'SRV'` (SRV records), `'PTR'` (used for reverse IP lookups), -`'NS'` (name server records) and `'CNAME'` (canonical name records). +specified by rrtype. + +Valid rrtypes are: + + * `'A'` (IPV4 addresses, default) + * `'AAAA'` (IPV6 addresses) + * `'MX'` (mail exchange records) + * `'TXT'` (text records) + * `'SRV'` (SRV records) + * `'PTR'` (used for reverse IP lookups) + * `'NS'` (name server records) + * `'CNAME'` (canonical name records) + * `'SOA'` (start of authority record) The callback has arguments `(err, addresses)`. The type of each item in `addresses` is determined by the record type, and described in the @@ -96,6 +105,25 @@ The same as `dns.resolve()`, but only for service records (`SRV` records). of SRV records are priority, weight, port, and name (e.g., `[{'priority': 10, {'weight': 5, 'port': 21223, 'name': 'service.example.com'}, ...]`). +## dns.resolveSoa(hostname, callback) + +The same as `dns.resolve()`, but only for start of authority record queries +(`SOA` record). + +`addresses` is an object with the following structure: + +``` +{ + nsname: 'ns.example.com', + hostmaster: 'root.example.com', + serial: 2013101809, + refresh: 10000, + retry: 2400, + expire: 604800, + minttl: 3600 +} +``` + ## dns.resolveNs(hostname, callback) The same as `dns.resolve()`, but only for name server records (`NS` records). diff --git a/lib/dns.js b/lib/dns.js index 34545e835..cbba37258 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -176,6 +176,7 @@ exports.resolveNs = resolveMap.NS = resolver('queryNs'); exports.resolveTxt = resolveMap.TXT = resolver('queryTxt'); exports.resolveSrv = resolveMap.SRV = resolver('querySrv'); exports.resolveNaptr = resolveMap.NAPTR = resolver('queryNaptr'); +exports.resolveSoa = resolveMap.SOA = resolver('querySoa'); exports.reverse = resolveMap.PTR = resolver('getHostByAddr'); diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index d7669c277..ade6f1382 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -717,6 +717,59 @@ class QueryNaptrWrap: public QueryWrap { }; +class QuerySoaWrap: public QueryWrap { + public: + QuerySoaWrap(Environment* env, Local<Object> req_wrap_obj) + : QueryWrap(env, req_wrap_obj) { + } + + int Send(const char* name) { + ares_query(env()->cares_channel(), + name, + ns_c_in, + ns_t_soa, + Callback, + GetQueryArg()); + return 0; + } + + protected: + void Parse(unsigned char* buf, int len) { + HandleScope handle_scope(env()->isolate()); + Context::Scope context_scope(env()->context()); + + ares_soa_reply* soa_out; + int status = ares_parse_soa_reply(buf, len, &soa_out); + + if (status != ARES_SUCCESS) { + ParseError(status); + return; + } + + Local<Object> soa_record = Object::New(); + + soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "nsname"), + OneByteString(node_isolate, soa_out->nsname)); + soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "hostmaster"), + OneByteString(node_isolate, soa_out->hostmaster)); + soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "serial"), + Integer::New(soa_out->serial, node_isolate)); + soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "refresh"), + Integer::New(soa_out->refresh, node_isolate)); + soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "retry"), + Integer::New(soa_out->retry, node_isolate)); + soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "expire"), + Integer::New(soa_out->expire, node_isolate)); + soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "minttl"), + Integer::New(soa_out->minttl, node_isolate)); + + ares_free_data(soa_out); + + this->CallOnComplete(soa_record); + } +}; + + class GetHostByAddrWrap: public QueryWrap { public: explicit GetHostByAddrWrap(Environment* env, Local<Object> req_wrap_obj) @@ -1103,6 +1156,7 @@ static void Initialize(Handle<Object> target, NODE_SET_METHOD(target, "queryTxt", Query<QueryTxtWrap>); NODE_SET_METHOD(target, "querySrv", Query<QuerySrvWrap>); NODE_SET_METHOD(target, "queryNaptr", Query<QueryNaptrWrap>); + NODE_SET_METHOD(target, "querySoa", Query<QuerySoaWrap>); NODE_SET_METHOD(target, "getHostByAddr", Query<GetHostByAddrWrap>); NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo); diff --git a/test/internet/test-dns.js b/test/internet/test-dns.js index cc69106c5..bb55aeca6 100644 --- a/test/internet/test-dns.js +++ b/test/internet/test-dns.js @@ -244,6 +244,40 @@ TEST(function test_resolveNaptr(done) { checkWrap(req); }); +TEST(function test_resolveSoa(done) { + var req = dns.resolveSoa('nodejs.org', function(err, result) { + if (err) throw err; + + assert.ok(result); + assert.ok(typeof result === 'object'); + + assert.ok(typeof result.nsname === 'string'); + assert.ok(result.nsname.length > 0); + + assert.ok(typeof result.hostmaster === 'string'); + assert.ok(result.hostmaster.length > 0); + + assert.ok(typeof result.serial === 'number'); + assert.ok((result.serial > 0) && (result.serial < 4294967295)); + + assert.ok(typeof result.refresh === 'number'); + assert.ok((result.refresh > 0) && (result.refresh < 2147483647)); + + assert.ok(typeof result.retry === 'number'); + assert.ok((result.retry > 0) && (result.retry < 2147483647)); + + assert.ok(typeof result.expire === 'number'); + assert.ok((result.expire > 0) && (result.expire < 2147483647)); + + assert.ok(typeof result.minttl === 'number'); + assert.ok((result.minttl >= 0) && (result.minttl < 2147483647)); + + done(); + }); + + checkWrap(req); +}); + TEST(function test_resolveCname(done) { var req = dns.resolveCname('www.microsoft.com', function(err, names) { if (err) throw err; |