tor-browser

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

WebTransportStreamBase.h (4483B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef mozilla_net_WebTransportStreamBase_h
      7 #define mozilla_net_WebTransportStreamBase_h
      8 
      9 #include "nsISupportsImpl.h"
     10 #include "mozilla/net/neqo_glue_ffi_generated.h"
     11 #include "mozilla/Atomics.h"
     12 #include "mozilla/Mutex.h"
     13 #include "nsCOMPtr.h"
     14 #include "nsIAsyncInputStream.h"
     15 #include "nsIAsyncOutputStream.h"
     16 
     17 class nsIWebTransportSendStreamStats;
     18 class nsIWebTransportReceiveStreamStats;
     19 
     20 namespace mozilla::net {
     21 
     22 // https://www.ietf.org/archive/id/draft-ietf-webtrans-http2-10.html#section-5.2-2
     23 // Client initiated streams having even-numbered stream IDs and
     24 // server-initiated streams having odd-numbered stream IDs. Similarly, they
     25 // can be bidirectional or unidirectional, indicated by the second least
     26 // significant bit of the stream ID.
     27 
     28 class StreamId {
     29 public:
     30  constexpr explicit StreamId(uint64_t aId) : mId(aId) {}
     31 
     32  constexpr bool IsBiDi() const { return (mId & 0x02) == 0; }
     33 
     34  constexpr bool IsUni() const { return !IsBiDi(); }
     35 
     36  constexpr WebTransportStreamType StreamType() const {
     37    return IsBiDi() ? WebTransportStreamType::BiDi
     38                    : WebTransportStreamType::UniDi;
     39  }
     40 
     41  constexpr bool IsClientInitiated() const { return (mId & 0x01) == 0; }
     42 
     43  constexpr bool IsServerInitiated() const { return !IsClientInitiated(); }
     44 
     45  void Next() { mId += 4; }
     46 
     47  constexpr uint64_t Index() const { return mId >> 2; }
     48 
     49  constexpr bool operator==(const StreamId& aRhs) const {
     50    return mId == aRhs.mId;
     51  }
     52 
     53  static constexpr StreamId From(uint64_t aVal) { return StreamId(aVal); }
     54 
     55  constexpr operator uint64_t() const { return mId; }
     56 
     57 private:
     58  uint64_t mId = 0;
     59 };
     60 
     61 class SenderFlowControlBase;
     62 class ReceiverFlowControlBase;
     63 
     64 class WebTransportStreamBase : public nsIInputStreamCallback,
     65                               public nsIOutputStreamCallback {
     66 public:
     67  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
     68 
     69  explicit WebTransportStreamBase(
     70      uint64_t aSessionId,
     71      std::function<void(Result<RefPtr<WebTransportStreamBase>, nsresult>&&)>&&
     72          aCallback);
     73 
     74  WebTransportStreamType StreamType() const { return mStreamType; }
     75 
     76  void GetWriterAndReader(nsIAsyncOutputStream** aOutOutputStream,
     77                          nsIAsyncInputStream** aOutInputStream);
     78 
     79  virtual StreamId WebTransportStreamId() const = 0;
     80  virtual uint64_t GetStreamId() const = 0;
     81  virtual void SendStopSending(uint8_t aErrorCode) = 0;
     82  virtual void SendFin() = 0;
     83  virtual void Reset(uint64_t aErrorCode) = 0;
     84  virtual already_AddRefed<nsIWebTransportSendStreamStats>
     85  GetSendStreamStats() = 0;
     86  virtual already_AddRefed<nsIWebTransportReceiveStreamStats>
     87  GetReceiveStreamStats() = 0;
     88  virtual bool RecvDone() const = 0;
     89  virtual void SetSendOrder(Maybe<int64_t> aSendOrder) = 0;
     90  // Used only for testing.
     91  virtual SenderFlowControlBase* SenderFc() { return nullptr; }
     92  virtual ReceiverFlowControlBase* ReceiverFc() { return nullptr; }
     93 
     94 protected:
     95  virtual ~WebTransportStreamBase();
     96 
     97  nsresult InitOutputPipe();
     98  nsresult InitInputPipe();
     99 
    100  uint64_t mSessionId{UINT64_MAX};
    101  WebTransportStreamType mStreamType{WebTransportStreamType::BiDi};
    102 
    103  enum StreamRole {
    104    INCOMING,
    105    OUTGOING,
    106  } mStreamRole{INCOMING};
    107 
    108  enum SendStreamState {
    109    WAITING_TO_ACTIVATE,
    110    WAITING_DATA,
    111    SENDING,
    112    SEND_DONE,
    113  } mSendState{WAITING_TO_ACTIVATE};
    114 
    115  enum RecvStreamState { BEFORE_READING, READING, RECEIVED_FIN, RECV_DONE };
    116  Atomic<RecvStreamState> mRecvState{BEFORE_READING};
    117 
    118  nsresult mSocketOutCondition = NS_ERROR_NOT_INITIALIZED;
    119  nsresult mSocketInCondition = NS_ERROR_NOT_INITIALIZED;
    120 
    121  std::function<void(Result<RefPtr<WebTransportStreamBase>, nsresult>&&)>
    122      mStreamReadyCallback;
    123 
    124  Mutex mMutex{"WebTransportStreamBase::mMutex"};
    125  nsCOMPtr<nsIAsyncInputStream> mSendStreamPipeIn;
    126  nsCOMPtr<nsIAsyncOutputStream> mSendStreamPipeOut MOZ_GUARDED_BY(mMutex);
    127 
    128  nsCOMPtr<nsIAsyncInputStream> mReceiveStreamPipeIn MOZ_GUARDED_BY(mMutex);
    129  nsCOMPtr<nsIAsyncOutputStream> mReceiveStreamPipeOut;
    130 };
    131 
    132 }  // namespace mozilla::net
    133 
    134 inline nsISupports* ToSupports(mozilla::net::WebTransportStreamBase* aStream) {
    135  return static_cast<nsIInputStreamCallback*>(aStream);
    136 }
    137 
    138 #endif  // mozilla_net_WebTransportStreamBase_h