diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 825a85333bb6ba..c0368739ff03ef 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -224,7 +224,7 @@ int ParseGeneralReply( return status; CHECK_NOT_NULL(host); - HostentPointer ptr(host); + HostEntPointer ptr(host); /* If it's `CNAME`, return the CNAME value; * And if it's `CNAME_OR_A` and it has value in `h_name` and `h_aliases[0]`, @@ -802,7 +802,75 @@ void ChannelWrap::EnsureServers() { Setup(); } -void AnyTraits::Parse(QueryAnyWrap* wrap, unsigned char* buf, int len) { +int AnyTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_any); + return 0; +} + +int ATraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_a); + return 0; +} + +int AaaaTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_aaaa); + return 0; +} + +int CaaTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, T_CAA); + return 0; +} + +int CnameTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_cname); + return 0; +} + +int MxTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_mx); + return 0; +} + +int NsTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_ns); + return 0; +} + +int TxtTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_txt); + return 0; +} + +int SrvTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_srv); + return 0; +} + +int PtrTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_ptr); + return 0; +} + +int NaptrTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_naptr); + return 0; +} + +int SoaTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_soa); + return 0; +} + +int AnyTraits::Parse( + QueryAnyWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -824,7 +892,7 @@ void AnyTraits::Parse(QueryAnyWrap* wrap, unsigned char* buf, int len) { &naddrttls); uint32_t a_count = ret->Length(); if (status != ARES_SUCCESS && status != ARES_ENODATA) - return wrap->ParseError(status); + return status; if (type == ns_t_a) { CHECK_EQ(static_cast(naddrttls), a_count); @@ -869,7 +937,7 @@ void AnyTraits::Parse(QueryAnyWrap* wrap, unsigned char* buf, int len) { &naddr6ttls); uint32_t aaaa_count = ret->Length() - a_count; if (status != ARES_SUCCESS && status != ARES_ENODATA) - return wrap->ParseError(status); + return status; CHECK_EQ(aaaa_count, static_cast(naddr6ttls)); CHECK_EQ(ret->Length(), a_count + aaaa_count); @@ -891,14 +959,14 @@ void AnyTraits::Parse(QueryAnyWrap* wrap, unsigned char* buf, int len) { /* Parse MX records */ status = ParseMxReply(env, buf, len, ret, true); if (status != ARES_SUCCESS && status != ARES_ENODATA) - return wrap->ParseError(status); + return status; /* Parse NS records */ type = ns_t_ns; old_count = ret->Length(); status = ParseGeneralReply(env, buf, len, &type, ret); if (status != ARES_SUCCESS && status != ARES_ENODATA) - return wrap->ParseError(status); + return status; for (uint32_t i = old_count; i < ret->Length(); i++) { Local obj = Object::New(env->isolate()); @@ -914,17 +982,19 @@ void AnyTraits::Parse(QueryAnyWrap* wrap, unsigned char* buf, int len) { /* Parse TXT records */ status = ParseTxtReply(env, buf, len, ret, true); if (status != ARES_SUCCESS && status != ARES_ENODATA) - return wrap->ParseError(status); + return status; /* Parse SRV records */ status = ParseSrvReply(env, buf, len, ret, true); if (status != ARES_SUCCESS && status != ARES_ENODATA) - return; + return status; /* Parse PTR records */ type = ns_t_ptr; old_count = ret->Length(); status = ParseGeneralReply(env, buf, len, &type, ret); + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; for (uint32_t i = old_count; i < ret->Length(); i++) { Local obj = Object::New(env->isolate()); obj->Set(env->context(), @@ -939,13 +1009,13 @@ void AnyTraits::Parse(QueryAnyWrap* wrap, unsigned char* buf, int len) { /* Parse NAPTR records */ status = ParseNaptrReply(env, buf, len, ret, true); if (status != ARES_SUCCESS && status != ARES_ENODATA) - return wrap->ParseError(status); + return status; /* Parse SOA records */ Local soa_record = Local(); status = ParseSoaReply(env, buf, len, &soa_record); if (status != ARES_SUCCESS && status != ARES_ENODATA) - return wrap->ParseError(status); + return status; if (!soa_record.IsEmpty()) ret->Set(env->context(), ret->Length(), soa_record).Check(); @@ -953,12 +1023,21 @@ void AnyTraits::Parse(QueryAnyWrap* wrap, unsigned char* buf, int len) { /* Parse CAA records */ status = ParseCaaReply(env, buf, len, ret, true); if (status != ARES_SUCCESS && status != ARES_ENODATA) - return wrap->ParseError(status); + return status; wrap->CallOnComplete(ret); + return 0; } -void ATraits::Parse(QueryAWrap* wrap, unsigned char* buf, int len) { +int ATraits::Parse( + QueryAWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -976,14 +1055,23 @@ void ATraits::Parse(QueryAWrap* wrap, unsigned char* buf, int len) { addrttls, &naddrttls); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; Local ttls = AddrTTLToArray(env, addrttls, naddrttls); wrap->CallOnComplete(ret, ttls); + return 0; } -void AaaaTraits::Parse(QueryAaaaWrap* wrap, unsigned char* buf, int len) { +int AaaaTraits::Parse( + QueryAaaaWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -1001,14 +1089,23 @@ void AaaaTraits::Parse(QueryAaaaWrap* wrap, unsigned char* buf, int len) { addrttls, &naddrttls); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; Local ttls = AddrTTLToArray(env, addrttls, naddrttls); wrap->CallOnComplete(ret, ttls); + return 0; } -void CaaTraits::Parse(QueryCaaWrap* wrap, unsigned char* buf, int len) { +int CaaTraits::Parse( + QueryCaaWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -1016,12 +1113,21 @@ void CaaTraits::Parse(QueryCaaWrap* wrap, unsigned char* buf, int len) { Local ret = Array::New(env->isolate()); int status = ParseCaaReply(env, buf, len, ret); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; wrap->CallOnComplete(ret); + return 0; } -void CnameTraits::Parse(QueryCnameWrap* wrap, unsigned char* buf, int len) { +int CnameTraits::Parse( + QueryCnameWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -1030,12 +1136,21 @@ void CnameTraits::Parse(QueryCnameWrap* wrap, unsigned char* buf, int len) { int type = ns_t_cname; int status = ParseGeneralReply(env, buf, len, &type, ret); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; wrap->CallOnComplete(ret); + return 0; } -void MxTraits::Parse(QueryMxWrap* wrap, unsigned char* buf, int len) { +int MxTraits::Parse( + QueryMxWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -1044,12 +1159,21 @@ void MxTraits::Parse(QueryMxWrap* wrap, unsigned char* buf, int len) { int status = ParseMxReply(env, buf, len, mx_records); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; wrap->CallOnComplete(mx_records); + return 0; } -void NsTraits::Parse(QueryNsWrap* wrap, unsigned char* buf, int len) { +int NsTraits::Parse( + QueryNsWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -1058,12 +1182,21 @@ void NsTraits::Parse(QueryNsWrap* wrap, unsigned char* buf, int len) { Local names = Array::New(env->isolate()); int status = ParseGeneralReply(env, buf, len, &type, names); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; wrap->CallOnComplete(names); + return 0; } -void TxtTraits::Parse(QueryTxtWrap* wrap, unsigned char* buf, int len) { +int TxtTraits::Parse( + QueryTxtWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -1071,12 +1204,21 @@ void TxtTraits::Parse(QueryTxtWrap* wrap, unsigned char* buf, int len) { Local txt_records = Array::New(env->isolate()); int status = ParseTxtReply(env, buf, len, txt_records); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; wrap->CallOnComplete(txt_records); + return 0; } -void SrvTraits::Parse(QuerySrvWrap* wrap, unsigned char* buf, int len) { +int SrvTraits::Parse( + QuerySrvWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -1084,12 +1226,21 @@ void SrvTraits::Parse(QuerySrvWrap* wrap, unsigned char* buf, int len) { Local srv_records = Array::New(env->isolate()); int status = ParseSrvReply(env, buf, len, srv_records); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; wrap->CallOnComplete(srv_records); + return 0; } -void PtrTraits::Parse(QueryPtrWrap* wrap, unsigned char* buf, int len) { +int PtrTraits::Parse( + QueryPtrWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -1099,12 +1250,21 @@ void PtrTraits::Parse(QueryPtrWrap* wrap, unsigned char* buf, int len) { int status = ParseGeneralReply(env, buf, len, &type, aliases); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; wrap->CallOnComplete(aliases); + return 0; } -void NaptrTraits::Parse(QueryNaptrWrap* wrap, unsigned char* buf, int len) { +int NaptrTraits::Parse( + QueryNaptrWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -1112,12 +1272,21 @@ void NaptrTraits::Parse(QueryNaptrWrap* wrap, unsigned char* buf, int len) { Local naptr_records = Array::New(env->isolate()); int status = ParseNaptrReply(env, buf, len, naptr_records); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; wrap->CallOnComplete(naptr_records); + return 0; } -void SoaTraits::Parse(QuerySoaWrap* wrap, unsigned char* buf, int len) { +int SoaTraits::Parse( + QuerySoaWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -1126,7 +1295,7 @@ void SoaTraits::Parse(QuerySoaWrap* wrap, unsigned char* buf, int len) { int status = ares_parse_soa_reply(buf, len, &soa_out); if (status != ARES_SUCCESS) - return wrap->ParseError(status); + return status; Local soa_record = Object::New(env->isolate()); @@ -1157,6 +1326,7 @@ void SoaTraits::Parse(QuerySoaWrap* wrap, unsigned char* buf, int len) { ares_free_data(soa_out); wrap->CallOnComplete(soa_record); + return 0; } int ReverseTraits::Send(GetHostByAddrWrap* wrap, const char* name) { @@ -1188,11 +1358,19 @@ int ReverseTraits::Send(GetHostByAddrWrap* wrap, const char* name) { return 0; } -void ReverseTraits::Parse(GetHostByAddrWrap* wrap, struct hostent* host) { +int ReverseTraits::Parse( + GetHostByAddrWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(!response->is_host)) + return ARES_EBADRESP; + + struct hostent* host = response->host.get(); + Environment* env = wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); wrap->CallOnComplete(HostentToNames(env, host)); + return 0; } namespace { @@ -1650,6 +1828,31 @@ void StrError(const FunctionCallbackInfo& args) { } // namespace +inline void safe_free_hostent(struct hostent* host) { + int idx; + + if (host->h_addr_list != nullptr) { + idx = 0; + while (host->h_addr_list[idx]) { + free(host->h_addr_list[idx++]); + } + free(host->h_addr_list); + host->h_addr_list = nullptr; + } + + if (host->h_aliases != nullptr) { + idx = 0; + while (host->h_aliases[idx]) { + free(host->h_aliases[idx++]); + } + free(host->h_aliases); + host->h_aliases = nullptr; + } + + free(host->h_name); + free(host); +} + void Initialize(Local target, Local unused, Local context, diff --git a/src/cares_wrap.h b/src/cares_wrap.h index 58636032e49aac..bceafcb8b7f46b 100644 --- a/src/cares_wrap.h +++ b/src/cares_wrap.h @@ -48,7 +48,10 @@ constexpr int DNS_ESETSRVPENDING = -1000; class ChannelWrap; -using HostentPointer = DeleteFnPtr; +inline void safe_free_hostent(struct hostent* host); + +using HostEntPointer = DeleteFnPtr; +using SafeHostEntPointer = DeleteFnPtr; inline const char* ToErrorCodeString(int status) { switch (status) { @@ -223,6 +226,13 @@ class GetNameInfoReqWrap final : public ReqWrap { SET_SELF_SIZE(GetNameInfoReqWrap) }; +struct ResponseData final { + int status; + bool is_host; + SafeHostEntPointer host; + MallocedBuffer buf; +}; + template class QueryWrap final : public AsyncWrap { public: @@ -271,52 +281,18 @@ class QueryWrap final : public AsyncWrap { const BaseObjectPtr& channel() const { return channel_; } - static void safe_free_hostent(struct hostent* host) { - int idx; - - if (host->h_addr_list != nullptr) { - idx = 0; - while (host->h_addr_list[idx]) { - free(host->h_addr_list[idx++]); - } - free(host->h_addr_list); - host->h_addr_list = nullptr; - } - - if (host->h_aliases != nullptr) { - idx = 0; - while (host->h_aliases[idx]) { - free(host->h_aliases[idx++]); - } - free(host->h_aliases); - host->h_aliases = nullptr; - } - - free(host->h_name); - free(host); - } - - using HostEntPointer = DeleteFnPtr; - - struct ResponseData { - int status; - bool is_host; - HostEntPointer host; - MallocedBuffer buf; - }; - void AfterResponse() { CHECK(response_data_); - const int status = response_data_->status; + int status = response_data_->status; + + if (status != ARES_SUCCESS) + return ParseError(status); + + status = Traits::Parse(this, response_data_); - if (status != ARES_SUCCESS) { + if (status != ARES_SUCCESS) ParseError(status); - } else if (!response_data_->is_host) { - Parse(response_data_->buf.data, response_data_->buf.size); - } else { - Parse(response_data_->host.get()); - } } void* MakeCallbackPointer() { @@ -412,15 +388,6 @@ class QueryWrap final : public AsyncWrap { MakeCallback(env()->oncomplete_string(), argc, argv); } - // Subclasses should implement the appropriate Parse method. - void Parse(unsigned char* buf, int len) { - Traits::Parse(this, buf, len); - } - - void Parse(struct hostent* host) { - Traits::Parse(this, host); - } - void MemoryInfo(MemoryTracker* tracker) const override { tracker->TrackField("channel", channel_); if (response_data_) { @@ -441,194 +408,122 @@ class QueryWrap final : public AsyncWrap { QueryWrap** callback_ptr_ = nullptr; }; -template -struct QueryTraits final { - static constexpr const char* name = Impl::name; - - static int Send( - QueryWrap>* wrap, - const char* name) { - wrap->AresQuery(name, Impl::dns_class, Impl::type); - return 0; - } - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len) { - Impl::Parse(wrap, buf, len); - } - - static void Parse( - QueryWrap>* wrap, - struct hostent* host) { - UNREACHABLE(); - } -}; - struct AnyTraits final { static constexpr const char* name = "resolveAny"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_any; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct ATraits final { static constexpr const char* name = "resolve4"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_a; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct AaaaTraits final { static constexpr const char* name = "resolve6"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_aaaa; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct CaaTraits final { static constexpr const char* name = "resolveCaa"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = T_CAA; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct CnameTraits final { static constexpr const char* name = "resolveCname"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_cname; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct MxTraits final { static constexpr const char* name = "resolveMx"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_mx; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct NsTraits final { static constexpr const char* name = "resolveNs"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_ns; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct TxtTraits final { static constexpr const char* name = "resolveTxt"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_txt; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct SrvTraits final { static constexpr const char* name = "resolveSrv"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_srv; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct PtrTraits final { static constexpr const char* name = "resolvePtr"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_ptr; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct NaptrTraits final { static constexpr const char* name = "resolveNaptr"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_naptr; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct SoaTraits final { static constexpr const char* name = "resolveSoa"; - static constexpr int dns_class = ns_c_in; - static constexpr int type = ns_t_soa; - - static void Parse( - QueryWrap>* wrap, - unsigned char* buf, - int len); + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); }; struct ReverseTraits final { static constexpr const char* name = "reverse"; - - static int Send( - QueryWrap* wrap, - const char* name); - - static void Parse( - QueryWrap* wrap, - unsigned char* buf, - int len) { - UNREACHABLE(); - } - - static void Parse( + static int Send(QueryWrap* wrap, const char* name); + static int Parse( QueryWrap* wrap, - struct hostent* host); + const std::unique_ptr& response); }; -using QueryAnyWrap = QueryWrap>; -using QueryAWrap = QueryWrap>; -using QueryAaaaWrap = QueryWrap>; -using QueryCaaWrap = QueryWrap>; -using QueryCnameWrap = QueryWrap>; -using QueryMxWrap = QueryWrap>; -using QueryNsWrap = QueryWrap>; -using QueryTxtWrap = QueryWrap>; -using QuerySrvWrap = QueryWrap>; -using QueryPtrWrap = QueryWrap>; -using QueryNaptrWrap = QueryWrap>; -using QuerySoaWrap = QueryWrap>; +using QueryAnyWrap = QueryWrap; +using QueryAWrap = QueryWrap; +using QueryAaaaWrap = QueryWrap; +using QueryCaaWrap = QueryWrap; +using QueryCnameWrap = QueryWrap; +using QueryMxWrap = QueryWrap; +using QueryNsWrap = QueryWrap; +using QueryTxtWrap = QueryWrap; +using QuerySrvWrap = QueryWrap; +using QueryPtrWrap = QueryWrap; +using QueryNaptrWrap = QueryWrap; +using QuerySoaWrap = QueryWrap; using GetHostByAddrWrap = QueryWrap; } // namespace cares_wrap