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 #include "quiche/common/masque/connect_udp_datagram_payload.h" 6 7 #include <cstdint> 8 #include <memory> 9 #include <utility> 10 11 #include "absl/strings/string_view.h" 12 #include "quiche/common/platform/api/quiche_bug_tracker.h" 13 #include "quiche/common/platform/api/quiche_logging.h" 14 #include "quiche/common/quiche_data_reader.h" 15 #include "quiche/common/quiche_data_writer.h" 16 17 namespace quiche { 18 19 // static Parse(absl::string_view datagram_payload)20std::unique_ptr<ConnectUdpDatagramPayload> ConnectUdpDatagramPayload::Parse( 21 absl::string_view datagram_payload) { 22 QuicheDataReader data_reader(datagram_payload); 23 24 uint64_t context_id; 25 if (!data_reader.ReadVarInt62(&context_id)) { 26 QUICHE_DVLOG(1) << "Could not parse malformed UDP proxy payload"; 27 return nullptr; 28 } 29 30 if (ContextId{context_id} == ConnectUdpDatagramUdpPacketPayload::kContextId) { 31 return std::make_unique<ConnectUdpDatagramUdpPacketPayload>( 32 data_reader.ReadRemainingPayload()); 33 } else { 34 return std::make_unique<ConnectUdpDatagramUnknownPayload>( 35 ContextId{context_id}, data_reader.ReadRemainingPayload()); 36 } 37 } 38 Serialize() const39std::string ConnectUdpDatagramPayload::Serialize() const { 40 std::string buffer(SerializedLength(), '\0'); 41 QuicheDataWriter writer(buffer.size(), buffer.data()); 42 43 bool result = SerializeTo(writer); 44 QUICHE_DCHECK(result); 45 QUICHE_DCHECK_EQ(writer.remaining(), 0u); 46 47 return buffer; 48 } 49 ConnectUdpDatagramUdpPacketPayload(absl::string_view udp_packet)50ConnectUdpDatagramUdpPacketPayload::ConnectUdpDatagramUdpPacketPayload( 51 absl::string_view udp_packet) 52 : udp_packet_(udp_packet) {} 53 54 ConnectUdpDatagramPayload::ContextId GetContextId() const55ConnectUdpDatagramUdpPacketPayload::GetContextId() const { 56 return kContextId; 57 } 58 GetType() const59ConnectUdpDatagramPayload::Type ConnectUdpDatagramUdpPacketPayload::GetType() 60 const { 61 return Type::kUdpPacket; 62 } 63 GetUdpProxyingPayload() const64absl::string_view ConnectUdpDatagramUdpPacketPayload::GetUdpProxyingPayload() 65 const { 66 return udp_packet_; 67 } 68 SerializedLength() const69size_t ConnectUdpDatagramUdpPacketPayload::SerializedLength() const { 70 return udp_packet_.size() + 71 QuicheDataWriter::GetVarInt62Len(uint64_t{kContextId}); 72 } 73 SerializeTo(QuicheDataWriter & writer) const74bool ConnectUdpDatagramUdpPacketPayload::SerializeTo( 75 QuicheDataWriter& writer) const { 76 if (!writer.WriteVarInt62(uint64_t{kContextId})) { 77 return false; 78 } 79 80 if (!writer.WriteStringPiece(udp_packet_)) { 81 return false; 82 } 83 84 return true; 85 } 86 ConnectUdpDatagramUnknownPayload(ContextId context_id,absl::string_view udp_proxying_payload)87ConnectUdpDatagramUnknownPayload::ConnectUdpDatagramUnknownPayload( 88 ContextId context_id, absl::string_view udp_proxying_payload) 89 : context_id_(context_id), udp_proxying_payload_(udp_proxying_payload) { 90 if (context_id == ConnectUdpDatagramUdpPacketPayload::kContextId) { 91 QUICHE_BUG(udp_proxy_unknown_payload_udp_context) 92 << "ConnectUdpDatagramUnknownPayload created with UDP packet context " 93 "type (0). Should instead create a " 94 "ConnectUdpDatagramUdpPacketPayload."; 95 } 96 } 97 98 ConnectUdpDatagramPayload::ContextId GetContextId() const99ConnectUdpDatagramUnknownPayload::GetContextId() const { 100 return context_id_; 101 } 102 GetType() const103ConnectUdpDatagramPayload::Type ConnectUdpDatagramUnknownPayload::GetType() 104 const { 105 return Type::kUnknown; 106 } GetUdpProxyingPayload() const107absl::string_view ConnectUdpDatagramUnknownPayload::GetUdpProxyingPayload() 108 const { 109 return udp_proxying_payload_; 110 } 111 SerializedLength() const112size_t ConnectUdpDatagramUnknownPayload::SerializedLength() const { 113 return udp_proxying_payload_.size() + 114 QuicheDataWriter::GetVarInt62Len(uint64_t{context_id_}); 115 } 116 SerializeTo(QuicheDataWriter & writer) const117bool ConnectUdpDatagramUnknownPayload::SerializeTo( 118 QuicheDataWriter& writer) const { 119 if (!writer.WriteVarInt62(uint64_t{context_id_})) { 120 return false; 121 } 122 123 if (!writer.WriteStringPiece(udp_proxying_payload_)) { 124 return false; 125 } 126 127 return true; 128 } 129 130 } // namespace quiche 131