diff --git a/doc/api/dns.md b/doc/api/dns.md index fa7c34f654d011..03dd72deebf04e 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -285,6 +285,9 @@ changes: When `true`, the callback receives an array of `{ address: '1.2.3.4', ttl: 60 }` objects rather than an array of strings, with the TTL expressed in seconds. + - `search` {boolean} Resolve the DNS using the local domain name or the search + list for host-name lookup. + When `true`, the resolve will use the search list which can create extra dns queries. - `callback` {Function} - `err` {Error} - `addresses` {string[] | Object[]} @@ -310,6 +313,9 @@ changes: When `true`, the callback receives an array of `{ address: '0:1:2:3:4:5:6:7', ttl: 60 }` objects rather than an array of strings, with the TTL expressed in seconds. + - `search` {boolean} Resolve the DNS using the local domain name or the search + list for host-name lookup. + When `true`, the resolve will use the search list which can create extra dns queries. - `callback` {Function} - `err` {Error} - `addresses` {string[] | Object[]} diff --git a/lib/dns.js b/lib/dns.js index cb8b2ca0beb4cd..3ae315119c1ff6 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -228,6 +228,7 @@ function resolver(bindingName) { req.hostname = name; req.oncomplete = onresolve; req.ttl = !!(options && options.ttl); + req.search = !!(options && options.search); var err = this._handle[bindingName](req, name); if (err) throw dnsException(err, bindingName); return req; diff --git a/src/base_object-inl.h b/src/base_object-inl.h index 51ef46599667df..dd31d6e8857aca 100644 --- a/src/base_object-inl.h +++ b/src/base_object-inl.h @@ -52,6 +52,15 @@ inline v8::Local BaseObject::object() { } +inline v8::MaybeLocal BaseObject::GetField( + std::string const& field) { + return object()->Get(env()->context(), + v8::String::NewFromUtf8(env()->isolate(), + field.c_str(), + v8::NewStringType::kNormal).ToLocalChecked()); +} + + inline Environment* BaseObject::env() const { return env_; } diff --git a/src/base_object.h b/src/base_object.h index 478499bbfeb5b2..310afbba1a00b7 100644 --- a/src/base_object.h +++ b/src/base_object.h @@ -40,6 +40,8 @@ class BaseObject { // persistent.IsEmpty() is true. inline v8::Local object(); + inline v8::MaybeLocal GetField(std::string const& field); + inline Persistent& persistent(); inline Environment* env() const; diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 8f69df83133f4f..a212dcc517ad54 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -619,6 +619,14 @@ class QueryWrap : public AsyncWrap { static_cast(this)); } + void AresSearch(const char* name, + int dnsclass, + int type) { + channel_->EnsureServers(); + ares_search(channel_->cares_channel(), name, dnsclass, type, Callback, + static_cast(this)); + } + static void CaresAsyncClose(uv_handle_t* handle) { uv_async_t* async = reinterpret_cast(handle); auto data = static_cast(async->data); @@ -1360,7 +1368,20 @@ class QueryAWrap: public QueryWrap { } int Send(const char* name) override { - AresQuery(name, ns_c_in, ns_t_a); + auto prop_value = GetField("search"); + bool bSearch = false; + + if (!prop_value.IsEmpty()) { + auto search_prop = prop_value.ToLocalChecked()->ToBoolean(); + bSearch = search_prop->Value(); + } + + if (bSearch) { + AresSearch(name, ns_c_in, ns_t_a); + } else { + AresQuery(name, ns_c_in, ns_t_a); + } + return 0; } @@ -1404,7 +1425,20 @@ class QueryAaaaWrap: public QueryWrap { } int Send(const char* name) override { - AresQuery(name, ns_c_in, ns_t_aaaa); + auto prop_value = GetField("search"); + bool bSearch = false; + + if (!prop_value.IsEmpty()) { + auto search_prop = prop_value.ToLocalChecked()->ToBoolean(); + bSearch = search_prop->Value(); + } + + if (bSearch) { + AresSearch(name, ns_c_in, ns_t_a); + } else { + AresQuery(name, ns_c_in, ns_t_a); + } + return 0; } diff --git a/test/internet/test-dns.js b/test/internet/test-dns.js index f1b7b4ff056833..ac43fe399ecfe2 100644 --- a/test/internet/test-dns.js +++ b/test/internet/test-dns.js @@ -76,7 +76,7 @@ TEST(function test_reverse_bogus(done) { TEST(function test_resolve4_ttl(done) { const req = dns.resolve4(addresses.INET4_HOST, { - ttl: true + ttl: true, search: false }, function(err, result) { assert.ifError(err); assert.ok(result.length > 0); @@ -99,7 +99,7 @@ TEST(function test_resolve4_ttl(done) { TEST(function test_resolve6_ttl(done) { const req = dns.resolve6(addresses.INET6_HOST, { - ttl: true + ttl: true, search: false }, function(err, result) { assert.ifError(err); assert.ok(result.length > 0);