• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <ngtcp2/ngtcp2.h>
9 #include <node_external_reference.h>
10 #include <node_sockaddr.h>
11 #include <req_wrap.h>
12 #include <uv.h>
13 #include <v8.h>
14 #include <string>
15 #include "bindingdata.h"
16 #include "cid.h"
17 #include "data.h"
18 #include "tokens.h"
19 
20 namespace node {
21 namespace quic {
22 
23 struct PathDescriptor {
24   uint32_t version;
25   const CID& dcid;
26   const CID& scid;
27   const SocketAddress& local_address;
28   const SocketAddress& remote_address;
29 };
30 
31 // A Packet encapsulates serialized outbound QUIC data.
32 // Packets must never be larger than the path MTU. The
33 // default QUIC packet maximum length is 1200 bytes,
34 // which we assume by default. The packet storage will
35 // be stack allocated up to this size.
36 //
37 // Packets are maintained in a freelist held by the
38 // BindingData instance. When using Create() to create
39 // a Packet, we'll check to see if there is a free
40 // packet in the freelist and use it instead of starting
41 // fresh with a new packet. The freelist can store at
42 // most kMaxFreeList packets
43 //
44 // Packets are always encrypted so their content should
45 // be considered opaque to us. We leave it entirely up
46 // to ngtcp2 how to encode QUIC frames into the packet.
47 class Packet final : public ReqWrap<uv_udp_send_t> {
48  private:
49   struct Data;
50 
51  public:
52   using Queue = std::deque<BaseObjectPtr<Packet>>;
53 
54   static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
55       Environment* env);
56 
57   class Listener {
58    public:
59     virtual void PacketDone(int status) = 0;
60   };
61 
62   // Do not use the Packet constructors directly to create
63   // them. These are public only to support MakeBaseObject.
64   // Use the Create, or Create variants to create or
65   // acquire packet instances.
66 
67   Packet(Environment* env,
68          Listener* listener,
69          v8::Local<v8::Object> object,
70          const SocketAddress& destination,
71          size_t length,
72          const char* diagnostic_label = "<unknown>");
73 
74   Packet(Environment* env,
75          Listener* listener,
76          v8::Local<v8::Object> object,
77          const SocketAddress& destination,
78          std::shared_ptr<Data> data);
79 
80   Packet(const Packet&) = delete;
81   Packet(Packet&&) = delete;
82   Packet& operator=(const Packet&) = delete;
83   Packet& operator=(Packet&&) = delete;
84 
85   const SocketAddress& destination() const;
86   bool is_sending() const;
87   size_t length() const;
88   operator uv_buf_t() const;
89   operator ngtcp2_vec() const;
90 
91   // Modify the size of the packet after ngtcp2 has written
92   // to it. len must be <= length(). We call this after we've
93   // asked ngtcp2 to encode frames into the packet and ngtcp2
94   // tells us how many of the packets bytes were used.
95   void Truncate(size_t len);
96 
97   static BaseObjectPtr<Packet> Create(
98       Environment* env,
99       Listener* listener,
100       const SocketAddress& destination,
101       size_t length = kDefaultMaxPacketLength,
102       const char* diagnostic_label = "<unknown>");
103 
104   BaseObjectPtr<Packet> Clone() const;
105 
106   void MemoryInfo(MemoryTracker* tracker) const override;
107   SET_MEMORY_INFO_NAME(Packet)
108   SET_SELF_SIZE(Packet)
109 
110   std::string ToString() const;
111 
112   // Transmits the packet. The handle is the bound uv_udp_t
113   // port that we're sending on, the ref is a pointer to the
114   // HandleWrap that owns the handle.
115   int Send(uv_udp_t* handle, BaseObjectPtr<BaseObject> ref);
116 
117   static BaseObjectPtr<Packet> CreateRetryPacket(
118       Environment* env,
119       Listener* listener,
120       const PathDescriptor& path_descriptor,
121       const TokenSecret& token_secret);
122 
123   static BaseObjectPtr<Packet> CreateConnectionClosePacket(
124       Environment* env,
125       Listener* listener,
126       const SocketAddress& destination,
127       ngtcp2_conn* conn,
128       const QuicError& error);
129 
130   static BaseObjectPtr<Packet> CreateImmediateConnectionClosePacket(
131       Environment* env,
132       Listener* listener,
133       const SocketAddress& destination,
134       const PathDescriptor& path_descriptor,
135       const QuicError& reason);
136 
137   static BaseObjectPtr<Packet> CreateStatelessResetPacket(
138       Environment* env,
139       Listener* listener,
140       const PathDescriptor& path_descriptor,
141       const TokenSecret& token_secret,
142       size_t source_len);
143 
144   static BaseObjectPtr<Packet> CreateVersionNegotiationPacket(
145       Environment* env,
146       Listener* listener,
147       const PathDescriptor& path_descriptor);
148 
149  private:
150   static BaseObjectPtr<Packet> FromFreeList(Environment* env,
151                                             std::shared_ptr<Data> data,
152                                             Listener* listener,
153                                             const SocketAddress& destination);
154 
155   // Called when the packet is done being sent.
156   void Done(int status);
157 
158   Listener* listener_;
159   SocketAddress destination_;
160   std::shared_ptr<Data> data_;
161   BaseObjectPtr<BaseObject> handle_;
162 };
163 
164 }  // namespace quic
165 }  // namespace node
166 
167 #endif  // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
168 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
169