dns: support max timeout · nodejs/node@c52aaac · GitHub
Skip to content

Commit c52aaac

Browse files
theanarkhtargos
authored andcommitted
dns: support max timeout
PR-URL: #58440 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent cb95e18 commit c52aaac

5 files changed

Lines changed: 118 additions & 22 deletions

File tree

doc/api/dns.md

Lines changed: 2 additions & 0 deletions

lib/internal/dns/utils.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const {
2525
validateInt32,
2626
validateOneOf,
2727
validateString,
28+
validateUint32,
2829
} = require('internal/validators');
2930
let binding;
3031
function lazyBinding() {
@@ -49,6 +50,12 @@ function validateTimeout(options) {
4950
return timeout;
5051
}
5152

53+
function validateMaxTimeout(options) {
54+
const { maxTimeout = 0 } = { ...options };
55+
validateUint32(maxTimeout, 'options.maxTimeout');
56+
return maxTimeout;
57+
}
58+
5259
function validateTries(options) {
5360
const { tries = 4 } = { ...options };
5461
validateInt32(tries, 'options.tries', 1);
@@ -67,17 +74,18 @@ class ResolverBase {
6774
constructor(options = undefined) {
6875
const timeout = validateTimeout(options);
6976
const tries = validateTries(options);
77+
const maxTimeout = validateMaxTimeout(options);
7078
// If we are building snapshot, save the states of the resolver along
7179
// the way.
7280
if (isBuildingSnapshot()) {
73-
this[kSnapshotStates] = { timeout, tries };
81+
this[kSnapshotStates] = { timeout, tries, maxTimeout };
7482
}
75-
this[kInitializeHandle](timeout, tries);
83+
this[kInitializeHandle](timeout, tries, maxTimeout);
7684
}
7785

78-
[kInitializeHandle](timeout, tries) {
86+
[kInitializeHandle](timeout, tries, maxTimeout) {
7987
const { ChannelWrap } = lazyBinding();
80-
this._handle = new ChannelWrap(timeout, tries);
88+
this._handle = new ChannelWrap(timeout, tries, maxTimeout);
8189
}
8290

8391
cancel() {
@@ -187,8 +195,8 @@ class ResolverBase {
187195
}
188196

189197
[kDeserializeResolver]() {
190-
const { timeout, tries, localAddress, servers } = this[kSnapshotStates];
191-
this[kInitializeHandle](timeout, tries);
198+
const { timeout, tries, maxTimeout, localAddress, servers } = this[kSnapshotStates];
199+
this[kInitializeHandle](timeout, tries, maxTimeout);
192200
if (localAddress) {
193201
const { ipv4, ipv6 } = localAddress;
194202
this._handle.setLocalAddress(ipv4, ipv6);

src/cares_wrap.cc

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -787,14 +787,15 @@ Maybe<int> ParseSoaReply(Environment* env,
787787
}
788788
} // anonymous namespace
789789

790-
ChannelWrap::ChannelWrap(
791-
Environment* env,
792-
Local<Object> object,
793-
int timeout,
794-
int tries)
790+
ChannelWrap::ChannelWrap(Environment* env,
791+
Local<Object> object,
792+
int timeout,
793+
int tries,
794+
int max_timeout)
795795
: AsyncWrap(env, object, PROVIDER_DNSCHANNEL),
796796
timeout_(timeout),
797-
tries_(tries) {
797+
tries_(tries),
798+
max_timeout_(max_timeout) {
798799
MakeWeak();
799800

800801
Setup();
@@ -808,13 +809,15 @@ void ChannelWrap::MemoryInfo(MemoryTracker* tracker) const {
808809

809810
void ChannelWrap::New(const FunctionCallbackInfo<Value>& args) {
810811
CHECK(args.IsConstructCall());
811-
CHECK_EQ(args.Length(), 2);
812+
CHECK_EQ(args.Length(), 3);
812813
CHECK(args[0]->IsInt32());
813814
CHECK(args[1]->IsInt32());
815+
CHECK(args[2]->IsInt32());
814816
const int timeout = args[0].As<Int32>()->Value();
815817
const int tries = args[1].As<Int32>()->Value();
818+
const int max_timeout = args[2].As<Int32>()->Value();
816819
Environment* env = Environment::GetCurrent(args);
817-
new ChannelWrap(env, args.This(), timeout, tries);
820+
new ChannelWrap(env, args.This(), timeout, tries, max_timeout);
818821
}
819822

820823
GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env,
@@ -879,9 +882,14 @@ void ChannelWrap::Setup() {
879882
}
880883

881884
/* We do the call to ares_init_option for caller. */
882-
const int optmask = ARES_OPT_FLAGS | ARES_OPT_TIMEOUTMS |
883-
ARES_OPT_SOCK_STATE_CB | ARES_OPT_TRIES |
884-
ARES_OPT_QUERY_CACHE;
885+
int optmask = ARES_OPT_FLAGS | ARES_OPT_TIMEOUTMS | ARES_OPT_SOCK_STATE_CB |
886+
ARES_OPT_TRIES | ARES_OPT_QUERY_CACHE;
887+
888+
if (max_timeout_ > 0) {
889+
options.maxtimeout = max_timeout_;
890+
optmask |= ARES_OPT_MAXTIMEOUTMS;
891+
}
892+
885893
r = ares_init_options(&channel_, &options, optmask);
886894

887895
if (r != ARES_SUCCESS) {

src/cares_wrap.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ struct NodeAresTask final : public MemoryRetainer {
151151

152152
class ChannelWrap final : public AsyncWrap {
153153
public:
154-
ChannelWrap(
155-
Environment* env,
156-
v8::Local<v8::Object> object,
157-
int timeout,
158-
int tries);
154+
ChannelWrap(Environment* env,
155+
v8::Local<v8::Object> object,
156+
int timeout,
157+
int tries,
158+
int max_timeout);
159159
~ChannelWrap() override;
160160

161161
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -190,6 +190,7 @@ class ChannelWrap final : public AsyncWrap {
190190
bool library_inited_ = false;
191191
int timeout_;
192192
int tries_;
193+
int max_timeout_;
193194
int active_query_count_ = 0;
194195
NodeAresTask::List task_list_;
195196
};
Lines changed: 77 additions & 0 deletions

0 commit comments

Comments
 (0)