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
|