| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -337,16 +337,22 @@ | |||
| 337 | 337 | 'src/node_crypto.h', | |
| 338 | 338 | ], | |
| 339 | 339 | 'node_quic_sources': [ | |
| 340 | + 'src/quic/bindingdata.cc', | ||
| 340 | 341 | 'src/quic/cid.cc', | |
| 341 | 342 | 'src/quic/data.cc', | |
| 343 | + 'src/quic/logstream.cc', | ||
| 342 | 344 | 'src/quic/preferredaddress.cc', | |
| 343 | 345 | 'src/quic/sessionticket.cc', | |
| 344 | 346 | 'src/quic/tokens.cc', | |
| 347 | + 'src/quic/transportparams.cc', | ||
| 348 | + 'src/quic/bindingdata.h', | ||
| 345 | 349 | 'src/quic/cid.h', | |
| 346 | 350 | 'src/quic/data.h', | |
| 351 | + 'src/quic/logstream.h', | ||
| 347 | 352 | 'src/quic/preferredaddress.h', | |
| 348 | 353 | 'src/quic/sessionticket.h', | |
| 349 | 354 | 'src/quic/tokens.h', | |
| 355 | + 'src/quic/transportparams.h', | ||
| 350 | 356 | ], | |
| 351 | 357 | 'node_mksnapshot_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)node_mksnapshot<(EXECUTABLE_SUFFIX)', | |
| 352 | 358 | 'conditions': [ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -60,6 +60,7 @@ namespace node { | |||
| 60 | 60 | V(PROCESSWRAP) \ | |
| 61 | 61 | V(PROMISE) \ | |
| 62 | 62 | V(QUERYWRAP) \ | |
| 63 | + V(QUIC_LOGSTREAM) \ | ||
| 63 | 64 | V(SHUTDOWNWRAP) \ | |
| 64 | 65 | V(SIGNALWRAP) \ | |
| 65 | 66 | V(STATWATCHER) \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,7 +20,8 @@ namespace node { | |||
| 20 | 20 | ||
| 21 | 21 | #define UNSERIALIZABLE_BINDING_TYPES(V) \ | |
| 22 | 22 | V(http2_binding_data, http2::BindingData) \ | |
| 23 | - V(http_parser_binding_data, http_parser::BindingData) | ||
| 23 | + V(http_parser_binding_data, http_parser::BindingData) \ | ||
| 24 | + V(quic_binding_data, quic::BindingData) | ||
| 24 | 25 | ||
| 25 | 26 | // List of (non-binding) BaseObjects that are serializable in the snapshot. | |
| 26 | 27 | // The first argument should match what the type passes to | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,165 @@ | |||
| 1 | + #if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC | ||
| 2 | + #include "bindingdata.h" | ||
| 3 | + #include <base_object-inl.h> | ||
| 4 | + #include <env-inl.h> | ||
| 5 | + #include <memory_tracker-inl.h> | ||
| 6 | + #include <nghttp3/nghttp3.h> | ||
| 7 | + #include <ngtcp2/ngtcp2.h> | ||
| 8 | + #include <node.h> | ||
| 9 | + #include <node_errors.h> | ||
| 10 | + #include <node_external_reference.h> | ||
| 11 | + #include <node_mem-inl.h> | ||
| 12 | + #include <node_realm-inl.h> | ||
| 13 | + #include <v8.h> | ||
| 14 | + | ||
| 15 | + namespace node { | ||
| 16 | + | ||
| 17 | + using v8::Function; | ||
| 18 | + using v8::FunctionCallbackInfo; | ||
| 19 | + using v8::FunctionTemplate; | ||
| 20 | + using v8::Local; | ||
| 21 | + using v8::Object; | ||
| 22 | + using v8::String; | ||
| 23 | + using v8::Value; | ||
| 24 | + | ||
| 25 | + namespace quic { | ||
| 26 | + | ||
| 27 | + BindingData& BindingData::Get(Environment* env) { | ||
| 28 | + return *Realm::GetBindingData<BindingData>(env->context()); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + BindingData::operator ngtcp2_mem() { | ||
| 32 | + return MakeAllocator(); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + BindingData::operator nghttp3_mem() { | ||
| 36 | + ngtcp2_mem allocator = *this; | ||
| 37 | + nghttp3_mem http3_allocator = { | ||
| 38 | + allocator.user_data, | ||
| 39 | + allocator.malloc, | ||
| 40 | + allocator.free, | ||
| 41 | + allocator.calloc, | ||
| 42 | + allocator.realloc, | ||
| 43 | + }; | ||
| 44 | + return http3_allocator; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + void BindingData::CheckAllocatedSize(size_t previous_size) const { | ||
| 48 | + CHECK_GE(current_ngtcp2_memory_, previous_size); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + void BindingData::IncreaseAllocatedSize(size_t size) { | ||
| 52 | + current_ngtcp2_memory_ += size; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + void BindingData::DecreaseAllocatedSize(size_t size) { | ||
| 56 | + current_ngtcp2_memory_ -= size; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + void BindingData::Initialize(Environment* env, Local<Object> target) { | ||
| 60 | + SetMethod(env->context(), target, "setCallbacks", SetCallbacks); | ||
| 61 | + Realm::GetCurrent(env->context()) | ||
| 62 | + ->AddBindingData<BindingData>(env->context(), target); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + void BindingData::RegisterExternalReferences( | ||
| 66 | + ExternalReferenceRegistry* registry) { | ||
| 67 | + registry->Register(SetCallbacks); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + BindingData::BindingData(Realm* realm, Local<Object> object) | ||
| 71 | + : BaseObject(realm, object) { | ||
| 72 | + MakeWeak(); | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + void BindingData::MemoryInfo(MemoryTracker* tracker) const { | ||
| 76 | + #define V(name, _) tracker->TrackField(#name, name##_callback()); | ||
| 77 | + | ||
| 78 | + QUIC_JS_CALLBACKS(V) | ||
| 79 | + | ||
| 80 | + #undef V | ||
| 81 | + | ||
| 82 | + #define V(name, _) tracker->TrackField(#name, name##_string()); | ||
| 83 | + | ||
| 84 | + QUIC_STRINGS(V) | ||
| 85 | + | ||
| 86 | + #undef V | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + #define V(name) \ | ||
| 90 | + void BindingData::set_##name##_constructor_template( \ | ||
| 91 | + Local<FunctionTemplate> tmpl) { \ | ||
| 92 | + name##_constructor_template_.Reset(env()->isolate(), tmpl); \ | ||
| 93 | + } \ | ||
| 94 | + Local<FunctionTemplate> BindingData::name##_constructor_template() const { \ | ||
| 95 | + return PersistentToLocal::Default(env()->isolate(), \ | ||
| 96 | + name##_constructor_template_); \ | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + QUIC_CONSTRUCTORS(V) | ||
| 100 | + | ||
| 101 | + #undef V | ||
| 102 | + | ||
| 103 | + #define V(name, _) \ | ||
| 104 | + void BindingData::set_##name##_callback(Local<Function> fn) { \ | ||
| 105 | + name##_callback_.Reset(env()->isolate(), fn); \ | ||
| 106 | + } \ | ||
| 107 | + Local<Function> BindingData::name##_callback() const { \ | ||
| 108 | + return PersistentToLocal::Default(env()->isolate(), name##_callback_); \ | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + QUIC_JS_CALLBACKS(V) | ||
| 112 | + | ||
| 113 | + #undef V | ||
| 114 | + | ||
| 115 | + #define V(name, value) \ | ||
| 116 | + Local<String> BindingData::name##_string() const { \ | ||
| 117 | + if (name##_string_.IsEmpty()) \ | ||
| 118 | + name##_string_.Set(env()->isolate(), \ | ||
| 119 | + OneByteString(env()->isolate(), value)); \ | ||
| 120 | + return name##_string_.Get(env()->isolate()); \ | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + QUIC_STRINGS(V) | ||
| 124 | + | ||
| 125 | + #undef V | ||
| 126 | + | ||
| 127 | + #define V(name, value) \ | ||
| 128 | + Local<String> BindingData::on_##name##_string() const { \ | ||
| 129 | + if (on_##name##_string_.IsEmpty()) \ | ||
| 130 | + on_##name##_string_.Set( \ | ||
| 131 | + env()->isolate(), \ | ||
| 132 | + FIXED_ONE_BYTE_STRING(env()->isolate(), "on" #value)); \ | ||
| 133 | + return on_##name##_string_.Get(env()->isolate()); \ | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + QUIC_JS_CALLBACKS(V) | ||
| 137 | + | ||
| 138 | + #undef V | ||
| 139 | + | ||
| 140 | + void BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) { | ||
| 141 | + auto env = Environment::GetCurrent(args); | ||
| 142 | + auto isolate = env->isolate(); | ||
| 143 | + BindingData& state = BindingData::Get(env); | ||
| 144 | + CHECK(args[0]->IsObject()); | ||
| 145 | + Local<Object> obj = args[0].As<Object>(); | ||
| 146 | + | ||
| 147 | + #define V(name, key) \ | ||
| 148 | + do { \ | ||
| 149 | + Local<Value> val; \ | ||
| 150 | + if (!obj->Get(env->context(), state.on_##name##_string()).ToLocal(&val) || \ | ||
| 151 | + !val->IsFunction()) { \ | ||
| 152 | + return THROW_ERR_MISSING_ARGS(isolate, "Missing Callback: on" #key); \ | ||
| 153 | + } \ | ||
| 154 | + state.set_##name##_callback(val.As<Function>()); \ | ||
| 155 | + } while (0); | ||
| 156 | + | ||
| 157 | + QUIC_JS_CALLBACKS(V) | ||
| 158 | + | ||
| 159 | + #undef V | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + } // namespace quic | ||
| 163 | + } // namespace node | ||
| 164 | + | ||
| 165 | + #endif // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,173 @@ | |||
| 1 | + #pragma once | ||
| 2 | + | ||
| 3 | + #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
| 4 | + #if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC | ||
| 5 | + | ||
| 6 | + #include <base_object.h> | ||
| 7 | + #include <env.h> | ||
| 8 | + #include <memory_tracker.h> | ||
| 9 | + #include <nghttp3/nghttp3.h> | ||
| 10 | + #include <ngtcp2/ngtcp2.h> | ||
| 11 | + #include <ngtcp2/ngtcp2_crypto.h> | ||
| 12 | + #include <node.h> | ||
| 13 | + #include <node_mem.h> | ||
| 14 | + #include <v8.h> | ||
| 15 | + | ||
| 16 | + namespace node { | ||
| 17 | + namespace quic { | ||
| 18 | + | ||
| 19 | + class Endpoint; | ||
| 20 | + | ||
| 21 | + enum class Side { | ||
| 22 | + CLIENT = NGTCP2_CRYPTO_SIDE_CLIENT, | ||
| 23 | + SERVER = NGTCP2_CRYPTO_SIDE_SERVER, | ||
| 24 | + }; | ||
| 25 | + | ||
| 26 | + constexpr size_t kDefaultMaxPacketLength = NGTCP2_MAX_UDP_PAYLOAD_SIZE; | ||
| 27 | + | ||
| 28 | + // ============================================================================ | ||
| 29 | + | ||
| 30 | + // The FunctionTemplates the BindingData will store for us. | ||
| 31 | + #define QUIC_CONSTRUCTORS(V) \ | ||
| 32 | + V(endpoint) \ | ||
| 33 | + V(logstream) \ | ||
| 34 | + V(packet) \ | ||
| 35 | + V(session) \ | ||
| 36 | + V(stream) \ | ||
| 37 | + V(udp) | ||
| 38 | + | ||
| 39 | + // The callbacks are persistent v8::Function references that are set in the | ||
| 40 | + // quic::BindingState used to communicate data and events back out to the JS | ||
| 41 | + // environment. They are set once from the JavaScript side when the | ||
| 42 | + // internalBinding('quic') is first loaded. | ||
| 43 | + #define QUIC_JS_CALLBACKS(V) \ | ||
| 44 | + V(endpoint_close, EndpointClose) \ | ||
| 45 | + V(endpoint_error, EndpointError) \ | ||
| 46 | + V(session_new, SessionNew) \ | ||
| 47 | + V(session_close, SessionClose) \ | ||
| 48 | + V(session_error, SessionError) \ | ||
| 49 | + V(session_datagram, SessionDatagram) \ | ||
| 50 | + V(session_datagram_status, SessionDatagramStatus) \ | ||
| 51 | + V(session_handshake, SessionHandshake) \ | ||
| 52 | + V(session_ticket, SessionTicket) \ | ||
| 53 | + V(session_version_negotiation, SessionVersionNegotiation) \ | ||
| 54 | + V(session_path_validation, SessionPathValidation) \ | ||
| 55 | + V(stream_close, StreamClose) \ | ||
| 56 | + V(stream_error, StreamError) \ | ||
| 57 | + V(stream_created, StreamCreated) \ | ||
| 58 | + V(stream_reset, StreamReset) \ | ||
| 59 | + V(stream_headers, StreamHeaders) \ | ||
| 60 | + V(stream_blocked, StreamBlocked) \ | ||
| 61 | + V(stream_trailers, StreamTrailers) | ||
| 62 | + | ||
| 63 | + // The various JS strings the implementation uses. | ||
| 64 | + #define QUIC_STRINGS(V) \ | ||
| 65 | + V(ack_delay_exponent, "ackDelayExponent") \ | ||
| 66 | + V(active_connection_id_limit, "activeConnectionIDLimit") \ | ||
| 67 | + V(disable_active_migration, "disableActiveMigration") \ | ||
| 68 | + V(endpoint, "Endpoint") \ | ||
| 69 | + V(endpoint_udp, "Endpoint::UDP") \ | ||
| 70 | + V(http3_alpn, &NGHTTP3_ALPN_H3[1]) \ | ||
| 71 | + V(initial_max_data, "initialMaxData") \ | ||
| 72 | + V(initial_max_stream_data_bidi_local, "initialMaxStreamDataBidiLocal") \ | ||
| 73 | + V(initial_max_stream_data_bidi_remote, "initialMaxStreamDataBidiRemote") \ | ||
| 74 | + V(initial_max_stream_data_uni, "initialMaxStreamDataUni") \ | ||
| 75 | + V(initial_max_streams_bidi, "initialMaxStreamsBidi") \ | ||
| 76 | + V(initial_max_streams_uni, "initialMaxStreamsUni") \ | ||
| 77 | + V(logstream, "LogStream") \ | ||
| 78 | + V(max_ack_delay, "maxAckDelay") \ | ||
| 79 | + V(max_datagram_frame_size, "maxDatagramFrameSize") \ | ||
| 80 | + V(max_idle_timeout, "maxIdleTimeout") \ | ||
| 81 | + V(packetwrap, "PacketWrap") \ | ||
| 82 | + V(session, "Session") \ | ||
| 83 | + V(stream, "Stream") | ||
| 84 | + | ||
| 85 | + // ============================================================================= | ||
| 86 | + // The BindingState object holds state for the internalBinding('quic') binding | ||
| 87 | + // instance. It is mostly used to hold the persistent constructors, strings, and | ||
| 88 | + // callback references used for the rest of the implementation. | ||
| 89 | + // | ||
| 90 | + // TODO(@jasnell): Make this snapshotable? | ||
| 91 | + class BindingData final | ||
| 92 | + : public BaseObject, | ||
| 93 | + public mem::NgLibMemoryManager<BindingData, ngtcp2_mem> { | ||
| 94 | + public: | ||
| 95 | + SET_BINDING_ID(quic_binding_data) | ||
| 96 | + static void Initialize(Environment* env, v8::Local<v8::Object> target); | ||
| 97 | + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); | ||
| 98 | + | ||
| 99 | + static BindingData& Get(Environment* env); | ||
| 100 | + | ||
| 101 | + BindingData(Realm* realm, v8::Local<v8::Object> object); | ||
| 102 | + | ||
| 103 | + void MemoryInfo(MemoryTracker* tracker) const override; | ||
| 104 | + SET_MEMORY_INFO_NAME(BindingData) | ||
| 105 | + SET_SELF_SIZE(BindingData) | ||
| 106 | + | ||
| 107 | + // NgLibMemoryManager | ||
| 108 | + operator ngtcp2_mem(); | ||
| 109 | + operator nghttp3_mem(); | ||
| 110 | + void CheckAllocatedSize(size_t previous_size) const; | ||
| 111 | + void IncreaseAllocatedSize(size_t size); | ||
| 112 | + void DecreaseAllocatedSize(size_t size); | ||
| 113 | + | ||
| 114 | + // Installs the set of JavaScript callback functions that are used to | ||
| 115 | + // bridge out to the JS API. | ||
| 116 | + static void SetCallbacks(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 117 | + | ||
| 118 | + // TODO(@jasnell) This will be added when Endpoint is implemented. | ||
| 119 | + // // A set of listening Endpoints. We maintain this to ensure that the | ||
| 120 | + // Endpoint | ||
| 121 | + // // cannot be gc'd while it is still listening and there are active | ||
| 122 | + // // connections. | ||
| 123 | + // std::unordered_map<Endpoint*, BaseObjectPtr<Endpoint>> listening_endpoints; | ||
| 124 | + | ||
| 125 | + // The following set up various storage and accessors for common strings, | ||
| 126 | + // construction templates, and callbacks stored on the BindingData. These | ||
| 127 | + // are all defined in defs.h | ||
| 128 | + | ||
| 129 | + #define V(name) \ | ||
| 130 | + void set_##name##_constructor_template( \ | ||
| 131 | + v8::Local<v8::FunctionTemplate> tmpl); \ | ||
| 132 | + v8::Local<v8::FunctionTemplate> name##_constructor_template() const; | ||
| 133 | + QUIC_CONSTRUCTORS(V) | ||
| 134 | + #undef V | ||
| 135 | + | ||
| 136 | + #define V(name, _) \ | ||
| 137 | + void set_##name##_callback(v8::Local<v8::Function> fn); \ | ||
| 138 | + v8::Local<v8::Function> name##_callback() const; | ||
| 139 | + QUIC_JS_CALLBACKS(V) | ||
| 140 | + #undef V | ||
| 141 | + | ||
| 142 | + #define V(name, _) v8::Local<v8::String> name##_string() const; | ||
| 143 | + QUIC_STRINGS(V) | ||
| 144 | + #undef V | ||
| 145 | + | ||
| 146 | + #define V(name, _) v8::Local<v8::String> on_##name##_string() const; | ||
| 147 | + QUIC_JS_CALLBACKS(V) | ||
| 148 | + #undef V | ||
| 149 | + | ||
| 150 | + size_t current_ngtcp2_memory_ = 0; | ||
| 151 | + | ||
| 152 | + #define V(name) v8::Global<v8::FunctionTemplate> name##_constructor_template_; | ||
| 153 | + QUIC_CONSTRUCTORS(V) | ||
| 154 | + #undef V | ||
| 155 | + | ||
| 156 | + #define V(name, _) v8::Global<v8::Function> name##_callback_; | ||
| 157 | + QUIC_JS_CALLBACKS(V) | ||
| 158 | + #undef V | ||
| 159 | + | ||
| 160 | + #define V(name, _) mutable v8::Eternal<v8::String> name##_string_; | ||
| 161 | + QUIC_STRINGS(V) | ||
| 162 | + #undef V | ||
| 163 | + | ||
| 164 | + #define V(name, _) mutable v8::Eternal<v8::String> on_##name##_string_; | ||
| 165 | + QUIC_JS_CALLBACKS(V) | ||
| 166 | + #undef V | ||
| 167 | + }; | ||
| 168 | + | ||
| 169 | + } // namespace quic | ||
| 170 | + } // namespace node | ||
| 171 | + | ||
| 172 | + #endif // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC | ||
| 173 | + #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments