Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Dague <jd@josh3736.net>2020-08-18 09:23:25 +0300
committerAntoine du Hamel <duhamelantoine1995@gmail.com>2020-10-25 13:18:39 +0300
commit3e10ce30b471214cc5020a92d628357e9ed4fb91 (patch)
tree4c9092895509dab0a0092e42cc53da4890643e83 /src/cares_wrap.cc
parent70834250e83fa89e92314be37a9592978ee8c6bd (diff)
dns: add setLocalAddress to Resolver
Fixes: https://github.com/nodejs/node/issues/34818 PR-URL: https://github.com/nodejs/node/pull/34824 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Roman Reiss <me@silverwind.io>
Diffstat (limited to 'src/cares_wrap.cc')
-rw-r--r--src/cares_wrap.cc66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc
index fcffc2bec67..6d7a8e66a9d 100644
--- a/src/cares_wrap.cc
+++ b/src/cares_wrap.cc
@@ -29,6 +29,7 @@
#include "req_wrap-inl.h"
#include "util-inl.h"
#include "uv.h"
+#include "node_errors.h"
#include <cerrno>
#include <cstring>
@@ -2227,6 +2228,70 @@ void SetServers(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(err);
}
+void SetLocalAddress(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ ChannelWrap* channel;
+ ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());
+
+ CHECK_EQ(args.Length(), 2);
+ CHECK(args[0]->IsString());
+
+ Isolate* isolate = args.GetIsolate();
+ node::Utf8Value ip0(isolate, args[0]);
+
+ unsigned char addr0[sizeof(struct in6_addr)];
+ unsigned char addr1[sizeof(struct in6_addr)];
+ int type0 = 0;
+
+ // This function accepts 2 arguments. The first may be either an IPv4
+ // address or an IPv6 address. If present, the second argument must be the
+ // other type of address. Otherwise, the unspecified type of IP is set
+ // to 0 (any).
+
+ if (uv_inet_pton(AF_INET, *ip0, &addr0) == 0) {
+ ares_set_local_ip4(channel->cares_channel(), ReadUint32BE(addr0));
+ type0 = 4;
+ } else if (uv_inet_pton(AF_INET6, *ip0, &addr0) == 0) {
+ ares_set_local_ip6(channel->cares_channel(), addr0);
+ type0 = 6;
+ } else {
+ THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP address.");
+ return;
+ }
+
+ if (!args[1]->IsUndefined()) {
+ CHECK(args[1]->IsString());
+ node::Utf8Value ip1(isolate, args[1]);
+
+ if (uv_inet_pton(AF_INET, *ip1, &addr1) == 0) {
+ if (type0 == 4) {
+ THROW_ERR_INVALID_ARG_VALUE(env, "Cannot specify two IPv4 addresses.");
+ return;
+ } else {
+ ares_set_local_ip4(channel->cares_channel(), ReadUint32BE(addr1));
+ }
+ } else if (uv_inet_pton(AF_INET6, *ip1, &addr1) == 0) {
+ if (type0 == 6) {
+ THROW_ERR_INVALID_ARG_VALUE(env, "Cannot specify two IPv6 addresses.");
+ return;
+ } else {
+ ares_set_local_ip6(channel->cares_channel(), addr1);
+ }
+ } else {
+ THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP address.");
+ return;
+ }
+ } else {
+ // No second arg specifed
+ if (type0 == 4) {
+ memset(&addr1, 0, sizeof(addr1));
+ ares_set_local_ip6(channel->cares_channel(), addr1);
+ } else {
+ ares_set_local_ip4(channel->cares_channel(), 0);
+ }
+ }
+}
+
void Cancel(const FunctionCallbackInfo<Value>& args) {
ChannelWrap* channel;
ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());
@@ -2329,6 +2394,7 @@ void Initialize(Local<Object> target,
env->SetProtoMethodNoSideEffect(channel_wrap, "getServers", GetServers);
env->SetProtoMethod(channel_wrap, "setServers", SetServers);
+ env->SetProtoMethod(channel_wrap, "setLocalAddress", SetLocalAddress);
env->SetProtoMethod(channel_wrap, "cancel", Cancel);
Local<String> channelWrapString =