Source code

Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 NETWERK_SCTP_DATACHANNEL_DATACHANNELUSRSCTP_H_
#define NETWERK_SCTP_DATACHANNEL_DATACHANNELUSRSCTP_H_
#include "DataChannel.h"
extern "C" {
struct socket;
struct sctp_rcvinfo;
}
#ifndef EALREADY
# define EALREADY WSAEALREADY
#endif
namespace mozilla {
// for queuing incoming data messages before the Open or
// external negotiation is indicated to us
class QueuedDataMessage {
public:
QueuedDataMessage(uint16_t stream, uint32_t ppid, uint16_t messageId,
int flags, const uint8_t* data, uint32_t length)
: mStream(stream),
mPpid(ppid),
mMessageId(messageId),
mFlags(flags),
mData(data, length) {}
const uint16_t mStream;
const uint32_t mPpid;
const uint16_t mMessageId;
const int mFlags;
const nsTArray<uint8_t> mData;
};
class DataChannelConnectionUsrsctp : public DataChannelConnection {
virtual ~DataChannelConnectionUsrsctp();
public:
DataChannelConnectionUsrsctp(DataConnectionListener* aListener,
nsISerialEventTarget* aTarget,
MediaTransportHandler* aHandler);
void Destroy() override;
bool RaiseStreamLimitTo(uint16_t aNewLimit) override;
void OnTransportReady() override;
bool Init(const uint16_t aLocalPort, const uint16_t aNumStreams,
const Maybe<uint64_t>& aMaxMessageSize) override;
int SendMessage(DataChannel& aChannel, OutgoingMsg&& aMsg) override;
void OnSctpPacketReceived(const MediaPacket& packet) override;
void ResetStreams(nsTArray<uint16_t>& aStreams) override;
void OnStreamOpen(uint16_t stream) override;
// Called on data reception from the SCTP library
// must(?) be public so my c->c++ trampoline can call it
// May be called with (STS thread) or without the lock
int ReceiveCallback(struct socket* sock, void* data, size_t datalen,
struct sctp_rcvinfo rcv, int flags);
int SendSctpPacket(const uint8_t* buffer, size_t length);
private:
void HandleAssociationChangeEvent(const struct sctp_assoc_change* sac);
void HandlePeerAddressChangeEvent(const struct sctp_paddr_change* spc);
void HandleRemoteErrorEvent(const struct sctp_remote_error* sre);
void HandleShutdownEvent(const struct sctp_shutdown_event* sse);
void HandleAdaptationIndication(const struct sctp_adaptation_event* sai);
void HandlePartialDeliveryEvent(const struct sctp_pdapi_event* spde);
void HandleSendFailedEvent(const struct sctp_send_failed_event* ssfe);
void HandleStreamResetEvent(const struct sctp_stream_reset_event* strrst);
void HandleStreamChangeEvent(const struct sctp_stream_change_event* strchg);
void HandleNotification(const union sctp_notification* notif, size_t n);
int SendMsgInternal(OutgoingMsg& msg, size_t* aWritten);
bool SendBufferedMessages(nsTArray<OutgoingMsg>& buffer, size_t* aWritten);
void SendDeferredMessages();
static int OnThresholdEvent(struct socket* sock, uint32_t sb_free,
void* ulp_info);
int SendMsgInternalOrBuffer(nsTArray<OutgoingMsg>& buffer, OutgoingMsg&& msg,
bool* aBuffered, size_t* aWritten);
uint32_t UpdateCurrentStreamIndex();
uint32_t GetCurrentStreamIndex();
// Finish Destroy on STS to avoid SCTP race condition with ABORT from far end
void DestroyOnSTS();
void HandleMessageChunk(const void* buffer, size_t length, uint32_t ppid,
uint16_t messageId, uint16_t stream, int flags);
void HandleDataMessageChunk(const void* data, size_t length, uint32_t ppid,
uint16_t stream, uint16_t messageId, int flags);
void HandleDCEPMessageChunk(const void* buffer, size_t length, uint32_t ppid,
uint16_t stream, int flags);
// All STS only
bool mSendInterleaved = false;
// Keeps track of whose turn it is in the round robin
uint32_t mCurrentStream = 0;
PendingType mPendingType = PendingType::None;
// holds outgoing control messages if usrsctp is not ready to send them
nsTArray<OutgoingMsg> mBufferedControl;
// holds data that's come in before a channel is open
nsTArray<UniquePtr<QueuedDataMessage>> mQueuedData;
// accessed from STS thread
// Set once on main in Init, STS-only thereafter
struct socket* mSocket = nullptr;
bool mSctpConfigured = false;
};
} // namespace mozilla
#endif // NETWERK_SCTP_DATACHANNEL_DATACHANNELUSRSCTP_H_