File: WebTransportStreamBase.h

package info (click to toggle)
firefox 147.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,324 kB
  • sloc: cpp: 7,607,156; javascript: 6,532,492; ansic: 3,775,158; python: 1,415,368; xml: 634,556; asm: 438,949; java: 186,241; sh: 62,751; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (138 lines) | stat: -rw-r--r-- 4,483 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_net_WebTransportStreamBase_h
#define mozilla_net_WebTransportStreamBase_h

#include "nsISupportsImpl.h"
#include "mozilla/net/neqo_glue_ffi_generated.h"
#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h"
#include "nsCOMPtr.h"
#include "nsIAsyncInputStream.h"
#include "nsIAsyncOutputStream.h"

class nsIWebTransportSendStreamStats;
class nsIWebTransportReceiveStreamStats;

namespace mozilla::net {

// https://www.ietf.org/archive/id/draft-ietf-webtrans-http2-10.html#section-5.2-2
// Client initiated streams having even-numbered stream IDs and
// server-initiated streams having odd-numbered stream IDs. Similarly, they
// can be bidirectional or unidirectional, indicated by the second least
// significant bit of the stream ID.

class StreamId {
 public:
  constexpr explicit StreamId(uint64_t aId) : mId(aId) {}

  constexpr bool IsBiDi() const { return (mId & 0x02) == 0; }

  constexpr bool IsUni() const { return !IsBiDi(); }

  constexpr WebTransportStreamType StreamType() const {
    return IsBiDi() ? WebTransportStreamType::BiDi
                    : WebTransportStreamType::UniDi;
  }

  constexpr bool IsClientInitiated() const { return (mId & 0x01) == 0; }

  constexpr bool IsServerInitiated() const { return !IsClientInitiated(); }

  void Next() { mId += 4; }

  constexpr uint64_t Index() const { return mId >> 2; }

  constexpr bool operator==(const StreamId& aRhs) const {
    return mId == aRhs.mId;
  }

  static constexpr StreamId From(uint64_t aVal) { return StreamId(aVal); }

  constexpr operator uint64_t() const { return mId; }

 private:
  uint64_t mId = 0;
};

class SenderFlowControlBase;
class ReceiverFlowControlBase;

class WebTransportStreamBase : public nsIInputStreamCallback,
                               public nsIOutputStreamCallback {
 public:
  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING

  explicit WebTransportStreamBase(
      uint64_t aSessionId,
      std::function<void(Result<RefPtr<WebTransportStreamBase>, nsresult>&&)>&&
          aCallback);

  WebTransportStreamType StreamType() const { return mStreamType; }

  void GetWriterAndReader(nsIAsyncOutputStream** aOutOutputStream,
                          nsIAsyncInputStream** aOutInputStream);

  virtual StreamId WebTransportStreamId() const = 0;
  virtual uint64_t GetStreamId() const = 0;
  virtual void SendStopSending(uint8_t aErrorCode) = 0;
  virtual void SendFin() = 0;
  virtual void Reset(uint64_t aErrorCode) = 0;
  virtual already_AddRefed<nsIWebTransportSendStreamStats>
  GetSendStreamStats() = 0;
  virtual already_AddRefed<nsIWebTransportReceiveStreamStats>
  GetReceiveStreamStats() = 0;
  virtual bool RecvDone() const = 0;
  virtual void SetSendOrder(Maybe<int64_t> aSendOrder) = 0;
  // Used only for testing.
  virtual SenderFlowControlBase* SenderFc() { return nullptr; }
  virtual ReceiverFlowControlBase* ReceiverFc() { return nullptr; }

 protected:
  virtual ~WebTransportStreamBase();

  nsresult InitOutputPipe();
  nsresult InitInputPipe();

  uint64_t mSessionId{UINT64_MAX};
  WebTransportStreamType mStreamType{WebTransportStreamType::BiDi};

  enum StreamRole {
    INCOMING,
    OUTGOING,
  } mStreamRole{INCOMING};

  enum SendStreamState {
    WAITING_TO_ACTIVATE,
    WAITING_DATA,
    SENDING,
    SEND_DONE,
  } mSendState{WAITING_TO_ACTIVATE};

  enum RecvStreamState { BEFORE_READING, READING, RECEIVED_FIN, RECV_DONE };
  Atomic<RecvStreamState> mRecvState{BEFORE_READING};

  nsresult mSocketOutCondition = NS_ERROR_NOT_INITIALIZED;
  nsresult mSocketInCondition = NS_ERROR_NOT_INITIALIZED;

  std::function<void(Result<RefPtr<WebTransportStreamBase>, nsresult>&&)>
      mStreamReadyCallback;

  Mutex mMutex{"WebTransportStreamBase::mMutex"};
  nsCOMPtr<nsIAsyncInputStream> mSendStreamPipeIn;
  nsCOMPtr<nsIAsyncOutputStream> mSendStreamPipeOut MOZ_GUARDED_BY(mMutex);

  nsCOMPtr<nsIAsyncInputStream> mReceiveStreamPipeIn MOZ_GUARDED_BY(mMutex);
  nsCOMPtr<nsIAsyncOutputStream> mReceiveStreamPipeOut;
};

}  // namespace mozilla::net

inline nsISupports* ToSupports(mozilla::net::WebTransportStreamBase* aStream) {
  return static_cast<nsIInputStreamCallback*>(aStream);
}

#endif  // mozilla_net_WebTransportStreamBase_h