tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CapsuleEncoder.cpp (6351B)


      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 #include "nsString.h"
      8 #include "nsTArray.h"
      9 
     10 #include "Capsule.h"
     11 #include "CapsuleEncoder.h"
     12 
     13 namespace mozilla::net {
     14 
     15 CapsuleEncoder::CapsuleEncoder() {
     16  NeqoEncoder::Init(getter_AddRefs(mEncoder));
     17  MOZ_ASSERT(mEncoder);
     18 }
     19 
     20 CapsuleEncoder::~CapsuleEncoder() = default;
     21 
     22 void CapsuleEncoder::EncodeCapsule(Capsule& aCapsule) {
     23  if (aCapsule.mCapsule.is<UnknownCapsule>()) {
     24    auto& value = aCapsule.mCapsule.as<UnknownCapsule>();
     25    EncodeVarint(value.mType).EncodeBufferWithVarintLen(value.mData);
     26    return;
     27  }
     28 
     29  if (aCapsule.mCapsule.is<CloseWebTransportSessionCapsule>()) {
     30    const auto& value = aCapsule.mCapsule.as<CloseWebTransportSessionCapsule>();
     31    EncodeVarint(value.Type())
     32        .EncodeVarint(4 + value.mReason.Length())
     33        .EncodeUint(4, value.mStatus)
     34        .EncodeString(value.mReason);
     35    return;
     36  }
     37 
     38  if (aCapsule.mCapsule.is<WebTransportMaxDataCapsule>()) {
     39    auto& value = aCapsule.mCapsule.as<WebTransportMaxDataCapsule>();
     40    EncodeVarint(value.Type())
     41        .EncodeVarint(CapsuleEncoder::VarintLength(value.mMaxDataSize))
     42        .EncodeVarint(value.mMaxDataSize);
     43    return;
     44  }
     45 
     46  if (aCapsule.mCapsule.is<WebTransportStreamDataCapsule>()) {
     47    auto& value = aCapsule.mCapsule.as<WebTransportStreamDataCapsule>();
     48    uint64_t length =
     49        CapsuleEncoder::VarintLength(value.mID) + value.mData.Length();
     50    EncodeVarint(value.Type())
     51        .EncodeVarint(length)
     52        .EncodeVarint(value.mID)
     53        .EncodeBuffer(value.mData);
     54    mStreamMetadata = Some(StreamMetadata{
     55        value.mID, value.mData.Length(),
     56        CapsuleEncoder::VarintLength(static_cast<uint64_t>(value.Type())) +
     57            CapsuleEncoder::VarintLength(length) +
     58            CapsuleEncoder::VarintLength(value.mID)});
     59    return;
     60  }
     61 
     62  if (aCapsule.mCapsule.is<WebTransportStreamsBlockedCapsule>()) {
     63    auto& value = aCapsule.mCapsule.as<WebTransportStreamsBlockedCapsule>();
     64    EncodeVarint(value.Type())
     65        .EncodeVarint(CapsuleEncoder::VarintLength(value.mLimit))
     66        .EncodeVarint(value.mLimit);
     67    return;
     68  }
     69 
     70  if (aCapsule.mCapsule.is<WebTransportMaxStreamsCapsule>()) {
     71    auto& value = aCapsule.mCapsule.as<WebTransportMaxStreamsCapsule>();
     72    EncodeVarint(value.Type())
     73        .EncodeVarint(CapsuleEncoder::VarintLength(value.mLimit))
     74        .EncodeVarint(value.mLimit);
     75    return;
     76  }
     77 
     78  if (aCapsule.mCapsule.is<WebTransportStreamDataBlockedCapsule>()) {
     79    auto& value = aCapsule.mCapsule.as<WebTransportStreamDataBlockedCapsule>();
     80    EncodeVarint(value.Type())
     81        .EncodeVarint(CapsuleEncoder::VarintLength(value.mID) +
     82                      CapsuleEncoder::VarintLength(value.mLimit))
     83        .EncodeVarint(value.mID)
     84        .EncodeVarint(value.mLimit);
     85    return;
     86  }
     87 
     88  if (aCapsule.mCapsule.is<WebTransportMaxStreamDataCapsule>()) {
     89    auto& value = aCapsule.mCapsule.as<WebTransportMaxStreamDataCapsule>();
     90    EncodeVarint(value.Type())
     91        .EncodeVarint(CapsuleEncoder::VarintLength(value.mID) +
     92                      CapsuleEncoder::VarintLength(value.mLimit))
     93        .EncodeVarint(value.mID)
     94        .EncodeVarint(value.mLimit);
     95    return;
     96  }
     97 
     98  if (aCapsule.mCapsule.is<WebTransportDataBlockedCapsule>()) {
     99    auto& value = aCapsule.mCapsule.as<WebTransportDataBlockedCapsule>();
    100    EncodeVarint(value.Type())
    101        .EncodeVarint(CapsuleEncoder::VarintLength(value.mLimit))
    102        .EncodeVarint(value.mLimit);
    103    return;
    104  }
    105 
    106  if (aCapsule.mCapsule.is<WebTransportStopSendingCapsule>()) {
    107    auto& value = aCapsule.mCapsule.as<WebTransportStopSendingCapsule>();
    108    EncodeVarint(value.Type())
    109        .EncodeVarint(CapsuleEncoder::VarintLength(value.mID) +
    110                      CapsuleEncoder::VarintLength(value.mErrorCode))
    111        .EncodeVarint(value.mID)
    112        .EncodeVarint(value.mErrorCode);
    113    return;
    114  }
    115 
    116  if (aCapsule.mCapsule.is<WebTransportResetStreamCapsule>()) {
    117    auto& value = aCapsule.mCapsule.as<WebTransportResetStreamCapsule>();
    118    EncodeVarint(value.Type())
    119        .EncodeVarint(CapsuleEncoder::VarintLength(value.mID) +
    120                      CapsuleEncoder::VarintLength(value.mErrorCode) +
    121                      CapsuleEncoder::VarintLength(value.mReliableSize))
    122        .EncodeVarint(value.mID)
    123        .EncodeVarint(value.mErrorCode)
    124        .EncodeVarint(value.mReliableSize);
    125    return;
    126  }
    127 
    128  if (aCapsule.mCapsule.is<WebTransportDatagramCapsule>()) {
    129    auto& value = aCapsule.mCapsule.as<WebTransportDatagramCapsule>();
    130    uint64_t length = value.mPayload.Length();
    131    EncodeVarint(value.Type())
    132        .EncodeVarint(length)
    133        .EncodeBuffer(value.mPayload);
    134    return;
    135  }
    136 }
    137 
    138 CapsuleEncoder& CapsuleEncoder::EncodeByte(uint8_t aData) {
    139  mEncoder->EncodeByte(aData);
    140  return *this;
    141 }
    142 
    143 template <typename T>
    144 CapsuleEncoder& CapsuleEncoder::EncodeUint(uint32_t aSize, T aValue) {
    145  uint64_t value = static_cast<uint64_t>(aValue);
    146  mEncoder->EncodeUint(aSize, value);
    147  return *this;
    148 }
    149 
    150 template <typename T>
    151 CapsuleEncoder& CapsuleEncoder::EncodeVarint(T aValue) {
    152  uint64_t value = static_cast<uint64_t>(aValue);
    153  mEncoder->EncodeVarint(value);
    154  return *this;
    155 }
    156 
    157 CapsuleEncoder& CapsuleEncoder::EncodeString(const nsACString& aData) {
    158  mEncoder->EncodeBuffer(reinterpret_cast<const uint8_t*>(aData.BeginReading()),
    159                         aData.Length());
    160  return *this;
    161 }
    162 
    163 CapsuleEncoder& CapsuleEncoder::EncodeBuffer(nsTArray<uint8_t>& aData) {
    164  mEncoder->EncodeBuffer(aData.Elements(), aData.Length());
    165  return *this;
    166 }
    167 
    168 CapsuleEncoder& CapsuleEncoder::EncodeBufferWithVarintLen(
    169    nsTArray<uint8_t>& aData) {
    170  mEncoder->EncodeBufferWithVarintLen(aData.Elements(), aData.Length());
    171  return *this;
    172 }
    173 
    174 // static
    175 size_t CapsuleEncoder::VarintLength(uint64_t aValue) {
    176  return NeqoEncoder::VarintLength(aValue);
    177 }
    178 
    179 mozilla::Span<const uint8_t> CapsuleEncoder::GetBuffer() {
    180  const uint8_t* buffer = nullptr;
    181  uint32_t length = 0;
    182  mEncoder->GetData(&buffer, &length);
    183  return Span<const uint8_t>(buffer, length);
    184 }
    185 
    186 }  // namespace mozilla::net