Capsule.h (8347B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set sw=2 ts=8 et tw=80 : */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_net_capsule_h 8 #define mozilla_net_capsule_h 9 10 #include "mozilla/Variant.h" 11 #include "nsString.h" 12 #include "nsTArray.h" 13 14 namespace mozilla::net { 15 16 class CapsuleEncoder; 17 18 enum class CapsuleType : uint64_t { 19 CLOSE_WEBTRANSPORT_SESSION = 0x2843, 20 DRAIN_WEBTRANSPORT_SESSION = 0x78AE, 21 PADDING = 0x190b4d38, 22 WT_RESET_STREAM = 0x190B4D39, 23 WT_STOP_SENDING = 0x190B4D3A, 24 WT_STREAM = 0x190B4D3B, 25 WT_STREAM_FIN = 0x190B4D3C, 26 WT_MAX_DATA = 0x190B4D3D, 27 WT_MAX_STREAM_DATA = 0x190B4D3E, 28 WT_MAX_STREAMS_BIDI = 0x190B4D3F, 29 WT_MAX_STREAMS_UNIDI = 0x190B4D40, 30 WT_DATA_BLOCKED = 0x190B4D41, 31 WT_STREAM_DATA_BLOCKED = 0x190B4D42, 32 WT_STREAMS_BLOCKED_BIDI = 0x190B4D43, 33 WT_STREAMS_BLOCKED_UNIDI = 0x190B4D44, 34 DATAGRAM = 0x00, 35 }; 36 37 struct UnknownCapsule { 38 uint64_t mType; 39 nsTArray<uint8_t> mData; 40 41 CapsuleType Type() const { return static_cast<CapsuleType>(mType); } 42 }; 43 44 struct CloseWebTransportSessionCapsule { 45 uint32_t mStatus{0}; 46 nsCString mReason; 47 48 CapsuleType Type() const { return CapsuleType::CLOSE_WEBTRANSPORT_SESSION; } 49 }; 50 51 struct WebTransportMaxDataCapsule { 52 uint64_t mMaxDataSize{0}; 53 54 CapsuleType Type() const { return CapsuleType::WT_MAX_DATA; } 55 }; 56 57 struct WebTransportStreamDataCapsule { 58 uint64_t mID{0}; 59 bool mFin{false}; 60 nsTArray<uint8_t> mData; 61 62 CapsuleType Type() const { 63 return mFin ? CapsuleType::WT_STREAM_FIN : CapsuleType::WT_STREAM; 64 } 65 }; 66 67 struct WebTransportStreamsBlockedCapsule { 68 uint64_t mLimit = 0; 69 bool mBidi = true; 70 71 CapsuleType Type() const { 72 return mBidi ? CapsuleType::WT_STREAMS_BLOCKED_BIDI 73 : CapsuleType::WT_STREAMS_BLOCKED_UNIDI; 74 } 75 }; 76 77 struct WebTransportMaxStreamsCapsule { 78 uint64_t mLimit = 0; 79 bool mBidi = true; 80 81 CapsuleType Type() const { 82 return mBidi ? CapsuleType::WT_MAX_STREAMS_BIDI 83 : CapsuleType::WT_MAX_STREAMS_UNIDI; 84 } 85 }; 86 87 struct WebTransportStreamDataBlockedCapsule { 88 uint64_t mLimit = 0; 89 uint64_t mID{0}; 90 91 CapsuleType Type() const { return CapsuleType::WT_STREAM_DATA_BLOCKED; } 92 }; 93 94 struct WebTransportMaxStreamDataCapsule { 95 uint64_t mLimit = 0; 96 uint64_t mID{0}; 97 98 CapsuleType Type() const { return CapsuleType::WT_MAX_STREAM_DATA; } 99 }; 100 101 struct WebTransportDataBlockedCapsule { 102 uint64_t mLimit = 0; 103 uint64_t mID{0}; 104 105 CapsuleType Type() const { return CapsuleType::WT_DATA_BLOCKED; } 106 }; 107 108 struct WebTransportStopSendingCapsule { 109 uint64_t mErrorCode = 0; 110 uint64_t mID{0}; 111 112 CapsuleType Type() const { return CapsuleType::WT_STOP_SENDING; } 113 }; 114 115 struct WebTransportResetStreamCapsule { 116 uint64_t mErrorCode = 0; 117 uint64_t mReliableSize{0}; 118 uint64_t mID{0}; 119 120 CapsuleType Type() const { return CapsuleType::WT_RESET_STREAM; } 121 }; 122 123 struct WebTransportDatagramCapsule { 124 nsTArray<uint8_t> mPayload; 125 126 CapsuleType Type() const { return CapsuleType::DATAGRAM; } 127 }; 128 129 using CapsuleValue = mozilla::Variant< 130 UnknownCapsule, CloseWebTransportSessionCapsule, WebTransportMaxDataCapsule, 131 WebTransportStreamDataCapsule, WebTransportStreamsBlockedCapsule, 132 WebTransportMaxStreamsCapsule, WebTransportStreamDataBlockedCapsule, 133 WebTransportMaxStreamDataCapsule, WebTransportDataBlockedCapsule, 134 WebTransportStopSendingCapsule, WebTransportResetStreamCapsule, 135 WebTransportDatagramCapsule>; 136 137 class Capsule final { 138 public: 139 static Capsule Unknown(uint64_t aType, nsTArray<uint8_t>&& aData); 140 static Capsule CloseWebTransportSession(uint32_t aStatus, 141 const nsACString& aReason); 142 static Capsule WebTransportMaxData(uint64_t aValue); 143 static Capsule WebTransportStreamData(uint64_t aID, bool aFin, 144 nsTArray<uint8_t>&& aData); 145 static Capsule WebTransportStreamsBlocked(uint64_t aLimit, bool aBidi); 146 static Capsule WebTransportMaxStreams(uint64_t aLimit, bool aBidi); 147 static Capsule WebTransportStreamDataBlocked(uint64_t aLimit, uint64_t aID); 148 static Capsule WebTransportMaxStreamData(uint64_t aLimit, uint64_t aID); 149 static Capsule WebTransportDataBlocked(uint64_t aLimit); 150 static Capsule WebTransportStopSending(uint64_t aError, uint64_t aID); 151 static Capsule WebTransportResetStream(uint64_t aError, uint64_t aSize, 152 uint64_t aID); 153 static Capsule WebTransportDatagram(nsTArray<uint8_t>&& aData); 154 155 CapsuleType Type() const; 156 157 UnknownCapsule& GetUnknownCapsule() { return mCapsule.as<UnknownCapsule>(); } 158 const UnknownCapsule& GetUnknownCapsule() const { 159 return mCapsule.as<UnknownCapsule>(); 160 } 161 CloseWebTransportSessionCapsule& GetCloseWebTransportSessionCapsule() { 162 return mCapsule.as<CloseWebTransportSessionCapsule>(); 163 } 164 const CloseWebTransportSessionCapsule& GetCloseWebTransportSessionCapsule() 165 const { 166 return mCapsule.as<CloseWebTransportSessionCapsule>(); 167 } 168 WebTransportMaxDataCapsule& GetWebTransportMaxDataCapsule() { 169 return mCapsule.as<WebTransportMaxDataCapsule>(); 170 } 171 const WebTransportMaxDataCapsule& GetWebTransportMaxDataCapsule() const { 172 return mCapsule.as<WebTransportMaxDataCapsule>(); 173 } 174 WebTransportStreamDataCapsule& GetWebTransportStreamDataCapsule() { 175 return mCapsule.as<WebTransportStreamDataCapsule>(); 176 } 177 const WebTransportStreamDataCapsule& GetWebTransportStreamDataCapsule() 178 const { 179 return mCapsule.as<WebTransportStreamDataCapsule>(); 180 } 181 WebTransportStreamsBlockedCapsule& GetWebTransportStreamsBlockedCapsule() { 182 return mCapsule.as<WebTransportStreamsBlockedCapsule>(); 183 } 184 const WebTransportStreamsBlockedCapsule& 185 GetWebTransportStreamsBlockedCapsule() const { 186 return mCapsule.as<WebTransportStreamsBlockedCapsule>(); 187 } 188 WebTransportMaxStreamsCapsule& GetWebTransportMaxStreamsCapsule() { 189 return mCapsule.as<WebTransportMaxStreamsCapsule>(); 190 } 191 const WebTransportMaxStreamsCapsule& GetWebTransportMaxStreamsCapsule() 192 const { 193 return mCapsule.as<WebTransportMaxStreamsCapsule>(); 194 } 195 WebTransportStreamDataBlockedCapsule& 196 GetWebTransportStreamDataBlockedCapsule() { 197 return mCapsule.as<WebTransportStreamDataBlockedCapsule>(); 198 } 199 const WebTransportStreamDataBlockedCapsule& 200 GetWebTransportStreamDataBlockedCapsule() const { 201 return mCapsule.as<WebTransportStreamDataBlockedCapsule>(); 202 } 203 WebTransportMaxStreamDataCapsule& GetWebTransportMaxStreamDataCapsule() { 204 return mCapsule.as<WebTransportMaxStreamDataCapsule>(); 205 } 206 const WebTransportMaxStreamDataCapsule& GetWebTransportMaxStreamDataCapsule() 207 const { 208 return mCapsule.as<WebTransportMaxStreamDataCapsule>(); 209 } 210 WebTransportDataBlockedCapsule& GetWebTransportDataBlockedCapsule() { 211 return mCapsule.as<WebTransportDataBlockedCapsule>(); 212 } 213 const WebTransportDataBlockedCapsule& GetWebTransportDataBlockedCapsule() 214 const { 215 return mCapsule.as<WebTransportDataBlockedCapsule>(); 216 } 217 WebTransportStopSendingCapsule& GetWebTransportStopSendingCapsule() { 218 return mCapsule.as<WebTransportStopSendingCapsule>(); 219 } 220 const WebTransportStopSendingCapsule& GetWebTransportStopSendingCapsule() 221 const { 222 return mCapsule.as<WebTransportStopSendingCapsule>(); 223 } 224 WebTransportResetStreamCapsule& GetWebTransportResetStreamCapsule() { 225 return mCapsule.as<WebTransportResetStreamCapsule>(); 226 } 227 const WebTransportResetStreamCapsule& GetWebTransportResetStreamCapsule() 228 const { 229 return mCapsule.as<WebTransportResetStreamCapsule>(); 230 } 231 WebTransportDatagramCapsule& GetWebTransportDatagramCapsule() { 232 return mCapsule.as<WebTransportDatagramCapsule>(); 233 } 234 const WebTransportDatagramCapsule& GetWebTransportDatagramCapsule() const { 235 return mCapsule.as<WebTransportDatagramCapsule>(); 236 } 237 238 template <typename CapsuleStruct> 239 explicit Capsule(CapsuleStruct&& aCapsule) : mCapsule(std::move(aCapsule)) {} 240 241 static void LogBuffer(const uint8_t* aBuffer, uint32_t aLength); 242 243 private: 244 Capsule() = default; 245 246 friend class CapsuleEncoder; 247 CapsuleValue mCapsule = AsVariant(UnknownCapsule()); 248 }; 249 250 }; // namespace mozilla::net 251 252 #endif