Skip to content

Commit 24c1e1c

Browse files
committed
dns: validate default c-ares servers on first query
1 parent f8d5bad commit 24c1e1c

2 files changed

Lines changed: 53 additions & 1 deletion

File tree

src/cares_wrap.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,9 @@ class ChannelWrap final : public AsyncWrap {
186186
private:
187187
uv_timer_t* timer_handle_ = nullptr;
188188
ares_channel channel_ = nullptr;
189-
bool query_last_ok_ = true;
189+
// Start pessimistically so the first query validates whether c-ares fell
190+
// back to a loopback resolver while using the system DNS configuration.
191+
bool query_last_ok_ = false;
190192
bool is_servers_default_ = true;
191193
bool library_inited_ = false;
192194
int timeout_;

test/cctest/test_cares_wrap.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "cares_wrap.h"
2+
3+
#include "gtest/gtest.h"
4+
#include "node.h"
5+
#include "node_test_fixture.h"
6+
#include "v8.h"
7+
8+
#include <winsock2.h>
9+
10+
class CaresWrapTest : public EnvironmentTestFixture {};
11+
12+
TEST_F(CaresWrapTest, FreshChannelChecksServersBeforeFirstQuery) {
13+
v8::HandleScope handle_scope(isolate_);
14+
const Argv argv;
15+
Env env{handle_scope, argv};
16+
17+
v8::Local<v8::FunctionTemplate> templ =
18+
node::BaseObject::MakeLazilyInitializedJSTemplate(*env);
19+
v8::Local<v8::Object> object = templ->GetFunction(env.context())
20+
.ToLocalChecked()
21+
->NewInstance(env.context())
22+
.ToLocalChecked();
23+
24+
node::cares_wrap::ChannelWrap channel(*env, object, -1, 4, 0);
25+
26+
ares_addr_port_node server{};
27+
server.family = AF_INET;
28+
server.addr.addr4.s_addr = htonl(INADDR_LOOPBACK);
29+
server.tcp_port = 12345;
30+
server.udp_port = 12345;
31+
32+
ASSERT_EQ(ares_set_servers_ports(channel.cares_channel(), &server),
33+
ARES_SUCCESS);
34+
channel.set_is_servers_default(true);
35+
36+
channel.EnsureServers();
37+
38+
ares_addr_port_node* current = nullptr;
39+
ares_get_servers_ports(channel.cares_channel(), &current);
40+
ASSERT_NE(current, nullptr);
41+
42+
const bool still_using_test_loopback =
43+
current->next == nullptr && current->family == AF_INET &&
44+
current->addr.addr4.s_addr == htonl(INADDR_LOOPBACK) &&
45+
current->tcp_port == 12345 && current->udp_port == 12345;
46+
47+
ares_free_data(current);
48+
49+
EXPECT_FALSE(still_using_test_loopback);
50+
}

0 commit comments

Comments
 (0)