1 /* 2 * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 #ifndef NET_DCSCTP_PACKET_DATA_H_ 11 #define NET_DCSCTP_PACKET_DATA_H_ 12 13 #include <cstdint> 14 #include <utility> 15 #include <vector> 16 17 #include "net/dcsctp/common/internal_types.h" 18 #include "net/dcsctp/public/types.h" 19 20 namespace dcsctp { 21 22 // Represents data that is either received and extracted from a DATA/I-DATA 23 // chunk, or data that is supposed to be sent, and wrapped in a DATA/I-DATA 24 // chunk (depending on peer capabilities). 25 // 26 // The data wrapped in this structure is actually the same as the DATA/I-DATA 27 // chunk (actually the union of them), but to avoid having all components be 28 // aware of the implementation details of the different chunks, this abstraction 29 // is used instead. A notable difference is also that it doesn't carry a 30 // Transmission Sequence Number (TSN), as that is not known when a chunk is 31 // created (assigned late, just when sending), and that the TSNs in DATA/I-DATA 32 // are wrapped numbers, and within the library, unwrapped sequence numbers are 33 // preferably used. 34 struct Data { 35 // Indicates if a chunk is the first in a fragmented message and maps to the 36 // "beginning" flag in DATA/I-DATA chunk. 37 using IsBeginning = webrtc::StrongAlias<class IsBeginningTag, bool>; 38 39 // Indicates if a chunk is the last in a fragmented message and maps to the 40 // "end" flag in DATA/I-DATA chunk. 41 using IsEnd = webrtc::StrongAlias<class IsEndTag, bool>; 42 DataData43 Data(StreamID stream_id, 44 SSN ssn, 45 MID message_id, 46 FSN fsn, 47 PPID ppid, 48 std::vector<uint8_t> payload, 49 IsBeginning is_beginning, 50 IsEnd is_end, 51 IsUnordered is_unordered) 52 : stream_id(stream_id), 53 ssn(ssn), 54 message_id(message_id), 55 fsn(fsn), 56 ppid(ppid), 57 payload(std::move(payload)), 58 is_beginning(is_beginning), 59 is_end(is_end), 60 is_unordered(is_unordered) {} 61 62 // Move-only, to avoid accidental copies. 63 Data(Data&& other) = default; 64 Data& operator=(Data&& other) = default; 65 66 // Creates a copy of this `Data` object. CloneData67 Data Clone() const { 68 return Data(stream_id, ssn, message_id, fsn, ppid, payload, is_beginning, 69 is_end, is_unordered); 70 } 71 72 // The size of this data, which translates to the size of its payload. sizeData73 size_t size() const { return payload.size(); } 74 75 // Stream Identifier. 76 StreamID stream_id; 77 78 // Stream Sequence Number (SSN), per stream, for ordered chunks. Defined by 79 // RFC4960 and used only in DATA chunks (not I-DATA). 80 SSN ssn; 81 82 // Message Identifier (MID) per stream and ordered/unordered. Defined by 83 // RFC8260, and used together with options.is_unordered and stream_id to 84 // uniquely identify a message. Used only in I-DATA chunks (not DATA). 85 MID message_id; 86 // Fragment Sequence Number (FSN) per stream and ordered/unordered, as above. 87 FSN fsn; 88 89 // Payload Protocol Identifier (PPID). 90 PPID ppid; 91 92 // The actual data payload. 93 std::vector<uint8_t> payload; 94 95 // If this data represents the first, last or a middle chunk. 96 IsBeginning is_beginning; 97 IsEnd is_end; 98 // If this data is sent/received unordered. 99 IsUnordered is_unordered; 100 }; 101 } // namespace dcsctp 102 103 #endif // NET_DCSCTP_PACKET_DATA_H_ 104