Coverage Report

Created: 2025-08-03 10:06

/src/node/src/cares_wrap.h
Line
Count
Source (jump to first uncovered line)
1
#ifndef SRC_CARES_WRAP_H_
2
#define SRC_CARES_WRAP_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#define CARES_STATICLIB
7
8
#include "async_wrap.h"
9
#include "base_object.h"
10
#include "env.h"
11
#include "memory_tracker.h"
12
#include "node.h"
13
#include "node_internals.h"
14
#include "util.h"
15
16
#include "ares.h"
17
#include "v8.h"
18
#include "uv.h"
19
20
#include <unordered_set>
21
22
#ifdef __POSIX__
23
# include <netdb.h>
24
#endif  // __POSIX__
25
26
# include <ares_nameser.h>
27
28
namespace node {
29
namespace cares_wrap {
30
31
constexpr int ns_t_cname_or_a = -1;
32
constexpr int DNS_ESETSRVPENDING = -1000;
33
34
class ChannelWrap;
35
36
inline void safe_free_hostent(struct hostent* host);
37
38
using HostEntPointer = DeleteFnPtr<hostent, ares_free_hostent>;
39
using SafeHostEntPointer = DeleteFnPtr<hostent, safe_free_hostent>;
40
41
0
inline const char* ToErrorCodeString(int status) {
42
0
  switch (status) {
43
0
#define V(code) case ARES_##code: return #code;
44
0
    V(EADDRGETNETWORKPARAMS)
45
0
    V(EBADFAMILY)
46
0
    V(EBADFLAGS)
47
0
    V(EBADHINTS)
48
0
    V(EBADNAME)
49
0
    V(EBADQUERY)
50
0
    V(EBADRESP)
51
0
    V(EBADSTR)
52
0
    V(ECANCELLED)
53
0
    V(ECONNREFUSED)
54
0
    V(EDESTRUCTION)
55
0
    V(EFILE)
56
0
    V(EFORMERR)
57
0
    V(ELOADIPHLPAPI)
58
0
    V(ENODATA)
59
0
    V(ENOMEM)
60
0
    V(ENONAME)
61
0
    V(ENOTFOUND)
62
0
    V(ENOTIMP)
63
0
    V(ENOTINITIALIZED)
64
0
    V(EOF)
65
0
    V(EREFUSED)
66
0
    V(ESERVFAIL)
67
0
    V(ETIMEOUT)
68
0
#undef V
69
0
  }
70
71
0
  return "UNKNOWN_ARES_ERROR";
72
0
}
73
74
75
int FuzzParseSrvReply(
76
    Environment* env,
77
    const unsigned char* buf,
78
    int len,
79
    v8::Local<v8::Array> ret);
80
81
int FuzzParseNaptrReply(
82
    Environment* env,
83
    const unsigned char* buf,
84
    int len,
85
    v8::Local<v8::Array> ret);
86
87
int FuzzParseSoaReply(
88
    Environment* env,
89
    unsigned char* buf,
90
    int len,
91
    v8::Local<v8::Object>* ret);
92
93
int FuzzParseGeneralReply(
94
    Environment* env,
95
    unsigned char* buf,
96
    int len,
97
    int* type,
98
    v8::Local<v8::Array> ret);
99
100
int FuzzParseMxReply(
101
    Environment* env,
102
    const unsigned char* buf,
103
    int len,
104
    v8::Local<v8::Array> ret);
105
106
int FuzzParseCaaReply(
107
    Environment* env,
108
    const unsigned char* buf,
109
    int len,
110
    v8::Local<v8::Array> ret);
111
112
int FuzzParseTxtReply(
113
    Environment* env,
114
    const unsigned char* buf,
115
    int len,
116
    v8::Local<v8::Array> ret);
117
118
inline void cares_wrap_hostent_cpy(
119
    struct hostent* dest,
120
0
    const struct hostent* src) {
121
0
  dest->h_addr_list = nullptr;
122
0
  dest->h_addrtype = 0;
123
0
  dest->h_aliases = nullptr;
124
0
  dest->h_length = 0;
125
0
  dest->h_name = nullptr;
126
127
  /* copy `h_name` */
128
0
  size_t name_size = strlen(src->h_name) + 1;
129
0
  dest->h_name = node::Malloc<char>(name_size);
130
0
  memcpy(dest->h_name, src->h_name, name_size);
131
132
  /* copy `h_aliases` */
133
0
  size_t alias_count;
134
0
  for (alias_count = 0;
135
0
      src->h_aliases[alias_count] != nullptr;
136
0
      alias_count++) {
137
0
  }
138
139
0
  dest->h_aliases = node::Malloc<char*>(alias_count + 1);
140
0
  for (size_t i = 0; i < alias_count; i++) {
141
0
    const size_t cur_alias_size = strlen(src->h_aliases[i]) + 1;
142
0
    dest->h_aliases[i] = node::Malloc(cur_alias_size);
143
0
    memcpy(dest->h_aliases[i], src->h_aliases[i], cur_alias_size);
144
0
  }
145
0
  dest->h_aliases[alias_count] = nullptr;
146
147
  /* copy `h_addr_list` */
148
0
  size_t list_count;
149
0
  for (list_count = 0;
150
0
      src->h_addr_list[list_count] != nullptr;
151
0
      list_count++) {
152
0
  }
153
154
0
  dest->h_addr_list = node::Malloc<char*>(list_count + 1);
155
0
  for (size_t i = 0; i < list_count; i++) {
156
0
    dest->h_addr_list[i] = node::Malloc(src->h_length);
157
0
    memcpy(dest->h_addr_list[i], src->h_addr_list[i], src->h_length);
158
0
  }
159
0
  dest->h_addr_list[list_count] = nullptr;
160
161
  /* work after work */
162
0
  dest->h_length = src->h_length;
163
0
  dest->h_addrtype = src->h_addrtype;
164
0
}
165
166
167
struct NodeAresTask final : public MemoryRetainer {
168
  ChannelWrap* channel;
169
  ares_socket_t sock;
170
  uv_poll_t poll_watcher;
171
172
  inline void MemoryInfo(MemoryTracker* trakcer) const override;
173
  SET_MEMORY_INFO_NAME(NodeAresTask)
174
  SET_SELF_SIZE(NodeAresTask)
175
176
  struct Hash {
177
0
    inline size_t operator()(NodeAresTask* a) const {
178
0
      return std::hash<ares_socket_t>()(a->sock);
179
0
    }
180
  };
181
182
  struct Equal {
183
0
    inline bool operator()(NodeAresTask* a, NodeAresTask* b) const {
184
0
      return a->sock == b->sock;
185
0
    }
186
  };
187
188
  static NodeAresTask* Create(ChannelWrap* channel, ares_socket_t sock);
189
190
  using List = std::unordered_set<NodeAresTask*, Hash, Equal>;
191
};
192
193
class ChannelWrap final : public AsyncWrap {
194
 public:
195
  ChannelWrap(
196
      Environment* env,
197
      v8::Local<v8::Object> object,
198
      int timeout,
199
      int tries);
200
  ~ChannelWrap() override;
201
202
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
203
204
  void Setup();
205
  void EnsureServers();
206
  void StartTimer();
207
  void CloseTimer();
208
209
  void ModifyActivityQueryCount(int count);
210
211
0
  inline uv_timer_t* timer_handle() { return timer_handle_; }
212
0
  inline ares_channel cares_channel() { return channel_; }
213
0
  inline void set_query_last_ok(bool ok) { query_last_ok_ = ok; }
214
0
  inline void set_is_servers_default(bool is_default) {
215
0
    is_servers_default_ = is_default;
216
0
  }
217
0
  inline int active_query_count() { return active_query_count_; }
218
0
  inline NodeAresTask::List* task_list() { return &task_list_; }
219
220
  void MemoryInfo(MemoryTracker* tracker) const override;
221
  SET_MEMORY_INFO_NAME(ChannelWrap)
222
  SET_SELF_SIZE(ChannelWrap)
223
224
  static void AresTimeout(uv_timer_t* handle);
225
226
 private:
227
  uv_timer_t* timer_handle_ = nullptr;
228
  ares_channel channel_ = nullptr;
229
  bool query_last_ok_ = true;
230
  bool is_servers_default_ = true;
231
  bool library_inited_ = false;
232
  int timeout_;
233
  int tries_;
234
  int active_query_count_ = 0;
235
  NodeAresTask::List task_list_;
236
};
237
238
class GetAddrInfoReqWrap final : public ReqWrap<uv_getaddrinfo_t> {
239
 public:
240
  GetAddrInfoReqWrap(Environment* env,
241
                     v8::Local<v8::Object> req_wrap_obj,
242
                     bool verbatim);
243
244
  SET_NO_MEMORY_INFO()
245
  SET_MEMORY_INFO_NAME(GetAddrInfoReqWrap)
246
  SET_SELF_SIZE(GetAddrInfoReqWrap)
247
248
899
  bool verbatim() const { return verbatim_; }
249
250
 private:
251
  const bool verbatim_;
252
};
253
254
class GetNameInfoReqWrap final : public ReqWrap<uv_getnameinfo_t> {
255
 public:
256
  GetNameInfoReqWrap(Environment* env, v8::Local<v8::Object> req_wrap_obj);
257
258
  SET_NO_MEMORY_INFO()
259
  SET_MEMORY_INFO_NAME(GetNameInfoReqWrap)
260
  SET_SELF_SIZE(GetNameInfoReqWrap)
261
};
262
263
struct ResponseData final {
264
  int status;
265
  bool is_host;
266
  SafeHostEntPointer host;
267
  MallocedBuffer<unsigned char> buf;
268
};
269
270
template <typename Traits>
271
class QueryWrap final : public AsyncWrap {
272
 public:
273
  QueryWrap(ChannelWrap* channel, v8::Local<v8::Object> req_wrap_obj)
274
0
      : AsyncWrap(channel->env(), req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP),
275
0
        channel_(channel),
276
0
        trace_name_(Traits::name) {}
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::QueryWrap(node::cares_wrap::ChannelWrap*, v8::Local<v8::Object>)
277
278
0
  ~QueryWrap() {
279
0
    CHECK_EQ(false, persistent().IsEmpty());
280
281
    // Let Callback() know that this object no longer exists.
282
0
    if (callback_ptr_ != nullptr)
283
0
      *callback_ptr_ = nullptr;
284
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::~QueryWrap()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::~QueryWrap()
285
286
0
  int Send(const char* name) {
287
0
    return Traits::Send(this, name);
288
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::Send(char const*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::Send(char const*)
289
290
0
  void AresQuery(const char* name, int dnsclass, int type) {
291
0
    channel_->EnsureServers();
292
0
    TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
293
0
      TRACING_CATEGORY_NODE2(dns, native), trace_name_, this,
294
0
      "name", TRACE_STR_COPY(name));
295
0
    ares_query(
296
0
        channel_->cares_channel(),
297
0
        name,
298
0
        dnsclass,
299
0
        type,
300
0
        Callback,
301
0
        MakeCallbackPointer());
302
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::AresQuery(char const*, int, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::AresQuery(char const*, int, int)
303
304
0
  void ParseError(int status) {
305
0
    CHECK_NE(status, ARES_SUCCESS);
306
0
    v8::HandleScope handle_scope(env()->isolate());
307
0
    v8::Context::Scope context_scope(env()->context());
308
0
    const char* code = ToErrorCodeString(status);
309
0
    v8::Local<v8::Value> arg = OneByteString(env()->isolate(), code);
310
0
    TRACE_EVENT_NESTABLE_ASYNC_END1(
311
0
        TRACING_CATEGORY_NODE2(dns, native), trace_name_, this,
312
0
        "error", status);
313
0
    MakeCallback(env()->oncomplete_string(), 1, &arg);
314
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::ParseError(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::ParseError(int)
315
316
0
  const BaseObjectPtr<ChannelWrap>& channel() const { return channel_; }
317
318
0
  void AfterResponse() {
319
0
    CHECK(response_data_);
320
321
0
    int status = response_data_->status;
322
323
0
    if (status != ARES_SUCCESS)
324
0
      return ParseError(status);
325
326
0
    status = Traits::Parse(this, response_data_);
327
328
0
    if (status != ARES_SUCCESS)
329
0
      ParseError(status);
330
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::AfterResponse()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::AfterResponse()
331
332
0
  void* MakeCallbackPointer() {
333
0
    CHECK_NULL(callback_ptr_);
334
0
    callback_ptr_ = new QueryWrap<Traits>*(this);
335
0
    return callback_ptr_;
336
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::MakeCallbackPointer()
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::MakeCallbackPointer()
337
338
0
  static QueryWrap<Traits>* FromCallbackPointer(void* arg) {
339
0
    std::unique_ptr<QueryWrap<Traits>*> wrap_ptr {
340
0
        static_cast<QueryWrap<Traits>**>(arg)
341
0
    };
342
0
    QueryWrap<Traits>* wrap = *wrap_ptr.get();
343
0
    if (wrap == nullptr) return nullptr;
344
0
    wrap->callback_ptr_ = nullptr;
345
0
    return wrap;
346
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::FromCallbackPointer(void*)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::FromCallbackPointer(void*)
347
348
  static void Callback(
349
      void* arg,
350
      int status,
351
      int timeouts,
352
      unsigned char* answer_buf,
353
0
      int answer_len) {
354
0
    QueryWrap<Traits>* wrap = FromCallbackPointer(arg);
355
0
    if (wrap == nullptr) return;
356
357
0
    unsigned char* buf_copy = nullptr;
358
0
    if (status == ARES_SUCCESS) {
359
0
      buf_copy = node::Malloc<unsigned char>(answer_len);
360
0
      memcpy(buf_copy, answer_buf, answer_len);
361
0
    }
362
363
0
    wrap->response_data_ = std::make_unique<ResponseData>();
364
0
    ResponseData* data = wrap->response_data_.get();
365
0
    data->status = status;
366
0
    data->is_host = false;
367
0
    data->buf = MallocedBuffer<unsigned char>(buf_copy, answer_len);
368
369
0
    wrap->QueueResponseCallback(status);
370
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::Callback(void*, int, int, unsigned char*, int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::Callback(void*, int, int, unsigned char*, int)
371
372
  static void Callback(
373
      void* arg,
374
      int status,
375
      int timeouts,
376
0
      struct hostent* host) {
377
0
    QueryWrap<Traits>* wrap = FromCallbackPointer(arg);
378
0
    if (wrap == nullptr) return;
379
380
0
    struct hostent* host_copy = nullptr;
381
0
    if (status == ARES_SUCCESS) {
382
0
      host_copy = node::Malloc<hostent>(1);
383
0
      cares_wrap_hostent_cpy(host_copy, host);
384
0
    }
385
386
0
    wrap->response_data_ = std::make_unique<ResponseData>();
387
0
    ResponseData* data = wrap->response_data_.get();
388
0
    data->status = status;
389
0
    data->host.reset(host_copy);
390
0
    data->is_host = true;
391
392
0
    wrap->QueueResponseCallback(status);
393
0
  }
394
395
0
  void QueueResponseCallback(int status) {
396
0
    BaseObjectPtr<QueryWrap<Traits>> strong_ref{this};
397
0
    env()->SetImmediate([this, strong_ref](Environment*) {
398
0
      AfterResponse();
399
400
      // Delete once strong_ref goes out of scope.
401
0
      Detach();
402
0
    });
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::QueueResponseCallback(int)::{lambda(node::Environment*)#1}::operator()(node::Environment*) const
403
404
0
    channel_->set_query_last_ok(status != ARES_ECONNREFUSED);
405
0
    channel_->ModifyActivityQueryCount(-1);
406
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::QueueResponseCallback(int)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::QueueResponseCallback(int)
407
408
  void CallOnComplete(
409
      v8::Local<v8::Value> answer,
410
0
      v8::Local<v8::Value> extra = v8::Local<v8::Value>()) {
411
0
    v8::HandleScope handle_scope(env()->isolate());
412
0
    v8::Context::Scope context_scope(env()->context());
413
0
    v8::Local<v8::Value> argv[] = {
414
0
      v8::Integer::New(env()->isolate(), 0),
415
0
      answer,
416
0
      extra
417
0
    };
418
0
    const int argc = arraysize(argv) - extra.IsEmpty();
419
0
    TRACE_EVENT_NESTABLE_ASYNC_END0(
420
0
        TRACING_CATEGORY_NODE2(dns, native), trace_name_, this);
421
422
0
    MakeCallback(env()->oncomplete_string(), argc, argv);
423
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::CallOnComplete(v8::Local<v8::Value>, v8::Local<v8::Value>)
424
425
0
  void MemoryInfo(MemoryTracker* tracker) const override {
426
0
    tracker->TrackField("channel", channel_);
427
0
    if (response_data_) {
428
0
      tracker->TrackFieldWithSize("response", response_data_->buf.size);
429
0
    }
430
0
  }
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AnyTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ATraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::AaaaTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CaaTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::CnameTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::MxTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NsTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::TxtTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SrvTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::PtrTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::NaptrTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::SoaTraits>::MemoryInfo(node::MemoryTracker*) const
Unexecuted instantiation: node::cares_wrap::QueryWrap<node::cares_wrap::ReverseTraits>::MemoryInfo(node::MemoryTracker*) const
431
432
  SET_MEMORY_INFO_NAME(QueryWrap)
433
  SET_SELF_SIZE(QueryWrap<Traits>)
434
435
 private:
436
  BaseObjectPtr<ChannelWrap> channel_;
437
438
  std::unique_ptr<ResponseData> response_data_;
439
  const char* trace_name_;
440
  // Pointer to pointer to 'this' that can be reset from the destructor,
441
  // in order to let Callback() know that 'this' no longer exists.
442
  QueryWrap<Traits>** callback_ptr_ = nullptr;
443
};
444
445
struct AnyTraits final {
446
  static constexpr const char* name = "resolveAny";
447
  static int Send(QueryWrap<AnyTraits>* wrap, const char* name);
448
  static int Parse(
449
      QueryWrap<AnyTraits>* wrap,
450
      const std::unique_ptr<ResponseData>& response);
451
};
452
453
struct ATraits final {
454
  static constexpr const char* name = "resolve4";
455
  static int Send(QueryWrap<ATraits>* wrap, const char* name);
456
  static int Parse(
457
      QueryWrap<ATraits>* wrap,
458
      const std::unique_ptr<ResponseData>& response);
459
};
460
461
struct AaaaTraits final {
462
  static constexpr const char* name = "resolve6";
463
  static int Send(QueryWrap<AaaaTraits>* wrap, const char* name);
464
  static int Parse(
465
      QueryWrap<AaaaTraits>* wrap,
466
      const std::unique_ptr<ResponseData>& response);
467
};
468
469
struct CaaTraits final {
470
  static constexpr const char* name = "resolveCaa";
471
  static int Send(QueryWrap<CaaTraits>* wrap, const char* name);
472
  static int Parse(
473
      QueryWrap<CaaTraits>* wrap,
474
      const std::unique_ptr<ResponseData>& response);
475
};
476
477
struct CnameTraits final {
478
  static constexpr const char* name = "resolveCname";
479
  static int Send(QueryWrap<CnameTraits>* wrap, const char* name);
480
  static int Parse(
481
      QueryWrap<CnameTraits>* wrap,
482
      const std::unique_ptr<ResponseData>& response);
483
};
484
485
struct MxTraits final {
486
  static constexpr const char* name = "resolveMx";
487
  static int Send(QueryWrap<MxTraits>* wrap, const char* name);
488
  static int Parse(
489
      QueryWrap<MxTraits>* wrap,
490
      const std::unique_ptr<ResponseData>& response);
491
};
492
493
struct NsTraits final {
494
  static constexpr const char* name = "resolveNs";
495
  static int Send(QueryWrap<NsTraits>* wrap, const char* name);
496
  static int Parse(
497
      QueryWrap<NsTraits>* wrap,
498
      const std::unique_ptr<ResponseData>& response);
499
};
500
501
struct TxtTraits final {
502
  static constexpr const char* name = "resolveTxt";
503
  static int Send(QueryWrap<TxtTraits>* wrap, const char* name);
504
  static int Parse(
505
      QueryWrap<TxtTraits>* wrap,
506
      const std::unique_ptr<ResponseData>& response);
507
};
508
509
struct SrvTraits final {
510
  static constexpr const char* name = "resolveSrv";
511
  static int Send(QueryWrap<SrvTraits>* wrap, const char* name);
512
  static int Parse(
513
      QueryWrap<SrvTraits>* wrap,
514
      const std::unique_ptr<ResponseData>& response);
515
};
516
517
struct PtrTraits final {
518
  static constexpr const char* name = "resolvePtr";
519
  static int Send(QueryWrap<PtrTraits>* wrap, const char* name);
520
  static int Parse(
521
      QueryWrap<PtrTraits>* wrap,
522
      const std::unique_ptr<ResponseData>& response);
523
};
524
525
struct NaptrTraits final {
526
  static constexpr const char* name = "resolveNaptr";
527
  static int Send(QueryWrap<NaptrTraits>* wrap, const char* name);
528
  static int Parse(
529
      QueryWrap<NaptrTraits>* wrap,
530
      const std::unique_ptr<ResponseData>& response);
531
};
532
533
struct SoaTraits final {
534
  static constexpr const char* name = "resolveSoa";
535
  static int Send(QueryWrap<SoaTraits>* wrap, const char* name);
536
  static int Parse(
537
      QueryWrap<SoaTraits>* wrap,
538
      const std::unique_ptr<ResponseData>& response);
539
};
540
541
struct ReverseTraits final {
542
  static constexpr const char* name = "reverse";
543
  static int Send(QueryWrap<ReverseTraits>* wrap, const char* name);
544
  static int Parse(
545
      QueryWrap<ReverseTraits>* wrap,
546
      const std::unique_ptr<ResponseData>& response);
547
};
548
549
using QueryAnyWrap = QueryWrap<AnyTraits>;
550
using QueryAWrap = QueryWrap<ATraits>;
551
using QueryAaaaWrap = QueryWrap<AaaaTraits>;
552
using QueryCaaWrap = QueryWrap<CaaTraits>;
553
using QueryCnameWrap = QueryWrap<CnameTraits>;
554
using QueryMxWrap = QueryWrap<MxTraits>;
555
using QueryNsWrap = QueryWrap<NsTraits>;
556
using QueryTxtWrap = QueryWrap<TxtTraits>;
557
using QuerySrvWrap = QueryWrap<SrvTraits>;
558
using QueryPtrWrap = QueryWrap<PtrTraits>;
559
using QueryNaptrWrap = QueryWrap<NaptrTraits>;
560
using QuerySoaWrap = QueryWrap<SoaTraits>;
561
using GetHostByAddrWrap = QueryWrap<ReverseTraits>;
562
563
}  // namespace cares_wrap
564
}  // namespace node
565
566
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
567
568
#endif  // SRC_CARES_WRAP_H_