11cb0ef41Sopenharmony_ci#pragma once 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 41cb0ef41Sopenharmony_ci#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci#include <base_object.h> 71cb0ef41Sopenharmony_ci#include <env.h> 81cb0ef41Sopenharmony_ci#include <ngtcp2/ngtcp2.h> 91cb0ef41Sopenharmony_ci#include <node_external_reference.h> 101cb0ef41Sopenharmony_ci#include <node_sockaddr.h> 111cb0ef41Sopenharmony_ci#include <req_wrap.h> 121cb0ef41Sopenharmony_ci#include <uv.h> 131cb0ef41Sopenharmony_ci#include <v8.h> 141cb0ef41Sopenharmony_ci#include <string> 151cb0ef41Sopenharmony_ci#include "bindingdata.h" 161cb0ef41Sopenharmony_ci#include "cid.h" 171cb0ef41Sopenharmony_ci#include "data.h" 181cb0ef41Sopenharmony_ci#include "tokens.h" 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_cinamespace node { 211cb0ef41Sopenharmony_cinamespace quic { 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_cistruct PathDescriptor { 241cb0ef41Sopenharmony_ci uint32_t version; 251cb0ef41Sopenharmony_ci const CID& dcid; 261cb0ef41Sopenharmony_ci const CID& scid; 271cb0ef41Sopenharmony_ci const SocketAddress& local_address; 281cb0ef41Sopenharmony_ci const SocketAddress& remote_address; 291cb0ef41Sopenharmony_ci}; 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci// A Packet encapsulates serialized outbound QUIC data. 321cb0ef41Sopenharmony_ci// Packets must never be larger than the path MTU. The 331cb0ef41Sopenharmony_ci// default QUIC packet maximum length is 1200 bytes, 341cb0ef41Sopenharmony_ci// which we assume by default. The packet storage will 351cb0ef41Sopenharmony_ci// be stack allocated up to this size. 361cb0ef41Sopenharmony_ci// 371cb0ef41Sopenharmony_ci// Packets are maintained in a freelist held by the 381cb0ef41Sopenharmony_ci// BindingData instance. When using Create() to create 391cb0ef41Sopenharmony_ci// a Packet, we'll check to see if there is a free 401cb0ef41Sopenharmony_ci// packet in the freelist and use it instead of starting 411cb0ef41Sopenharmony_ci// fresh with a new packet. The freelist can store at 421cb0ef41Sopenharmony_ci// most kMaxFreeList packets 431cb0ef41Sopenharmony_ci// 441cb0ef41Sopenharmony_ci// Packets are always encrypted so their content should 451cb0ef41Sopenharmony_ci// be considered opaque to us. We leave it entirely up 461cb0ef41Sopenharmony_ci// to ngtcp2 how to encode QUIC frames into the packet. 471cb0ef41Sopenharmony_ciclass Packet final : public ReqWrap<uv_udp_send_t> { 481cb0ef41Sopenharmony_ci private: 491cb0ef41Sopenharmony_ci struct Data; 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci public: 521cb0ef41Sopenharmony_ci using Queue = std::deque<BaseObjectPtr<Packet>>; 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( 551cb0ef41Sopenharmony_ci Environment* env); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci class Listener { 581cb0ef41Sopenharmony_ci public: 591cb0ef41Sopenharmony_ci virtual void PacketDone(int status) = 0; 601cb0ef41Sopenharmony_ci }; 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci // Do not use the Packet constructors directly to create 631cb0ef41Sopenharmony_ci // them. These are public only to support MakeBaseObject. 641cb0ef41Sopenharmony_ci // Use the Create, or Create variants to create or 651cb0ef41Sopenharmony_ci // acquire packet instances. 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci Packet(Environment* env, 681cb0ef41Sopenharmony_ci Listener* listener, 691cb0ef41Sopenharmony_ci v8::Local<v8::Object> object, 701cb0ef41Sopenharmony_ci const SocketAddress& destination, 711cb0ef41Sopenharmony_ci size_t length, 721cb0ef41Sopenharmony_ci const char* diagnostic_label = "<unknown>"); 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci Packet(Environment* env, 751cb0ef41Sopenharmony_ci Listener* listener, 761cb0ef41Sopenharmony_ci v8::Local<v8::Object> object, 771cb0ef41Sopenharmony_ci const SocketAddress& destination, 781cb0ef41Sopenharmony_ci std::shared_ptr<Data> data); 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci Packet(const Packet&) = delete; 811cb0ef41Sopenharmony_ci Packet(Packet&&) = delete; 821cb0ef41Sopenharmony_ci Packet& operator=(const Packet&) = delete; 831cb0ef41Sopenharmony_ci Packet& operator=(Packet&&) = delete; 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci const SocketAddress& destination() const; 861cb0ef41Sopenharmony_ci bool is_sending() const; 871cb0ef41Sopenharmony_ci size_t length() const; 881cb0ef41Sopenharmony_ci operator uv_buf_t() const; 891cb0ef41Sopenharmony_ci operator ngtcp2_vec() const; 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci // Modify the size of the packet after ngtcp2 has written 921cb0ef41Sopenharmony_ci // to it. len must be <= length(). We call this after we've 931cb0ef41Sopenharmony_ci // asked ngtcp2 to encode frames into the packet and ngtcp2 941cb0ef41Sopenharmony_ci // tells us how many of the packets bytes were used. 951cb0ef41Sopenharmony_ci void Truncate(size_t len); 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci static BaseObjectPtr<Packet> Create( 981cb0ef41Sopenharmony_ci Environment* env, 991cb0ef41Sopenharmony_ci Listener* listener, 1001cb0ef41Sopenharmony_ci const SocketAddress& destination, 1011cb0ef41Sopenharmony_ci size_t length = kDefaultMaxPacketLength, 1021cb0ef41Sopenharmony_ci const char* diagnostic_label = "<unknown>"); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci BaseObjectPtr<Packet> Clone() const; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci void MemoryInfo(MemoryTracker* tracker) const override; 1071cb0ef41Sopenharmony_ci SET_MEMORY_INFO_NAME(Packet) 1081cb0ef41Sopenharmony_ci SET_SELF_SIZE(Packet) 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci std::string ToString() const; 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci // Transmits the packet. The handle is the bound uv_udp_t 1131cb0ef41Sopenharmony_ci // port that we're sending on, the ref is a pointer to the 1141cb0ef41Sopenharmony_ci // HandleWrap that owns the handle. 1151cb0ef41Sopenharmony_ci int Send(uv_udp_t* handle, BaseObjectPtr<BaseObject> ref); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci static BaseObjectPtr<Packet> CreateRetryPacket( 1181cb0ef41Sopenharmony_ci Environment* env, 1191cb0ef41Sopenharmony_ci Listener* listener, 1201cb0ef41Sopenharmony_ci const PathDescriptor& path_descriptor, 1211cb0ef41Sopenharmony_ci const TokenSecret& token_secret); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci static BaseObjectPtr<Packet> CreateConnectionClosePacket( 1241cb0ef41Sopenharmony_ci Environment* env, 1251cb0ef41Sopenharmony_ci Listener* listener, 1261cb0ef41Sopenharmony_ci const SocketAddress& destination, 1271cb0ef41Sopenharmony_ci ngtcp2_conn* conn, 1281cb0ef41Sopenharmony_ci const QuicError& error); 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci static BaseObjectPtr<Packet> CreateImmediateConnectionClosePacket( 1311cb0ef41Sopenharmony_ci Environment* env, 1321cb0ef41Sopenharmony_ci Listener* listener, 1331cb0ef41Sopenharmony_ci const SocketAddress& destination, 1341cb0ef41Sopenharmony_ci const PathDescriptor& path_descriptor, 1351cb0ef41Sopenharmony_ci const QuicError& reason); 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci static BaseObjectPtr<Packet> CreateStatelessResetPacket( 1381cb0ef41Sopenharmony_ci Environment* env, 1391cb0ef41Sopenharmony_ci Listener* listener, 1401cb0ef41Sopenharmony_ci const PathDescriptor& path_descriptor, 1411cb0ef41Sopenharmony_ci const TokenSecret& token_secret, 1421cb0ef41Sopenharmony_ci size_t source_len); 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci static BaseObjectPtr<Packet> CreateVersionNegotiationPacket( 1451cb0ef41Sopenharmony_ci Environment* env, 1461cb0ef41Sopenharmony_ci Listener* listener, 1471cb0ef41Sopenharmony_ci const PathDescriptor& path_descriptor); 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci private: 1501cb0ef41Sopenharmony_ci static BaseObjectPtr<Packet> FromFreeList(Environment* env, 1511cb0ef41Sopenharmony_ci std::shared_ptr<Data> data, 1521cb0ef41Sopenharmony_ci Listener* listener, 1531cb0ef41Sopenharmony_ci const SocketAddress& destination); 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci // Called when the packet is done being sent. 1561cb0ef41Sopenharmony_ci void Done(int status); 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci Listener* listener_; 1591cb0ef41Sopenharmony_ci SocketAddress destination_; 1601cb0ef41Sopenharmony_ci std::shared_ptr<Data> data_; 1611cb0ef41Sopenharmony_ci BaseObjectPtr<BaseObject> handle_; 1621cb0ef41Sopenharmony_ci}; 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci} // namespace quic 1651cb0ef41Sopenharmony_ci} // namespace node 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci#endif // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC 1681cb0ef41Sopenharmony_ci#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 169