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