1 // Copyright 2022 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_COMMON_MASQUE_CONNECT_UDP_DATAGRAM_PAYLOAD_H_ 6 #define QUICHE_COMMON_MASQUE_CONNECT_UDP_DATAGRAM_PAYLOAD_H_ 7 8 #include <cstdint> 9 #include <memory> 10 #include <string> 11 12 #include "absl/strings/string_view.h" 13 #include "quiche/common/quiche_data_writer.h" 14 15 namespace quiche { 16 17 // UDP-proxying HTTP Datagram payload for use with CONNECT-UDP. See RFC 9298, 18 // Section 5. 19 class QUICHE_EXPORT ConnectUdpDatagramPayload { 20 public: 21 using ContextId = uint64_t; 22 enum class Type { kUdpPacket, kUnknown }; 23 24 // Parse from `datagram_payload` (a wire-format UDP-proxying HTTP datagram 25 // payload). Returns nullptr on error. The created ConnectUdpDatagramPayload 26 // object may use absl::string_views pointing into `datagram_payload`, so the 27 // data pointed to by `datagram_payload` must outlive the created 28 // ConnectUdpDatagramPayload object. 29 static std::unique_ptr<ConnectUdpDatagramPayload> Parse( 30 absl::string_view datagram_payload); 31 32 ConnectUdpDatagramPayload() = default; 33 34 ConnectUdpDatagramPayload(const ConnectUdpDatagramPayload&) = delete; 35 ConnectUdpDatagramPayload& operator=(const ConnectUdpDatagramPayload&) = 36 delete; 37 38 virtual ~ConnectUdpDatagramPayload() = default; 39 40 virtual ContextId GetContextId() const = 0; 41 virtual Type GetType() const = 0; 42 // Get the inner payload (the UDP Proxying Payload). 43 virtual absl::string_view GetUdpProxyingPayload() const = 0; 44 45 // Length of this UDP-proxying HTTP datagram payload in wire format. 46 virtual size_t SerializedLength() const = 0; 47 // Write a wire-format buffer for the payload. Returns false on write failure 48 // (typically due to `writer` buffer being full). 49 virtual bool SerializeTo(QuicheDataWriter& writer) const = 0; 50 51 // Write a wire-format buffer. 52 std::string Serialize() const; 53 }; 54 55 // UDP-proxying HTTP Datagram payload that encodes a UDP packet. 56 class QUICHE_EXPORT ConnectUdpDatagramUdpPacketPayload final 57 : public ConnectUdpDatagramPayload { 58 public: 59 static constexpr ContextId kContextId = 0; 60 61 // The string pointed to by `udp_packet` must outlive the created 62 // ConnectUdpDatagramUdpPacketPayload. 63 explicit ConnectUdpDatagramUdpPacketPayload(absl::string_view udp_packet); 64 65 ContextId GetContextId() const override; 66 Type GetType() const override; 67 absl::string_view GetUdpProxyingPayload() const override; 68 size_t SerializedLength() const override; 69 bool SerializeTo(QuicheDataWriter& writer) const override; 70 udp_packet()71 absl::string_view udp_packet() const { return udp_packet_; } 72 73 private: 74 absl::string_view udp_packet_; 75 }; 76 77 class QUICHE_EXPORT ConnectUdpDatagramUnknownPayload final 78 : public ConnectUdpDatagramPayload { 79 public: 80 // `udp_proxying_payload` represents the inner payload contained by the UDP- 81 // proxying HTTP datagram payload. The string pointed to by `inner_payload` 82 // must outlive the created ConnectUdpDatagramUnknownPayload. 83 ConnectUdpDatagramUnknownPayload(ContextId context_id, 84 absl::string_view udp_proxying_payload); 85 86 ContextId GetContextId() const override; 87 Type GetType() const override; 88 absl::string_view GetUdpProxyingPayload() const override; 89 size_t SerializedLength() const override; 90 bool SerializeTo(QuicheDataWriter& writer) const override; 91 92 private: 93 ContextId context_id_; 94 absl::string_view udp_proxying_payload_; // The inner payload. 95 }; 96 97 } // namespace quiche 98 99 #endif // QUICHE_COMMON_MASQUE_CONNECT_UDP_DATAGRAM_PAYLOAD_H_ 100