%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/quic/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/quic/bindingdata.h |
#pragma once #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC #include <base_object.h> #include <env.h> #include <memory_tracker.h> #include <nghttp3/nghttp3.h> #include <ngtcp2/ngtcp2.h> #include <ngtcp2/ngtcp2_crypto.h> #include <node.h> #include <node_mem.h> #include <v8.h> #include <limits> #include <unordered_map> #include <vector> namespace node { namespace quic { class Endpoint; class Packet; enum class Side { CLIENT, SERVER, }; enum class EndpointLabel { LOCAL, REMOTE, }; enum class Direction { BIDIRECTIONAL, UNIDIRECTIONAL, }; enum class HeadersKind { HINTS, INITIAL, TRAILING, }; enum class HeadersFlags { NONE, TERMINAL, }; enum class StreamPriority { DEFAULT = NGHTTP3_DEFAULT_URGENCY, LOW = NGHTTP3_URGENCY_LOW, HIGH = NGHTTP3_URGENCY_HIGH, }; enum class StreamPriorityFlags { NONE, NON_INCREMENTAL, }; enum class PathValidationResult : uint8_t { SUCCESS = NGTCP2_PATH_VALIDATION_RESULT_SUCCESS, FAILURE = NGTCP2_PATH_VALIDATION_RESULT_FAILURE, ABORTED = NGTCP2_PATH_VALIDATION_RESULT_ABORTED, }; enum class DatagramStatus { ACKNOWLEDGED, LOST, }; constexpr uint64_t NGTCP2_APP_NOERROR = 65280; constexpr size_t kDefaultMaxPacketLength = NGTCP2_MAX_UDP_PAYLOAD_SIZE; constexpr size_t kMaxSizeT = std::numeric_limits<size_t>::max(); constexpr uint64_t kMaxSafeJsInteger = 9007199254740991; constexpr auto kSocketAddressInfoTimeout = 60 * NGTCP2_SECONDS; constexpr size_t kMaxVectorCount = 16; // ============================================================================ // The FunctionTemplates the BindingData will store for us. #define QUIC_CONSTRUCTORS(V) \ V(endpoint) \ V(logstream) \ V(packet) \ V(session) \ V(stream) \ V(udp) // The callbacks are persistent v8::Function references that are set in the // quic::BindingState used to communicate data and events back out to the JS // environment. They are set once from the JavaScript side when the // internalBinding('quic') is first loaded. #define QUIC_JS_CALLBACKS(V) \ V(endpoint_close, EndpointClose) \ V(session_new, SessionNew) \ V(session_close, SessionClose) \ V(session_datagram, SessionDatagram) \ V(session_datagram_status, SessionDatagramStatus) \ V(session_handshake, SessionHandshake) \ V(session_ticket, SessionTicket) \ V(session_version_negotiation, SessionVersionNegotiation) \ V(session_path_validation, SessionPathValidation) \ V(stream_close, StreamClose) \ V(stream_created, StreamCreated) \ V(stream_reset, StreamReset) \ V(stream_headers, StreamHeaders) \ V(stream_blocked, StreamBlocked) \ V(stream_trailers, StreamTrailers) // The various JS strings the implementation uses. #define QUIC_STRINGS(V) \ V(aborted, "aborted") \ V(acknowledged, "acknowledged") \ V(ack_delay_exponent, "ackDelayExponent") \ V(active_connection_id_limit, "activeConnectionIDLimit") \ V(address_lru_size, "addressLRUSize") \ V(alpn, "alpn") \ V(application_options, "application") \ V(bbr, "bbr") \ V(ca, "ca") \ V(certs, "certs") \ V(cc_algorithm, "cc") \ V(crl, "crl") \ V(ciphers, "ciphers") \ V(cubic, "cubic") \ V(disable_active_migration, "disableActiveMigration") \ V(disable_stateless_reset, "disableStatelessReset") \ V(enable_connect_protocol, "enableConnectProtocol") \ V(enable_datagrams, "enableDatagrams") \ V(enable_tls_trace, "tlsTrace") \ V(endpoint, "Endpoint") \ V(endpoint_udp, "Endpoint::UDP") \ V(failure, "failure") \ V(groups, "groups") \ V(handshake_timeout, "handshakeTimeout") \ V(hostname, "hostname") \ V(http3_alpn, &NGHTTP3_ALPN_H3[1]) \ V(initial_max_data, "initialMaxData") \ V(initial_max_stream_data_bidi_local, "initialMaxStreamDataBidiLocal") \ V(initial_max_stream_data_bidi_remote, "initialMaxStreamDataBidiRemote") \ V(initial_max_stream_data_uni, "initialMaxStreamDataUni") \ V(initial_max_streams_bidi, "initialMaxStreamsBidi") \ V(initial_max_streams_uni, "initialMaxStreamsUni") \ V(ipv6_only, "ipv6Only") \ V(keylog, "keylog") \ V(keys, "keys") \ V(logstream, "LogStream") \ V(lost, "lost") \ V(max_ack_delay, "maxAckDelay") \ V(max_connections_per_host, "maxConnectionsPerHost") \ V(max_connections_total, "maxConnectionsTotal") \ V(max_datagram_frame_size, "maxDatagramFrameSize") \ V(max_field_section_size, "maxFieldSectionSize") \ V(max_header_length, "maxHeaderLength") \ V(max_header_pairs, "maxHeaderPairs") \ V(max_idle_timeout, "maxIdleTimeout") \ V(max_payload_size, "maxPayloadSize") \ V(max_retries, "maxRetries") \ V(max_stateless_resets, "maxStatelessResetsPerHost") \ V(max_stream_window, "maxStreamWindow") \ V(max_window, "maxWindow") \ V(min_version, "minVersion") \ V(no_udp_payload_size_shaping, "noUdpPayloadSizeShaping") \ V(packetwrap, "PacketWrap") \ V(preferred_address_strategy, "preferredAddressPolicy") \ V(qlog, "qlog") \ V(qpack_blocked_streams, "qpackBlockedStreams") \ V(qpack_encoder_max_dtable_capacity, "qpackEncoderMaxDTableCapacity") \ V(qpack_max_dtable_capacity, "qpackMaxDTableCapacity") \ V(reject_unauthorized, "rejectUnauthorized") \ V(reno, "reno") \ V(retry_token_expiration, "retryTokenExpiration") \ V(request_peer_certificate, "requestPeerCertificate") \ V(reset_token_secret, "resetTokenSecret") \ V(rx_loss, "rxDiagnosticLoss") \ V(session, "Session") \ V(session_id_ctx, "sessionIDContext") \ V(stream, "Stream") \ V(success, "success") \ V(tls_options, "tls") \ V(token_expiration, "tokenExpiration") \ V(token_secret, "tokenSecret") \ V(transport_params, "transportParams") \ V(tx_loss, "txDiagnosticLoss") \ V(udp_receive_buffer_size, "udpReceiveBufferSize") \ V(udp_send_buffer_size, "udpSendBufferSize") \ V(udp_ttl, "udpTTL") \ V(unacknowledged_packet_threshold, "unacknowledgedPacketThreshold") \ V(validate_address, "validateAddress") \ V(verify_hostname_identity, "verifyHostnameIdentity") \ V(version, "version") // ============================================================================= // The BindingState object holds state for the internalBinding('quic') binding // instance. It is mostly used to hold the persistent constructors, strings, and // callback references used for the rest of the implementation. // // TODO(@jasnell): Make this snapshotable? class BindingData final : public BaseObject, public mem::NgLibMemoryManager<BindingData, ngtcp2_mem> { public: SET_BINDING_ID(quic_binding_data) static void InitPerContext(Realm* realm, v8::Local<v8::Object> target); static void RegisterExternalReferences(ExternalReferenceRegistry* registry); static BindingData& Get(Environment* env); BindingData(Realm* realm, v8::Local<v8::Object> object); void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(BindingData) SET_SELF_SIZE(BindingData) // NgLibMemoryManager operator ngtcp2_mem(); operator nghttp3_mem(); void CheckAllocatedSize(size_t previous_size) const; void IncreaseAllocatedSize(size_t size); void DecreaseAllocatedSize(size_t size); // Installs the set of JavaScript callback functions that are used to // bridge out to the JS API. static void SetCallbacks(const v8::FunctionCallbackInfo<v8::Value>& args); std::vector<Packet*> packet_freelist; std::unordered_map<Endpoint*, BaseObjectPtr<BaseObject>> listening_endpoints; // Purge the packet free list to free up memory. static void FlushPacketFreelist( const v8::FunctionCallbackInfo<v8::Value>& args); bool in_ngtcp2_callback_scope = false; bool in_nghttp3_callback_scope = false; // The following set up various storage and accessors for common strings, // construction templates, and callbacks stored on the BindingData. These // are all defined in defs.h #define V(name) \ void set_##name##_constructor_template( \ v8::Local<v8::FunctionTemplate> tmpl); \ v8::Local<v8::FunctionTemplate> name##_constructor_template() const; QUIC_CONSTRUCTORS(V) #undef V #define V(name, _) \ void set_##name##_callback(v8::Local<v8::Function> fn); \ v8::Local<v8::Function> name##_callback() const; QUIC_JS_CALLBACKS(V) #undef V #define V(name, _) v8::Local<v8::String> name##_string() const; QUIC_STRINGS(V) #undef V #define V(name, _) v8::Local<v8::String> on_##name##_string() const; QUIC_JS_CALLBACKS(V) #undef V size_t current_ngtcp2_memory_ = 0; #define V(name) v8::Global<v8::FunctionTemplate> name##_constructor_template_; QUIC_CONSTRUCTORS(V) #undef V #define V(name, _) v8::Global<v8::Function> name##_callback_; QUIC_JS_CALLBACKS(V) #undef V #define V(name, _) mutable v8::Eternal<v8::String> name##_string_; QUIC_STRINGS(V) #undef V #define V(name, _) mutable v8::Eternal<v8::String> on_##name##_string_; QUIC_JS_CALLBACKS(V) #undef V }; void IllegalConstructor(const v8::FunctionCallbackInfo<v8::Value>& args); // The ngtcp2 and nghttp3 callbacks have certain restrictions // that forbid re-entry. We provide the following scopes for // use in those to help protect against it. struct NgTcp2CallbackScope { Environment* env; explicit NgTcp2CallbackScope(Environment* env); ~NgTcp2CallbackScope(); static bool in_ngtcp2_callback(Environment* env); }; struct NgHttp3CallbackScope { Environment* env; explicit NgHttp3CallbackScope(Environment* env); ~NgHttp3CallbackScope(); static bool in_nghttp3_callback(Environment* env); }; struct CallbackScopeBase { Environment* env; v8::Context::Scope context_scope; v8::TryCatch try_catch; explicit CallbackScopeBase(Environment* env); CallbackScopeBase(const CallbackScopeBase&) = delete; CallbackScopeBase(CallbackScopeBase&&) = delete; CallbackScopeBase& operator=(const CallbackScopeBase&) = delete; CallbackScopeBase& operator=(CallbackScopeBase&&) = delete; ~CallbackScopeBase(); }; // Maintains a strong reference to BaseObject type ptr to keep it alive during // a MakeCallback during which it might be destroyed. template <typename T> struct CallbackScope final : public CallbackScopeBase { BaseObjectPtr<T> ref; explicit CallbackScope(const T* ptr) : CallbackScopeBase(ptr->env()), ref(ptr) {} explicit CallbackScope(T* ptr) : CallbackScopeBase(ptr->env()), ref(ptr) {} }; } // namespace quic } // namespace node #endif // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS