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