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