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