/* 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