summaryrefslogtreecommitdiff
path: root/src/cares_wrap.cc
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2017-08-10 11:19:13 +0200
committerJames M Snell <jasnell@gmail.com>2017-08-23 14:53:47 -0700
commite007f66ae211192f385dc253bfa19a84e7fc649a (patch)
tree987b0ec77b0af63a82709ee09f3230ad3f4bc6bb /src/cares_wrap.cc
parentcbd3708c85e13b234e9ded0beaaf1780a537dc39 (diff)
downloadnode-new-e007f66ae211192f385dc253bfa19a84e7fc649a.tar.gz
dns: add `verbatim` option to dns.lookup()
When true, results from the DNS resolver are passed on as-is, without the reshuffling that Node.js otherwise does that puts IPv4 addresses before IPv6 addresses. PR-URL: https://github.com/nodejs/node/pull/14731 Ref: https://github.com/nodejs/node/issues/6307 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/cares_wrap.cc')
-rw-r--r--src/cares_wrap.cc89
1 files changed, 33 insertions, 56 deletions
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc
index e881ff5173..e800e0f2fe 100644
--- a/src/cares_wrap.cc
+++ b/src/cares_wrap.cc
@@ -196,15 +196,23 @@ void ChannelWrap::New(const FunctionCallbackInfo<Value>& args) {
class GetAddrInfoReqWrap : public ReqWrap<uv_getaddrinfo_t> {
public:
- GetAddrInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);
+ GetAddrInfoReqWrap(Environment* env,
+ Local<Object> req_wrap_obj,
+ bool verbatim);
~GetAddrInfoReqWrap();
size_t self_size() const override { return sizeof(*this); }
+ bool verbatim() const { return verbatim_; }
+
+ private:
+ const bool verbatim_;
};
GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env,
- Local<Object> req_wrap_obj)
- : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETADDRINFOREQWRAP) {
+ Local<Object> req_wrap_obj,
+ bool verbatim)
+ : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETADDRINFOREQWRAP)
+ , verbatim_(verbatim) {
Wrap(req_wrap_obj, this);
}
@@ -1811,70 +1819,38 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
};
if (status == 0) {
- // Success
- struct addrinfo *address;
int n = 0;
-
- // Create the response array.
Local<Array> results = Array::New(env->isolate());
- char ip[INET6_ADDRSTRLEN];
- const char *addr;
-
- // Iterate over the IPv4 responses again this time creating javascript
- // strings for each IP and filling the results array.
- address = res;
- while (address) {
- CHECK_EQ(address->ai_socktype, SOCK_STREAM);
-
- // Ignore random ai_family types.
- if (address->ai_family == AF_INET) {
- // Juggle pointers
- addr = reinterpret_cast<char*>(&(reinterpret_cast<struct sockaddr_in*>(
- address->ai_addr)->sin_addr));
- int err = uv_inet_ntop(address->ai_family,
- addr,
- ip,
- INET6_ADDRSTRLEN);
- if (err)
+ auto add = [&] (bool want_ipv4, bool want_ipv6) {
+ for (auto p = res; p != nullptr; p = p->ai_next) {
+ CHECK_EQ(p->ai_socktype, SOCK_STREAM);
+
+ const char* addr;
+ if (want_ipv4 && p->ai_family == AF_INET) {
+ addr = reinterpret_cast<char*>(
+ &(reinterpret_cast<struct sockaddr_in*>(p->ai_addr)->sin_addr));
+ } else if (want_ipv6 && p->ai_family == AF_INET6) {
+ addr = reinterpret_cast<char*>(
+ &(reinterpret_cast<struct sockaddr_in6*>(p->ai_addr)->sin6_addr));
+ } else {
continue;
+ }
- // Create JavaScript string
- Local<String> s = OneByteString(env->isolate(), ip);
- results->Set(n, s);
- n++;
- }
-
- // Increment
- address = address->ai_next;
- }
-
- // Iterate over the IPv6 responses putting them in the array.
- address = res;
- while (address) {
- CHECK_EQ(address->ai_socktype, SOCK_STREAM);
-
- // Ignore random ai_family types.
- if (address->ai_family == AF_INET6) {
- // Juggle pointers
- addr = reinterpret_cast<char*>(&(reinterpret_cast<struct sockaddr_in6*>(
- address->ai_addr)->sin6_addr));
- int err = uv_inet_ntop(address->ai_family,
- addr,
- ip,
- INET6_ADDRSTRLEN);
- if (err)
+ char ip[INET6_ADDRSTRLEN];
+ if (uv_inet_ntop(p->ai_family, addr, ip, sizeof(ip)))
continue;
- // Create JavaScript string
Local<String> s = OneByteString(env->isolate(), ip);
results->Set(n, s);
n++;
}
+ };
- // Increment
- address = address->ai_next;
- }
+ const bool verbatim = req_wrap->verbatim();
+ add(true, verbatim);
+ if (verbatim == false)
+ add(false, true);
// No responses were found to return
if (n == 0) {
@@ -1965,6 +1941,7 @@ void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsObject());
CHECK(args[1]->IsString());
CHECK(args[2]->IsInt32());
+ CHECK(args[4]->IsBoolean());
Local<Object> req_wrap_obj = args[0].As<Object>();
node::Utf8Value hostname(env->isolate(), args[1]);
@@ -1985,7 +1962,7 @@ void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
CHECK(0 && "bad address family");
}
- GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap(env, req_wrap_obj);
+ auto req_wrap = new GetAddrInfoReqWrap(env, req_wrap_obj, args[4]->IsTrue());
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));