xref: /third_party/node/src/quic/bindingdata.cc (revision 1cb0ef41)
11cb0ef41Sopenharmony_ci#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
21cb0ef41Sopenharmony_ci#include "bindingdata.h"
31cb0ef41Sopenharmony_ci#include <base_object-inl.h>
41cb0ef41Sopenharmony_ci#include <env-inl.h>
51cb0ef41Sopenharmony_ci#include <memory_tracker-inl.h>
61cb0ef41Sopenharmony_ci#include <nghttp3/nghttp3.h>
71cb0ef41Sopenharmony_ci#include <ngtcp2/ngtcp2.h>
81cb0ef41Sopenharmony_ci#include <node.h>
91cb0ef41Sopenharmony_ci#include <node_errors.h>
101cb0ef41Sopenharmony_ci#include <node_external_reference.h>
111cb0ef41Sopenharmony_ci#include <node_mem-inl.h>
121cb0ef41Sopenharmony_ci#include <node_realm-inl.h>
131cb0ef41Sopenharmony_ci#include <v8.h>
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cinamespace node {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciusing v8::Function;
181cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo;
191cb0ef41Sopenharmony_ciusing v8::FunctionTemplate;
201cb0ef41Sopenharmony_ciusing v8::Local;
211cb0ef41Sopenharmony_ciusing v8::Object;
221cb0ef41Sopenharmony_ciusing v8::String;
231cb0ef41Sopenharmony_ciusing v8::Value;
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_cinamespace quic {
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciBindingData& BindingData::Get(Environment* env) {
281cb0ef41Sopenharmony_ci  return *Realm::GetBindingData<BindingData>(env->context());
291cb0ef41Sopenharmony_ci}
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ciBindingData::operator ngtcp2_mem() {
321cb0ef41Sopenharmony_ci  return MakeAllocator();
331cb0ef41Sopenharmony_ci}
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ciBindingData::operator nghttp3_mem() {
361cb0ef41Sopenharmony_ci  ngtcp2_mem allocator = *this;
371cb0ef41Sopenharmony_ci  nghttp3_mem http3_allocator = {
381cb0ef41Sopenharmony_ci      allocator.user_data,
391cb0ef41Sopenharmony_ci      allocator.malloc,
401cb0ef41Sopenharmony_ci      allocator.free,
411cb0ef41Sopenharmony_ci      allocator.calloc,
421cb0ef41Sopenharmony_ci      allocator.realloc,
431cb0ef41Sopenharmony_ci  };
441cb0ef41Sopenharmony_ci  return http3_allocator;
451cb0ef41Sopenharmony_ci}
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_civoid BindingData::CheckAllocatedSize(size_t previous_size) const {
481cb0ef41Sopenharmony_ci  CHECK_GE(current_ngtcp2_memory_, previous_size);
491cb0ef41Sopenharmony_ci}
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_civoid BindingData::IncreaseAllocatedSize(size_t size) {
521cb0ef41Sopenharmony_ci  current_ngtcp2_memory_ += size;
531cb0ef41Sopenharmony_ci}
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_civoid BindingData::DecreaseAllocatedSize(size_t size) {
561cb0ef41Sopenharmony_ci  current_ngtcp2_memory_ -= size;
571cb0ef41Sopenharmony_ci}
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_civoid BindingData::Initialize(Environment* env, Local<Object> target) {
601cb0ef41Sopenharmony_ci  SetMethod(env->context(), target, "setCallbacks", SetCallbacks);
611cb0ef41Sopenharmony_ci  SetMethod(env->context(), target, "flushPacketFreelist", FlushPacketFreelist);
621cb0ef41Sopenharmony_ci  Realm::GetCurrent(env->context())
631cb0ef41Sopenharmony_ci      ->AddBindingData<BindingData>(env->context(), target);
641cb0ef41Sopenharmony_ci}
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_civoid BindingData::RegisterExternalReferences(
671cb0ef41Sopenharmony_ci    ExternalReferenceRegistry* registry) {
681cb0ef41Sopenharmony_ci  registry->Register(SetCallbacks);
691cb0ef41Sopenharmony_ci  registry->Register(FlushPacketFreelist);
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciBindingData::BindingData(Realm* realm, Local<Object> object)
731cb0ef41Sopenharmony_ci    : BaseObject(realm, object) {
741cb0ef41Sopenharmony_ci  MakeWeak();
751cb0ef41Sopenharmony_ci}
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_civoid BindingData::MemoryInfo(MemoryTracker* tracker) const {
781cb0ef41Sopenharmony_ci#define V(name, _) tracker->TrackField(#name, name##_callback());
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  QUIC_JS_CALLBACKS(V)
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci#undef V
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci#define V(name, _) tracker->TrackField(#name, name##_string());
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  QUIC_STRINGS(V)
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci#undef V
891cb0ef41Sopenharmony_ci}
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci#define V(name)                                                                \
921cb0ef41Sopenharmony_ci  void BindingData::set_##name##_constructor_template(                         \
931cb0ef41Sopenharmony_ci      Local<FunctionTemplate> tmpl) {                                          \
941cb0ef41Sopenharmony_ci    name##_constructor_template_.Reset(env()->isolate(), tmpl);                \
951cb0ef41Sopenharmony_ci  }                                                                            \
961cb0ef41Sopenharmony_ci  Local<FunctionTemplate> BindingData::name##_constructor_template() const {   \
971cb0ef41Sopenharmony_ci    return PersistentToLocal::Default(env()->isolate(),                        \
981cb0ef41Sopenharmony_ci                                      name##_constructor_template_);           \
991cb0ef41Sopenharmony_ci  }
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ciQUIC_CONSTRUCTORS(V)
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci#undef V
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci#define V(name, _)                                                             \
1061cb0ef41Sopenharmony_ci  void BindingData::set_##name##_callback(Local<Function> fn) {                \
1071cb0ef41Sopenharmony_ci    name##_callback_.Reset(env()->isolate(), fn);                              \
1081cb0ef41Sopenharmony_ci  }                                                                            \
1091cb0ef41Sopenharmony_ci  Local<Function> BindingData::name##_callback() const {                       \
1101cb0ef41Sopenharmony_ci    return PersistentToLocal::Default(env()->isolate(), name##_callback_);     \
1111cb0ef41Sopenharmony_ci  }
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ciQUIC_JS_CALLBACKS(V)
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci#undef V
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci#define V(name, value)                                                         \
1181cb0ef41Sopenharmony_ci  Local<String> BindingData::name##_string() const {                           \
1191cb0ef41Sopenharmony_ci    if (name##_string_.IsEmpty())                                              \
1201cb0ef41Sopenharmony_ci      name##_string_.Set(env()->isolate(),                                     \
1211cb0ef41Sopenharmony_ci                         OneByteString(env()->isolate(), value));              \
1221cb0ef41Sopenharmony_ci    return name##_string_.Get(env()->isolate());                               \
1231cb0ef41Sopenharmony_ci  }
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ciQUIC_STRINGS(V)
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci#undef V
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci#define V(name, value)                                                         \
1301cb0ef41Sopenharmony_ci  Local<String> BindingData::on_##name##_string() const {                      \
1311cb0ef41Sopenharmony_ci    if (on_##name##_string_.IsEmpty())                                         \
1321cb0ef41Sopenharmony_ci      on_##name##_string_.Set(                                                 \
1331cb0ef41Sopenharmony_ci          env()->isolate(),                                                    \
1341cb0ef41Sopenharmony_ci          FIXED_ONE_BYTE_STRING(env()->isolate(), "on" #value));               \
1351cb0ef41Sopenharmony_ci    return on_##name##_string_.Get(env()->isolate());                          \
1361cb0ef41Sopenharmony_ci  }
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ciQUIC_JS_CALLBACKS(V)
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci#undef V
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_civoid BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) {
1431cb0ef41Sopenharmony_ci  auto env = Environment::GetCurrent(args);
1441cb0ef41Sopenharmony_ci  auto isolate = env->isolate();
1451cb0ef41Sopenharmony_ci  auto& state = BindingData::Get(env);
1461cb0ef41Sopenharmony_ci  CHECK(args[0]->IsObject());
1471cb0ef41Sopenharmony_ci  Local<Object> obj = args[0].As<Object>();
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci#define V(name, key)                                                           \
1501cb0ef41Sopenharmony_ci  do {                                                                         \
1511cb0ef41Sopenharmony_ci    Local<Value> val;                                                          \
1521cb0ef41Sopenharmony_ci    if (!obj->Get(env->context(), state.on_##name##_string()).ToLocal(&val) || \
1531cb0ef41Sopenharmony_ci        !val->IsFunction()) {                                                  \
1541cb0ef41Sopenharmony_ci      return THROW_ERR_MISSING_ARGS(isolate, "Missing Callback: on" #key);     \
1551cb0ef41Sopenharmony_ci    }                                                                          \
1561cb0ef41Sopenharmony_ci    state.set_##name##_callback(val.As<Function>());                           \
1571cb0ef41Sopenharmony_ci  } while (0);
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci  QUIC_JS_CALLBACKS(V)
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci#undef V
1621cb0ef41Sopenharmony_ci}
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_civoid BindingData::FlushPacketFreelist(const FunctionCallbackInfo<Value>& args) {
1651cb0ef41Sopenharmony_ci  auto env = Environment::GetCurrent(args);
1661cb0ef41Sopenharmony_ci  auto& state = BindingData::Get(env);
1671cb0ef41Sopenharmony_ci  state.packet_freelist.clear();
1681cb0ef41Sopenharmony_ci}
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ciNgTcp2CallbackScope::NgTcp2CallbackScope(Environment* env) : env(env) {
1711cb0ef41Sopenharmony_ci  auto& binding = BindingData::Get(env);
1721cb0ef41Sopenharmony_ci  CHECK(!binding.in_ngtcp2_callback_scope);
1731cb0ef41Sopenharmony_ci  binding.in_ngtcp2_callback_scope = true;
1741cb0ef41Sopenharmony_ci}
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ciNgTcp2CallbackScope::~NgTcp2CallbackScope() {
1771cb0ef41Sopenharmony_ci  auto& binding = BindingData::Get(env);
1781cb0ef41Sopenharmony_ci  binding.in_ngtcp2_callback_scope = false;
1791cb0ef41Sopenharmony_ci}
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_cibool NgTcp2CallbackScope::in_ngtcp2_callback(Environment* env) {
1821cb0ef41Sopenharmony_ci  auto& binding = BindingData::Get(env);
1831cb0ef41Sopenharmony_ci  return binding.in_ngtcp2_callback_scope;
1841cb0ef41Sopenharmony_ci}
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ciNgHttp3CallbackScope::NgHttp3CallbackScope(Environment* env) : env(env) {
1871cb0ef41Sopenharmony_ci  auto& binding = BindingData::Get(env);
1881cb0ef41Sopenharmony_ci  CHECK(!binding.in_nghttp3_callback_scope);
1891cb0ef41Sopenharmony_ci  binding.in_nghttp3_callback_scope = true;
1901cb0ef41Sopenharmony_ci}
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ciNgHttp3CallbackScope::~NgHttp3CallbackScope() {
1931cb0ef41Sopenharmony_ci  auto& binding = BindingData::Get(env);
1941cb0ef41Sopenharmony_ci  binding.in_nghttp3_callback_scope = false;
1951cb0ef41Sopenharmony_ci}
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_cibool NgHttp3CallbackScope::in_nghttp3_callback(Environment* env) {
1981cb0ef41Sopenharmony_ci  auto& binding = BindingData::Get(env);
1991cb0ef41Sopenharmony_ci  return binding.in_nghttp3_callback_scope;
2001cb0ef41Sopenharmony_ci}
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_civoid IllegalConstructor(const FunctionCallbackInfo<Value>& args) {
2031cb0ef41Sopenharmony_ci  THROW_ERR_ILLEGAL_CONSTRUCTOR(Environment::GetCurrent(args));
2041cb0ef41Sopenharmony_ci}
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci}  // namespace quic
2071cb0ef41Sopenharmony_ci}  // namespace node
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ci#endif  // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
210