diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 7ac6b766cda143..7225d20cae83b4 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -63,6 +63,7 @@ namespace cares_wrap { using v8::Array; using v8::ArrayBuffer; using v8::Context; +using v8::DictionaryTemplate; using v8::EscapableHandleScope; using v8::Exception; using v8::FunctionCallbackInfo; @@ -82,6 +83,7 @@ using v8::Null; using v8::Object; using v8::String; using v8::Uint32; +using v8::Undefined; using v8::Value; namespace { @@ -303,41 +305,43 @@ Maybe ParseMxReply(Environment* env, bool need_type = false) { HandleScope handle_scope(env->isolate()); + auto tmpl = env->mx_record_template(); + if (tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "exchange", + "priority", + "type", + }; + tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_mx_record_template(tmpl); + } + struct ares_mx_reply* mx_start; int status = ares_parse_mx_reply(buf, len, &mx_start); if (status != ARES_SUCCESS) return Just(status); + DeleteFnPtr free_me(mx_start); + uint32_t offset = ret->Length(); ares_mx_reply* current = mx_start; - for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { - Local mx_record = Object::New(env->isolate()); - if (mx_record - ->Set(env->context(), - env->exchange_string(), - OneByteString(env->isolate(), current->host)) - .IsNothing() || - mx_record - ->Set(env->context(), - env->priority_string(), - Integer::New(env->isolate(), current->priority)) - .IsNothing()) { - ares_free_data(mx_start); - return Nothing(); - } - if (need_type && - mx_record->Set(env->context(), env->type_string(), env->dns_mx_string()) - .IsNothing()) { - ares_free_data(mx_start); - return Nothing(); - } - if (ret->Set(env->context(), i + offset, mx_record).IsNothing()) { - ares_free_data(mx_start); + MaybeLocal values[] = { + Undefined(env->isolate()), // exchange + Undefined(env->isolate()), // priority + Undefined(env->isolate()), // type + }; + + for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { + values[0] = OneByteString(env->isolate(), current->host); + values[1] = Integer::New(env->isolate(), current->priority); + values[2] = env->dns_mx_string(); + Local record; + if (!NewDictionaryInstance(env->context(), tmpl, values).ToLocal(&record) || + ret->Set(env->context(), i + offset, record).IsNothing()) { return Nothing(); } } - ares_free_data(mx_start); return Just(ARES_SUCCESS); } @@ -348,43 +352,52 @@ Maybe ParseCaaReply(Environment* env, bool need_type = false) { HandleScope handle_scope(env->isolate()); + auto tmpl = env->caa_record_template(); + if (tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "critical", + "type", + }; + tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_caa_record_template(tmpl); + } + struct ares_caa_reply* caa_start; int status = ares_parse_caa_reply(buf, len, &caa_start); if (status != ARES_SUCCESS) return Just(status); + DeleteFnPtr free_me(caa_start); + + MaybeLocal values[] = { + Undefined(env->isolate()), // critical + Undefined(env->isolate()), // type + }; uint32_t offset = ret->Length(); ares_caa_reply* current = caa_start; for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { - Local caa_record = Object::New(env->isolate()); + values[0] = Integer::New(env->isolate(), current->critical); + values[1] = env->dns_caa_string(); + Local caa_record; + if (!NewDictionaryInstance(env->context(), tmpl, values) + .ToLocal(&caa_record)) { + return Nothing(); + } + // This additional property is not part of the template as it is + // variable based on the record. if (caa_record - ->Set(env->context(), - env->dns_critical_string(), - Integer::New(env->isolate(), current->critical)) - .IsNothing() || - caa_record ->Set(env->context(), OneByteString(env->isolate(), current->property), OneByteString(env->isolate(), current->value)) .IsNothing()) { - ares_free_data(caa_start); - return Nothing(); - } - if (need_type && - caa_record - ->Set(env->context(), env->type_string(), env->dns_caa_string()) - .IsNothing()) { - ares_free_data(caa_start); return Nothing(); } if (ret->Set(env->context(), i + offset, caa_record).IsNothing()) { - ares_free_data(caa_start); return Nothing(); } } - ares_free_data(caa_start); return Just(ARES_SUCCESS); } @@ -394,6 +407,18 @@ Maybe ParseTlsaReply(Environment* env, Local ret) { EscapableHandleScope handle_scope(env->isolate()); + auto tmpl = env->tlsa_record_template(); + if (tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "certUsage", + "selector", + "match", + "data", + }; + tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_tlsa_record_template(tmpl); + } + ares_dns_record_t* dnsrec = nullptr; int status = ares_dns_parse(buf, len, 0, &dnsrec); @@ -402,9 +427,18 @@ Maybe ParseTlsaReply(Environment* env, return Just(status); } + DeleteFnPtr free_me(dnsrec); + uint32_t offset = ret->Length(); size_t rr_count = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); + MaybeLocal values[] = { + Undefined(env->isolate()), // certUsage + Undefined(env->isolate()), // selector + Undefined(env->isolate()), // match + Undefined(env->isolate()), // data + }; + for (size_t i = 0; i < rr_count; i++) { const ares_dns_rr_t* rr = ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i); @@ -422,32 +456,19 @@ Maybe ParseTlsaReply(Environment* env, Local data_ab = ArrayBuffer::New(env->isolate(), data_len); memcpy(data_ab->Data(), data, data_len); - Local tlsa_rec = Object::New(env->isolate()); + values[0] = Integer::NewFromUnsigned(env->isolate(), certusage); + values[1] = Integer::NewFromUnsigned(env->isolate(), selector); + values[2] = Integer::NewFromUnsigned(env->isolate(), match); + values[3] = data_ab; - if (tlsa_rec - ->Set(env->context(), - env->cert_usage_string(), - Integer::NewFromUnsigned(env->isolate(), certusage)) - .IsNothing() || - tlsa_rec - ->Set(env->context(), - env->selector_string(), - Integer::NewFromUnsigned(env->isolate(), selector)) - .IsNothing() || - tlsa_rec - ->Set(env->context(), - env->match_string(), - Integer::NewFromUnsigned(env->isolate(), match)) - .IsNothing() || - tlsa_rec->Set(env->context(), env->data_string(), data_ab) - .IsNothing() || + Local tlsa_rec; + if (!NewDictionaryInstance(env->context(), tmpl, values) + .ToLocal(&tlsa_rec) || ret->Set(env->context(), offset + i, tlsa_rec).IsNothing()) { - ares_dns_record_destroy(dnsrec); return Nothing(); } } - ares_dns_record_destroy(dnsrec); return Just(ARES_SUCCESS); } @@ -458,70 +479,81 @@ Maybe ParseTxtReply(Environment* env, bool need_type = false) { HandleScope handle_scope(env->isolate()); + auto tmpl = env->txt_record_template(); + if (tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "entries", + "type", + }; + tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_txt_record_template(tmpl); + } + struct ares_txt_ext* txt_out; int status = ares_parse_txt_reply_ext(buf, len, &txt_out); if (status != ARES_SUCCESS) return Just(status); + DeleteFnPtr free_me(txt_out); Local txt_chunk; + LocalVector chunks(env->isolate()); struct ares_txt_ext* current = txt_out; - uint32_t i = 0, j; + uint32_t i = 0; uint32_t offset = ret->Length(); - for (j = 0; current != nullptr; current = current->next) { + + MaybeLocal values[] = { + Undefined(env->isolate()), // entries + Undefined(env->isolate()), // type + }; + + for (; current != nullptr; current = current->next) { Local txt = OneByteString(env->isolate(), current->txt, current->length); // New record found - write out the current chunk if (current->record_start) { - if (!txt_chunk.IsEmpty()) { + if (!chunks.empty()) { + auto txt_chunk = + Array::New(env->isolate(), chunks.data(), chunks.size()); + chunks.clear(); if (need_type) { - Local elem = Object::New(env->isolate()); - if (elem->Set(env->context(), env->entries_string(), txt_chunk) - .IsNothing() || - elem->Set( - env->context(), env->type_string(), env->dns_txt_string()) - .IsNothing() || + values[0] = txt_chunk; + values[1] = env->dns_txt_string(); + Local elem; + if (!NewDictionaryInstance(env->context(), tmpl, values) + .ToLocal(&elem) || ret->Set(env->context(), offset + i++, elem).IsNothing()) { - ares_free_data(txt_out); return Nothing(); } } else if (ret->Set(env->context(), offset + i++, txt_chunk) .IsNothing()) { - ares_free_data(txt_out); return Nothing(); } } txt_chunk = Array::New(env->isolate()); - j = 0; } - if (txt_chunk->Set(env->context(), j++, txt).IsNothing()) { - ares_free_data(txt_out); - return Nothing(); - } + chunks.push_back(txt); } // Push last chunk if it isn't empty - if (!txt_chunk.IsEmpty()) { + if (!chunks.empty()) { + txt_chunk = Array::New(env->isolate(), chunks.data(), chunks.size()); if (need_type) { - Local elem = Object::New(env->isolate()); - if (elem->Set(env->context(), env->entries_string(), txt_chunk) - .IsNothing() || - elem->Set(env->context(), env->type_string(), env->dns_txt_string()) - .IsNothing() || + values[0] = txt_chunk; + values[1] = env->dns_txt_string(); + Local elem; + if (!NewDictionaryInstance(env->context(), tmpl, values).ToLocal(&elem) || ret->Set(env->context(), offset + i, elem).IsNothing()) { - ares_free_data(txt_out); return Nothing(); } } else if (ret->Set(env->context(), offset + i, txt_chunk).IsNothing()) { - ares_free_data(txt_out); return Nothing(); } } - ares_free_data(txt_out); return Just(ARES_SUCCESS); } @@ -532,53 +564,49 @@ Maybe ParseSrvReply(Environment* env, bool need_type = false) { HandleScope handle_scope(env->isolate()); + auto tmpl = env->srv_record_template(); + if (tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "name", + "port", + "priority", + "weight", + "type", + }; + tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_srv_record_template(tmpl); + } + struct ares_srv_reply* srv_start; int status = ares_parse_srv_reply(buf, len, &srv_start); if (status != ARES_SUCCESS) return Just(status); + DeleteFnPtr free_me(srv_start); + + MaybeLocal values[] = { + Undefined(env->isolate()), // name + Undefined(env->isolate()), // port + Undefined(env->isolate()), // priority + Undefined(env->isolate()), // weight + Undefined(env->isolate()), // type + }; ares_srv_reply* current = srv_start; int offset = ret->Length(); for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { - Local srv_record = Object::New(env->isolate()); - - if (srv_record - ->Set(env->context(), - env->name_string(), - OneByteString(env->isolate(), current->host)) - .IsNothing() || - srv_record - ->Set(env->context(), - env->port_string(), - Integer::New(env->isolate(), current->port)) - .IsNothing() || - srv_record - ->Set(env->context(), - env->priority_string(), - Integer::New(env->isolate(), current->priority)) - .IsNothing() || - srv_record - ->Set(env->context(), - env->weight_string(), - Integer::New(env->isolate(), current->weight)) - .IsNothing()) { - ares_free_data(srv_start); - return Nothing(); - } - if (need_type && - srv_record - ->Set(env->context(), env->type_string(), env->dns_srv_string()) - .IsNothing()) { - ares_free_data(srv_start); - return Nothing(); - } - - if (ret->Set(env->context(), i + offset, srv_record).IsNothing()) { - ares_free_data(srv_start); + values[0] = OneByteString(env->isolate(), current->host); + values[1] = Integer::New(env->isolate(), current->port); + values[2] = Integer::New(env->isolate(), current->priority); + values[3] = Integer::New(env->isolate(), current->weight); + values[4] = env->dns_srv_string(); + + Local srv_record; + if (!NewDictionaryInstance(env->context(), tmpl, values) + .ToLocal(&srv_record) || + ret->Set(env->context(), i + offset, srv_record).IsNothing()) { return Nothing(); } } - ares_free_data(srv_start); return Just(ARES_SUCCESS); } @@ -589,73 +617,87 @@ Maybe ParseNaptrReply(Environment* env, bool need_type = false) { HandleScope handle_scope(env->isolate()); + auto tmpl = env->naptr_record_template(); + if (tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "flags", + "service", + "regexp", + "replacement", + "order", + "preference", + "type", + }; + tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_naptr_record_template(tmpl); + } + ares_naptr_reply* naptr_start; int status = ares_parse_naptr_reply(buf, len, &naptr_start); - if (status != ARES_SUCCESS) return Just(status); + DeleteFnPtr free_me(naptr_start); + + MaybeLocal values[] = { + Undefined(env->isolate()), // flags + Undefined(env->isolate()), // service + Undefined(env->isolate()), // regexp + Undefined(env->isolate()), // replacement + Undefined(env->isolate()), // order + Undefined(env->isolate()), // preference + Undefined(env->isolate()), // type + }; ares_naptr_reply* current = naptr_start; int offset = ret->Length(); for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { - Local naptr_record = Object::New(env->isolate()); - - if (naptr_record - ->Set(env->context(), - env->flags_string(), - OneByteString(env->isolate(), current->flags)) - .IsNothing() || - naptr_record - ->Set(env->context(), - env->service_string(), - OneByteString(env->isolate(), current->service)) - .IsNothing() || - naptr_record - ->Set(env->context(), - env->regexp_string(), - OneByteString(env->isolate(), current->regexp)) - .IsNothing() || - naptr_record - ->Set(env->context(), - env->replacement_string(), - OneByteString(env->isolate(), current->replacement)) - .IsNothing() || - naptr_record - ->Set(env->context(), - env->order_string(), - Integer::New(env->isolate(), current->order)) - .IsNothing() || - naptr_record - ->Set(env->context(), - env->preference_string(), - Integer::New(env->isolate(), current->preference)) - .IsNothing()) { - ares_free_data(naptr_start); - return Nothing(); - } - if (need_type && - naptr_record - ->Set(env->context(), env->type_string(), env->dns_naptr_string()) - .IsNothing()) { - ares_free_data(naptr_start); - return Nothing(); + values[0] = OneByteString(env->isolate(), current->flags); + values[1] = OneByteString(env->isolate(), current->service); + values[2] = OneByteString(env->isolate(), current->regexp); + values[3] = OneByteString(env->isolate(), current->replacement); + values[4] = Integer::New(env->isolate(), current->order); + values[5] = Integer::New(env->isolate(), current->preference); + if (need_type) { + values[6] = env->dns_naptr_string(); } - if (ret->Set(env->context(), i + offset, naptr_record).IsNothing()) { - ares_free_data(naptr_start); + Local naptr_record; + if (!NewDictionaryInstance(env->context(), tmpl, values) + .ToLocal(&naptr_record) || + ret->Set(env->context(), i + offset, naptr_record).IsNothing()) { return Nothing(); } } - ares_free_data(naptr_start); return Just(ARES_SUCCESS); } +Local getSoaRecordTemplate(Environment* env) { + auto tmpl = env->soa_record_template(); + if (tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "nsname", + "hostmaster", + "serial", + "refresh", + "retry", + "expire", + "minttl", + "type", + }; + tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_soa_record_template(tmpl); + } + return tmpl; +} + Maybe ParseSoaReply(Environment* env, unsigned char* buf, int len, Local* ret) { EscapableHandleScope handle_scope(env->isolate()); + auto tmpl = getSoaRecordTemplate(env); + // Manage memory using standardard smart pointer std::unique_tr struct AresDeleter { void operator()(char* ptr) const noexcept { ares_free_string(ptr); } @@ -680,6 +722,17 @@ Maybe ParseSoaReply(Environment* env, } ptr += temp_len + NS_QFIXEDSZ; + MaybeLocal values[] = { + Undefined(env->isolate()), // nsname + Undefined(env->isolate()), // hostmaster + Undefined(env->isolate()), // serial + Undefined(env->isolate()), // refresh + Undefined(env->isolate()), // retry + Undefined(env->isolate()), // expire + Undefined(env->isolate()), // minttl + Undefined(env->isolate()), // type + }; + for (unsigned int i = 0; i < ancount; i++) { char* rr_name_temp = nullptr; long rr_temp_len; // NOLINT(runtime/int) @@ -734,45 +787,17 @@ Maybe ParseSoaReply(Environment* env, const unsigned int expire = nbytes::ReadUint32BE(ptr + 3 * 4); const unsigned int minttl = nbytes::ReadUint32BE(ptr + 4 * 4); - Local soa_record = Object::New(env->isolate()); - if (soa_record - ->Set(env->context(), - env->nsname_string(), - OneByteString(env->isolate(), nsname.get())) - .IsNothing() || - soa_record - ->Set(env->context(), - env->hostmaster_string(), - OneByteString(env->isolate(), hostmaster.get())) - .IsNothing() || - soa_record - ->Set(env->context(), - env->serial_string(), - Integer::NewFromUnsigned(env->isolate(), serial)) - .IsNothing() || - soa_record - ->Set(env->context(), - env->refresh_string(), - Integer::New(env->isolate(), refresh)) - .IsNothing() || - soa_record - ->Set(env->context(), - env->retry_string(), - Integer::New(env->isolate(), retry)) - .IsNothing() || - soa_record - ->Set(env->context(), - env->expire_string(), - Integer::New(env->isolate(), expire)) - .IsNothing() || - soa_record - ->Set(env->context(), - env->minttl_string(), - Integer::NewFromUnsigned(env->isolate(), minttl)) - .IsNothing() || - soa_record - ->Set(env->context(), env->type_string(), env->dns_soa_string()) - .IsNothing()) { + values[0] = OneByteString(env->isolate(), nsname.get()); + values[1] = OneByteString(env->isolate(), hostmaster.get()); + values[2] = Integer::NewFromUnsigned(env->isolate(), serial); + values[3] = Integer::New(env->isolate(), refresh); + values[4] = Integer::New(env->isolate(), retry); + values[5] = Integer::New(env->isolate(), expire); + values[6] = Integer::NewFromUnsigned(env->isolate(), minttl); + values[7] = env->dns_soa_string(); + Local soa_record; + if (!NewDictionaryInstance(env->context(), tmpl, values) + .ToLocal(&soa_record)) { return Nothing(); } @@ -1083,30 +1108,61 @@ Maybe AnyTraits::Parse(QueryAnyWrap* wrap, if (type == ns_t_a) { CHECK_EQ(static_cast(naddrttls), a_count); + + auto tmpl = env->a_record_template(); + if (tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "address", + "ttl", + "type", + }; + tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_a_record_template(tmpl); + } + MaybeLocal values[] = { + Undefined(env->isolate()), // address + Undefined(env->isolate()), // ttl + Undefined(env->isolate()), // type + }; + for (uint32_t i = 0; i < a_count; i++) { - Local obj = Object::New(env->isolate()); Local address; - if (!ret->Get(env->context(), i).ToLocal(&address) || - obj->Set(env->context(), env->address_string(), address) - .IsNothing() || - obj->Set(env->context(), - env->ttl_string(), - Integer::NewFromUnsigned(env->isolate(), addrttls[i].ttl)) - .IsNothing() || - obj->Set(env->context(), env->type_string(), env->dns_a_string()) - .IsNothing() || + if (!ret->Get(env->context(), i).ToLocal(&address)) { + return Nothing(); + } + values[0] = address; + values[1] = Integer::NewFromUnsigned(env->isolate(), addrttls[i].ttl); + values[2] = env->dns_a_string(); + + Local obj; + if (!NewDictionaryInstance(env->context(), tmpl, values).ToLocal(&obj) || ret->Set(env->context(), i, obj).IsNothing()) { return Nothing(); } } } else { + auto tmpl = env->cname_record_template(); + if (tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "value", + "type", + }; + tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_cname_record_template(tmpl); + } + MaybeLocal values[] = { + Undefined(env->isolate()), // value + Undefined(env->isolate()), // type + }; for (uint32_t i = 0; i < a_count; i++) { - Local obj = Object::New(env->isolate()); Local value; - if (!ret->Get(env->context(), i).ToLocal(&value) || - obj->Set(env->context(), env->value_string(), value).IsNothing() || - obj->Set(env->context(), env->type_string(), env->dns_cname_string()) - .IsNothing() || + if (!ret->Get(env->context(), i).ToLocal(&value)) { + return Nothing(); + } + values[0] = value; + values[1] = env->dns_cname_string(); + Local obj; + if (!NewDictionaryInstance(env->context(), tmpl, values).ToLocal(&obj) || ret->Set(env->context(), i, obj).IsNothing()) { return Nothing(); } @@ -1128,19 +1184,35 @@ Maybe AnyTraits::Parse(QueryAnyWrap* wrap, CHECK_EQ(aaaa_count, static_cast(naddr6ttls)); CHECK_EQ(ret->Length(), a_count + aaaa_count); + + auto tmpl = env->aaaa_record_template(); + if (tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "address", + "ttl", + "type", + }; + tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_aaaa_record_template(tmpl); + } + + MaybeLocal values[] = { + Undefined(env->isolate()), // address + Undefined(env->isolate()), // ttl + Undefined(env->isolate()), // type + }; + for (uint32_t i = a_count; i < ret->Length(); i++) { - Local obj = Object::New(env->isolate()); Local address; - - if (!ret->Get(env->context(), i).ToLocal(&address) || - obj->Set(env->context(), env->address_string(), address).IsNothing() || - obj->Set(env->context(), - env->ttl_string(), - Integer::NewFromUnsigned(env->isolate(), - addr6ttls[i - a_count].ttl)) - .IsNothing() || - obj->Set(env->context(), env->type_string(), env->dns_aaaa_string()) - .IsNothing() || + if (!ret->Get(env->context(), i).ToLocal(&address)) { + return Nothing(); + } + values[0] = address; + values[1] = + Integer::NewFromUnsigned(env->isolate(), addr6ttls[i - a_count].ttl); + values[2] = env->dns_aaaa_string(); + Local obj; + if (!NewDictionaryInstance(env->context(), tmpl, values).ToLocal(&obj) || ret->Set(env->context(), i, obj).IsNothing()) { return Nothing(); } @@ -1164,14 +1236,31 @@ Maybe AnyTraits::Parse(QueryAnyWrap* wrap, return Just(status); } + auto dns_ns_tmpl = env->dns_ns_record_template(); + if (dns_ns_tmpl.IsEmpty()) { + static constexpr std::string_view names[] = { + "value", + "type", + }; + dns_ns_tmpl = DictionaryTemplate::New(env->isolate(), names); + env->set_dns_ns_record_template(dns_ns_tmpl); + } + + MaybeLocal values_ns[] = { + Undefined(env->isolate()), // value + Undefined(env->isolate()), // type + }; + for (uint32_t i = old_count; i < ret->Length(); i++) { - Local obj = Object::New(env->isolate()); Local value; - - if (!ret->Get(env->context(), i).ToLocal(&value) || - obj->Set(env->context(), env->value_string(), value).IsNothing() || - obj->Set(env->context(), env->type_string(), env->dns_ns_string()) - .IsNothing() || + if (!ret->Get(env->context(), i).ToLocal(&value)) { + return Nothing(); + } + values_ns[0] = value; + values_ns[1] = env->dns_ns_string(); + Local obj; + if (!NewDictionaryInstance(env->context(), dns_ns_tmpl, values_ns) + .ToLocal(&obj) || ret->Set(env->context(), i, obj).IsNothing()) { return Nothing(); } @@ -1201,14 +1290,17 @@ Maybe AnyTraits::Parse(QueryAnyWrap* wrap, } if (status != ARES_SUCCESS && status != ARES_ENODATA) return Just(status); + for (uint32_t i = old_count; i < ret->Length(); i++) { - Local obj = Object::New(env->isolate()); Local value; - - if (!ret->Get(env->context(), i).ToLocal(&value) || - obj->Set(env->context(), env->value_string(), value).IsNothing() || - obj->Set(env->context(), env->type_string(), env->dns_ptr_string()) - .IsNothing() || + if (!ret->Get(env->context(), i).ToLocal(&value)) { + return Nothing(); + } + values_ns[0] = value; + values_ns[1] = env->dns_ptr_string(); + Local obj; + if (!NewDictionaryInstance(env->context(), dns_ns_tmpl, values_ns) + .ToLocal(&obj) || ret->Set(env->context(), i, obj).IsNothing()) { return Nothing(); } @@ -1568,6 +1660,18 @@ Maybe SoaTraits::Parse(QuerySoaWrap* wrap, HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); + auto tmpl = getSoaRecordTemplate(env); + MaybeLocal values[] = { + Undefined(env->isolate()), // nsname + Undefined(env->isolate()), // hostmaster + Undefined(env->isolate()), // serial + Undefined(env->isolate()), // refresh + Undefined(env->isolate()), // retry + Undefined(env->isolate()), // expire + Undefined(env->isolate()), // minttl + Undefined(env->isolate()), // type + }; + ares_soa_reply* soa_out; int status = ares_parse_soa_reply(buf, len, &soa_out); @@ -1575,43 +1679,16 @@ Maybe SoaTraits::Parse(QuerySoaWrap* wrap, auto cleanup = OnScopeLeave([&]() { ares_free_data(soa_out); }); - Local soa_record = Object::New(env->isolate()); - - if (soa_record - ->Set(env->context(), - env->nsname_string(), - OneByteString(env->isolate(), soa_out->nsname)) - .IsNothing() || - soa_record - ->Set(env->context(), - env->hostmaster_string(), - OneByteString(env->isolate(), soa_out->hostmaster)) - .IsNothing() || - soa_record - ->Set(env->context(), - env->serial_string(), - Integer::NewFromUnsigned(env->isolate(), soa_out->serial)) - .IsNothing() || - soa_record - ->Set(env->context(), - env->refresh_string(), - Integer::New(env->isolate(), soa_out->refresh)) - .IsNothing() || - soa_record - ->Set(env->context(), - env->retry_string(), - Integer::New(env->isolate(), soa_out->retry)) - .IsNothing() || - soa_record - ->Set(env->context(), - env->expire_string(), - Integer::New(env->isolate(), soa_out->expire)) - .IsNothing() || - soa_record - ->Set(env->context(), - env->minttl_string(), - Integer::NewFromUnsigned(env->isolate(), soa_out->minttl)) - .IsNothing()) { + values[0] = OneByteString(env->isolate(), soa_out->nsname); + values[1] = OneByteString(env->isolate(), soa_out->hostmaster); + values[2] = Integer::NewFromUnsigned(env->isolate(), soa_out->serial); + values[3] = Integer::New(env->isolate(), soa_out->refresh); + values[4] = Integer::New(env->isolate(), soa_out->retry); + values[5] = Integer::New(env->isolate(), soa_out->expire); + values[6] = Integer::NewFromUnsigned(env->isolate(), soa_out->minttl); + Local soa_record; + if (!NewDictionaryInstance(env->context(), tmpl, values) + .ToLocal(&soa_record)) { return Nothing(); } diff --git a/src/env_properties.h b/src/env_properties.h index c2becb695b4635..0573cf65d6aef5 100644 --- a/src/env_properties.h +++ b/src/env_properties.h @@ -89,7 +89,6 @@ V(cached_data_produced_string, "cachedDataProduced") \ V(cached_data_rejected_string, "cachedDataRejected") \ V(cached_data_string, "cachedData") \ - V(cert_usage_string, "certUsage") \ V(change_string, "change") \ V(changes_string, "changes") \ V(chunks_sent_since_last_write_string, "chunksSentSinceLastWrite") \ @@ -142,7 +141,6 @@ V(dns_a_string, "A") \ V(dns_aaaa_string, "AAAA") \ V(dns_caa_string, "CAA") \ - V(dns_critical_string, "critical") \ V(dns_cname_string, "CNAME") \ V(dns_mx_string, "MX") \ V(dns_naptr_string, "NAPTR") \ @@ -158,7 +156,6 @@ V(emit_string, "emit") \ V(emit_warning_string, "emitWarning") \ V(encoding_string, "encoding") \ - V(entries_string, "entries") \ V(env_pairs_string, "envPairs") \ V(env_var_settings_string, "envVarSettings") \ V(err_sqlite_error_string, "ERR_SQLITE_ERROR") \ @@ -168,8 +165,6 @@ V(errstr_string, "errstr") \ V(events_waiting, "eventsWaiting") \ V(events, "events") \ - V(exchange_string, "exchange") \ - V(expire_string, "expire") \ V(exponent_string, "exponent") \ V(exports_string, "exports") \ V(external_stream_string, "_externalStream") \ @@ -200,7 +195,6 @@ V(help_text_string, "helpText") \ V(homedir_string, "homedir") \ V(host_string, "host") \ - V(hostmaster_string, "hostmaster") \ V(hostname_string, "hostname") \ V(href_string, "href") \ V(http_1_1_string, "http/1.1") \ @@ -222,10 +216,8 @@ V(jwk_d_string, "d") \ V(jwk_dp_string, "dp") \ V(jwk_dq_string, "dq") \ - V(jwk_dsa_string, "DSA") \ V(jwk_e_string, "e") \ V(jwk_ec_string, "EC") \ - V(jwk_g_string, "g") \ V(jwk_k_string, "k") \ V(jwk_kty_string, "kty") \ V(jwk_n_string, "n") \ @@ -245,8 +237,6 @@ V(length_string, "length") \ V(library_string, "library") \ V(loop_count, "loopCount") \ - V(mac_string, "mac") \ - V(match_string, "match") \ V(max_buffer_string, "maxBuffer") \ V(max_concurrent_streams_string, "maxConcurrentStreams") \ V(message_port_constructor_string, "MessagePort") \ @@ -254,7 +244,6 @@ V(message_string, "message") \ V(messageerror_string, "messageerror") \ V(mgf1_hash_algorithm_string, "mgf1HashAlgorithm") \ - V(minttl_string, "minttl") \ V(mode_string, "mode") \ V(module_string, "module") \ V(modulus_length_string, "modulusLength") \ @@ -262,7 +251,6 @@ V(named_curve_string, "namedCurve") \ V(next_string, "next") \ V(node_string, "node") \ - V(nsname_string, "nsname") \ V(object_string, "Object") \ V(ocsp_request_string, "OCSPRequest") \ V(oncertcb_string, "oncertcb") \ @@ -289,7 +277,6 @@ V(ongracefulclosecomplete_string, "ongracefulclosecomplete") \ V(openssl_error_stack, "opensslErrorStack") \ V(options_string, "options") \ - V(order_string, "order") \ V(original_string, "original") \ V(output_string, "output") \ V(overlapped_string, "overlapped") \ @@ -309,9 +296,7 @@ V(port1_string, "port1") \ V(port2_string, "port2") \ V(port_string, "port") \ - V(preference_string, "preference") \ V(primordials_string, "primordials") \ - V(priority_string, "priority") \ V(process_string, "process") \ V(progress_string, "progress") \ V(promise_string, "promise") \ @@ -320,16 +305,12 @@ V(psk_string, "psk") \ V(public_exponent_string, "publicExponent") \ V(rate_string, "rate") \ - V(raw_string, "raw") \ V(read_host_object_string, "_readHostObject") \ V(readable_string, "readable") \ V(read_bigints_string, "readBigInts") \ V(reason_string, "reason") \ - V(refresh_string, "refresh") \ - V(regexp_string, "regexp") \ V(remaining_pages_string, "remainingPages") \ V(rename_string, "rename") \ - V(replacement_string, "replacement") \ V(required_module_facade_url_string, \ "node:internal/require_module_default_facade") \ V(required_module_facade_source_string, \ @@ -338,14 +319,10 @@ V(require_string, "require") \ V(resource_string, "resource") \ V(result_string, "result") \ - V(retry_string, "retry") \ V(return_arrays_string, "returnArrays") \ V(salt_length_string, "saltLength") \ V(search_string, "search") \ - V(selector_string, "selector") \ - V(serial_string, "serial") \ V(servername_string, "servername") \ - V(service_string, "service") \ V(session_id_string, "sessionId") \ V(set_string, "set") \ V(shell_string, "shell") \ @@ -359,7 +336,6 @@ V(source_url_string, "sourceURL") \ V(specifier_string, "specifier") \ V(stack_string, "stack") \ - V(standard_name_string, "standardName") \ V(start_string, "start") \ V(state_string, "state") \ V(stats_string, "stats") \ @@ -393,7 +369,6 @@ V(value_string, "value") \ V(verify_error_string, "verifyError") \ V(version_string, "version") \ - V(weight_string, "weight") \ V(windows_hide_string, "windowsHide") \ V(windows_verbatim_arguments_string, "windowsVerbatimArguments") \ V(wrap_string, "wrap") \ @@ -402,13 +377,17 @@ V(write_queue_size_string, "writeQueueSize") #define PER_ISOLATE_TEMPLATE_PROPERTIES(V) \ + V(a_record_template, v8::DictionaryTemplate) \ + V(aaaa_record_template, v8::DictionaryTemplate) \ V(async_wrap_ctor_template, v8::FunctionTemplate) \ V(binding_data_default_template, v8::ObjectTemplate) \ V(blob_constructor_template, v8::FunctionTemplate) \ V(blob_reader_constructor_template, v8::FunctionTemplate) \ V(blocklist_constructor_template, v8::FunctionTemplate) \ + V(caa_record_template, v8::DictionaryTemplate) \ V(callsite_template, v8::DictionaryTemplate) \ V(cipherinfo_template, v8::DictionaryTemplate) \ + V(cname_record_template, v8::DictionaryTemplate) \ V(contextify_global_template, v8::ObjectTemplate) \ V(contextify_wrapper_template, v8::ObjectTemplate) \ V(cpu_usage_template, v8::DictionaryTemplate) \ @@ -417,6 +396,7 @@ V(env_proxy_ctor_template, v8::FunctionTemplate) \ V(ephemeral_key_template, v8::DictionaryTemplate) \ V(dir_instance_template, v8::ObjectTemplate) \ + V(dns_ns_record_template, v8::DictionaryTemplate) \ V(fd_constructor_template, v8::ObjectTemplate) \ V(fdclose_constructor_template, v8::ObjectTemplate) \ V(filehandlereadwrap_template, v8::ObjectTemplate) \ @@ -437,21 +417,27 @@ V(lock_holder_constructor_template, v8::FunctionTemplate) \ V(message_port_constructor_template, v8::FunctionTemplate) \ V(module_wrap_constructor_template, v8::FunctionTemplate) \ + V(mx_record_template, v8::DictionaryTemplate) \ + V(naptr_record_template, v8::DictionaryTemplate) \ V(object_stats_template, v8::DictionaryTemplate) \ V(page_stats_template, v8::DictionaryTemplate) \ V(pipe_constructor_template, v8::FunctionTemplate) \ V(script_context_constructor_template, v8::FunctionTemplate) \ V(secure_context_constructor_template, v8::FunctionTemplate) \ V(shutdown_wrap_template, v8::ObjectTemplate) \ + V(soa_record_template, v8::DictionaryTemplate) \ V(socketaddress_constructor_template, v8::FunctionTemplate) \ V(space_stats_template, v8::DictionaryTemplate) \ V(sqlite_column_template, v8::DictionaryTemplate) \ V(sqlite_statement_sync_constructor_template, v8::FunctionTemplate) \ V(sqlite_statement_sync_iterator_constructor_template, v8::FunctionTemplate) \ V(sqlite_session_constructor_template, v8::FunctionTemplate) \ + V(srv_record_template, v8::DictionaryTemplate) \ V(streambaseoutputstream_constructor_template, v8::ObjectTemplate) \ V(tcp_constructor_template, v8::FunctionTemplate) \ + V(tlsa_record_template, v8::DictionaryTemplate) \ V(tty_constructor_template, v8::FunctionTemplate) \ + V(txt_record_template, v8::DictionaryTemplate) \ V(urlpatterncomponentresult_template, v8::DictionaryTemplate) \ V(urlpatterninit_template, v8::DictionaryTemplate) \ V(urlpatternresult_template, v8::DictionaryTemplate) \