| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d3fadd8 commit e8ea834
11 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -341,16 +341,20 @@ | |||
| 341 | 341 | 'src/quic/cid.cc', | |
| 342 | 342 | 'src/quic/data.cc', | |
| 343 | 343 | 'src/quic/logstream.cc', | |
| 344 | + 'src/quic/packet.cc', | ||
| 344 | 345 | 'src/quic/preferredaddress.cc', | |
| 345 | 346 | 'src/quic/sessionticket.cc', | |
| 347 | + 'src/quic/tlscontext.cc', | ||
| 346 | 348 | 'src/quic/tokens.cc', | |
| 347 | 349 | 'src/quic/transportparams.cc', | |
| 348 | 350 | 'src/quic/bindingdata.h', | |
| 349 | 351 | 'src/quic/cid.h', | |
| 350 | 352 | 'src/quic/data.h', | |
| 351 | 353 | 'src/quic/logstream.h', | |
| 354 | + 'src/quic/packet.h', | ||
| 352 | 355 | 'src/quic/preferredaddress.h', | |
| 353 | 356 | 'src/quic/sessionticket.h', | |
| 357 | + 'src/quic/tlscontext.h', | ||
| 354 | 358 | 'src/quic/tokens.h', | |
| 355 | 359 | 'src/quic/transportparams.h', | |
| 356 | 360 | ], | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -61,6 +61,7 @@ namespace node { | |||
| 61 | 61 | V(PROMISE) \ | |
| 62 | 62 | V(QUERYWRAP) \ | |
| 63 | 63 | V(QUIC_LOGSTREAM) \ | |
| 64 | + V(QUIC_PACKET) \ | ||
| 64 | 65 | V(SHUTDOWNWRAP) \ | |
| 65 | 66 | V(SIGNALWRAP) \ | |
| 66 | 67 | V(STATWATCHER) \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -63,6 +63,7 @@ void OOMErrorHandler(const char* location, const v8::OOMDetails& details); | |||
| 63 | 63 | V(ERR_DLOPEN_FAILED, Error) \ | |
| 64 | 64 | V(ERR_ENCODING_INVALID_ENCODED_DATA, TypeError) \ | |
| 65 | 65 | V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE, Error) \ | |
| 66 | + V(ERR_ILLEGAL_CONSTRUCTOR, Error) \ | ||
| 66 | 67 | V(ERR_INVALID_ADDRESS, Error) \ | |
| 67 | 68 | V(ERR_INVALID_ARG_VALUE, TypeError) \ | |
| 68 | 69 | V(ERR_OSSL_EVP_INVALID_DIGEST, Error) \ | |
@@ -156,6 +157,7 @@ ERRORS_WITH_CODE(V) | |||
| 156 | 157 | V(ERR_DLOPEN_FAILED, "DLOpen failed") \ | |
| 157 | 158 | V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE, \ | |
| 158 | 159 | "Context not associated with Node.js environment") \ | |
| 160 | + V(ERR_ILLEGAL_CONSTRUCTOR, "Illegal constructor") \ | ||
| 159 | 161 | V(ERR_INVALID_ADDRESS, "Invalid socket address") \ | |
| 160 | 162 | V(ERR_INVALID_MODULE, "No such module") \ | |
| 161 | 163 | V(ERR_INVALID_STATE, "Invalid state") \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -58,13 +58,15 @@ void BindingData::DecreaseAllocatedSize(size_t size) { | |||
| 58 | 58 | ||
| 59 | 59 | void BindingData::Initialize(Environment* env, Local<Object> target) { | |
| 60 | 60 | SetMethod(env->context(), target, "setCallbacks", SetCallbacks); | |
| 61 | + SetMethod(env->context(), target, "flushPacketFreelist", FlushPacketFreelist); | ||
| 61 | 62 | Realm::GetCurrent(env->context()) | |
| 62 | 63 | ->AddBindingData<BindingData>(env->context(), target); | |
| 63 | 64 | } | |
| 64 | 65 | ||
| 65 | 66 | void BindingData::RegisterExternalReferences( | |
| 66 | 67 | ExternalReferenceRegistry* registry) { | |
| 67 | 68 | registry->Register(SetCallbacks); | |
| 69 | + registry->Register(FlushPacketFreelist); | ||
| 68 | 70 | } | |
| 69 | 71 | ||
| 70 | 72 | BindingData::BindingData(Realm* realm, Local<Object> object) | |
@@ -140,7 +142,7 @@ QUIC_JS_CALLBACKS(V) | |||
| 140 | 142 | void BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) { | |
| 141 | 143 | auto env = Environment::GetCurrent(args); | |
| 142 | 144 | auto isolate = env->isolate(); | |
| 143 | - BindingData& state = BindingData::Get(env); | ||
| 145 | + auto& state = BindingData::Get(env); | ||
| 144 | 146 | CHECK(args[0]->IsObject()); | |
| 145 | 147 | Local<Object> obj = args[0].As<Object>(); | |
| 146 | 148 | ||
@@ -159,6 +161,48 @@ void BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) { | |||
| 159 | 161 | #undef V | |
| 160 | 162 | } | |
| 161 | 163 | ||
| 164 | + void BindingData::FlushPacketFreelist(const FunctionCallbackInfo<Value>& args) { | ||
| 165 | + auto env = Environment::GetCurrent(args); | ||
| 166 | + auto& state = BindingData::Get(env); | ||
| 167 | + state.packet_freelist.clear(); | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + NgTcp2CallbackScope::NgTcp2CallbackScope(Environment* env) : env(env) { | ||
| 171 | + auto& binding = BindingData::Get(env); | ||
| 172 | + CHECK(!binding.in_ngtcp2_callback_scope); | ||
| 173 | + binding.in_ngtcp2_callback_scope = true; | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + NgTcp2CallbackScope::~NgTcp2CallbackScope() { | ||
| 177 | + auto& binding = BindingData::Get(env); | ||
| 178 | + binding.in_ngtcp2_callback_scope = false; | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + bool NgTcp2CallbackScope::in_ngtcp2_callback(Environment* env) { | ||
| 182 | + auto& binding = BindingData::Get(env); | ||
| 183 | + return binding.in_ngtcp2_callback_scope; | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + NgHttp3CallbackScope::NgHttp3CallbackScope(Environment* env) : env(env) { | ||
| 187 | + auto& binding = BindingData::Get(env); | ||
| 188 | + CHECK(!binding.in_nghttp3_callback_scope); | ||
| 189 | + binding.in_nghttp3_callback_scope = true; | ||
| 190 | + } | ||
| 191 | + | ||
| 192 | + NgHttp3CallbackScope::~NgHttp3CallbackScope() { | ||
| 193 | + auto& binding = BindingData::Get(env); | ||
| 194 | + binding.in_nghttp3_callback_scope = false; | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + bool NgHttp3CallbackScope::in_nghttp3_callback(Environment* env) { | ||
| 198 | + auto& binding = BindingData::Get(env); | ||
| 199 | + return binding.in_nghttp3_callback_scope; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + void IllegalConstructor(const FunctionCallbackInfo<Value>& args) { | ||
| 203 | + THROW_ERR_ILLEGAL_CONSTRUCTOR(Environment::GetCurrent(args)); | ||
| 204 | + } | ||
| 205 | + | ||
| 162 | 206 | } // namespace quic | |
| 163 | 207 | } // namespace node | |
| 164 | 208 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,11 +12,13 @@ | |||
| 12 | 12 | #include <node.h> | |
| 13 | 13 | #include <node_mem.h> | |
| 14 | 14 | #include <v8.h> | |
| 15 | + #include <vector> | ||
| 15 | 16 | ||
| 16 | 17 | namespace node { | |
| 17 | 18 | namespace quic { | |
| 18 | 19 | ||
| 19 | 20 | class Endpoint; | |
| 21 | + class Packet; | ||
| 20 | 22 | ||
| 21 | 23 | enum class Side { | |
| 22 | 24 | CLIENT = NGTCP2_CRYPTO_SIDE_CLIENT, | |
@@ -64,23 +66,37 @@ constexpr size_t kDefaultMaxPacketLength = NGTCP2_MAX_UDP_PAYLOAD_SIZE; | |||
| 64 | 66 | #define QUIC_STRINGS(V) \ | |
| 65 | 67 | V(ack_delay_exponent, "ackDelayExponent") \ | |
| 66 | 68 | V(active_connection_id_limit, "activeConnectionIDLimit") \ | |
| 69 | + V(alpn, "alpn") \ | ||
| 70 | + V(ca, "ca") \ | ||
| 71 | + V(certs, "certs") \ | ||
| 72 | + V(crl, "crl") \ | ||
| 73 | + V(ciphers, "ciphers") \ | ||
| 67 | 74 | V(disable_active_migration, "disableActiveMigration") \ | |
| 75 | + V(enable_tls_trace, "tlsTrace") \ | ||
| 68 | 76 | V(endpoint, "Endpoint") \ | |
| 69 | 77 | V(endpoint_udp, "Endpoint::UDP") \ | |
| 78 | + V(groups, "groups") \ | ||
| 79 | + V(hostname, "hostname") \ | ||
| 70 | 80 | V(http3_alpn, &NGHTTP3_ALPN_H3[1]) \ | |
| 71 | 81 | V(initial_max_data, "initialMaxData") \ | |
| 72 | 82 | V(initial_max_stream_data_bidi_local, "initialMaxStreamDataBidiLocal") \ | |
| 73 | 83 | V(initial_max_stream_data_bidi_remote, "initialMaxStreamDataBidiRemote") \ | |
| 74 | 84 | V(initial_max_stream_data_uni, "initialMaxStreamDataUni") \ | |
| 75 | 85 | V(initial_max_streams_bidi, "initialMaxStreamsBidi") \ | |
| 76 | 86 | V(initial_max_streams_uni, "initialMaxStreamsUni") \ | |
| 87 | + V(keylog, "keylog") \ | ||
| 88 | + V(keys, "keys") \ | ||
| 77 | 89 | V(logstream, "LogStream") \ | |
| 78 | 90 | V(max_ack_delay, "maxAckDelay") \ | |
| 79 | 91 | V(max_datagram_frame_size, "maxDatagramFrameSize") \ | |
| 80 | 92 | V(max_idle_timeout, "maxIdleTimeout") \ | |
| 81 | 93 | V(packetwrap, "PacketWrap") \ | |
| 94 | + V(reject_unauthorized, "rejectUnauthorized") \ | ||
| 95 | + V(request_peer_certificate, "requestPeerCertificate") \ | ||
| 82 | 96 | V(session, "Session") \ | |
| 83 | - V(stream, "Stream") | ||
| 97 | + V(session_id_ctx, "sessionIDContext") \ | ||
| 98 | + V(stream, "Stream") \ | ||
| 99 | + V(verify_hostname_identity, "verifyHostnameIdentity") | ||
| 84 | 100 | ||
| 85 | 101 | // ============================================================================= | |
| 86 | 102 | // The BindingState object holds state for the internalBinding('quic') binding | |
@@ -115,12 +131,14 @@ class BindingData final | |||
| 115 | 131 | // bridge out to the JS API. | |
| 116 | 132 | static void SetCallbacks(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 117 | 133 | ||
| 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; | ||
| 134 | + std::vector<BaseObjectPtr<BaseObject>> packet_freelist; | ||
| 135 | + | ||
| 136 | + // Purge the packet free list to free up memory. | ||
| 137 | + static void FlushPacketFreelist( | ||
| 138 | + const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 139 | + | ||
| 140 | + bool in_ngtcp2_callback_scope = false; | ||
| 141 | + bool in_nghttp3_callback_scope = false; | ||
| 124 | 142 | ||
| 125 | 143 | // The following set up various storage and accessors for common strings, | |
| 126 | 144 | // construction templates, and callbacks stored on the BindingData. These | |
@@ -166,6 +184,25 @@ class BindingData final | |||
| 166 | 184 | #undef V | |
| 167 | 185 | }; | |
| 168 | 186 | ||
| 187 | + void IllegalConstructor(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 188 | + | ||
| 189 | + // The ngtcp2 and nghttp3 callbacks have certain restrictions | ||
| 190 | + // that forbid re-entry. We provide the following scopes for | ||
| 191 | + // use in those to help protect against it. | ||
| 192 | + struct NgTcp2CallbackScope { | ||
| 193 | + Environment* env; | ||
| 194 | + explicit NgTcp2CallbackScope(Environment* env); | ||
| 195 | + ~NgTcp2CallbackScope(); | ||
| 196 | + static bool in_ngtcp2_callback(Environment* env); | ||
| 197 | + }; | ||
| 198 | + | ||
| 199 | + struct NgHttp3CallbackScope { | ||
| 200 | + Environment* env; | ||
| 201 | + explicit NgHttp3CallbackScope(Environment* env); | ||
| 202 | + ~NgHttp3CallbackScope(); | ||
| 203 | + static bool in_nghttp3_callback(Environment* env); | ||
| 204 | + }; | ||
| 205 | + | ||
| 169 | 206 | } // namespace quic | |
| 170 | 207 | } // namespace node | |
| 171 | 208 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,12 +1,28 @@ | |||
| 1 | 1 | #pragma once | |
| 2 | 2 | ||
| 3 | + #include <aliased_struct.h> | ||
| 3 | 4 | #include <env.h> | |
| 4 | 5 | #include <node_errors.h> | |
| 6 | + #include <uv.h> | ||
| 5 | 7 | #include <v8.h> | |
| 6 | 8 | ||
| 7 | 9 | namespace node { | |
| 8 | 10 | namespace quic { | |
| 9 | 11 | ||
| 12 | + template <typename Opt, std::string Opt::*member> | ||
| 13 | + bool SetOption(Environment* env, | ||
| 14 | + Opt* options, | ||
| 15 | + const v8::Local<v8::Object>& object, | ||
| 16 | + const v8::Local<v8::String>& name) { | ||
| 17 | + v8::Local<v8::Value> value; | ||
| 18 | + if (!object->Get(env->context(), name).ToLocal(&value)) return false; | ||
| 19 | + if (!value->IsUndefined()) { | ||
| 20 | + Utf8Value utf8(env->isolate(), value); | ||
| 21 | + options->*member = *utf8; | ||
| 22 | + } | ||
| 23 | + return true; | ||
| 24 | + } | ||
| 25 | + | ||
| 10 | 26 | template <typename Opt, bool Opt::*member> | |
| 11 | 27 | bool SetOption(Environment* env, | |
| 12 | 28 | Opt* options, | |
@@ -50,5 +66,37 @@ bool SetOption(Environment* env, | |||
| 50 | 66 | return true; | |
| 51 | 67 | } | |
| 52 | 68 | ||
| 69 | + // Utilities used to update the stats for Endpoint, Session, and Stream | ||
| 70 | + // objects. The stats themselves are maintained in an AliasedStruct within | ||
| 71 | + // each of the relevant classes. | ||
| 72 | + | ||
| 73 | + template <typename Stats, uint64_t Stats::*member> | ||
| 74 | + void IncrementStat(Stats* stats, uint64_t amt = 1) { | ||
| 75 | + stats->*member += amt; | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + template <typename Stats, uint64_t Stats::*member> | ||
| 79 | + void RecordTimestampStat(Stats* stats) { | ||
| 80 | + stats->*member = uv_hrtime(); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + template <typename Stats, uint64_t Stats::*member> | ||
| 84 | + void SetStat(Stats* stats, uint64_t val) { | ||
| 85 | + stats->*member = val; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + template <typename Stats, uint64_t Stats::*member> | ||
| 89 | + uint64_t GetStat(Stats* stats) { | ||
| 90 | + return stats->*member; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + #define STAT_INCREMENT(Type, name) IncrementStat<Type, &Type::name>(&stats_); | ||
| 94 | + #define STAT_INCREMENT_N(Type, name, amt) \ | ||
| 95 | + IncrementStat<Type, &Type::name>(&stats_, amt); | ||
| 96 | + #define STAT_RECORD_TIMESTAMP(Type, name) \ | ||
| 97 | + RecordTimestampStat<Type, &Type::name>(&stats_); | ||
| 98 | + #define STAT_SET(Type, name, val) SetStat<Type, &Type::name>(&stats_, val); | ||
| 99 | + #define STAT_GET(Type, name) GetStat<Type, &Type::name>(&stats_); | ||
| 100 | + | ||
| 53 | 101 | } // namespace quic | |
| 54 | 102 | } // namespace node | |
| Back | FazBrowse Home | New Git URL |
0 commit comments