/* 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 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) override; int SendMessage(DataChannel& aChannel, OutgoingMsg&& aMsg) override; void OnSctpPacketReceived(const MediaPacket& packet) override; bool ResetStreams(nsTArray& 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& buffer, size_t* aWritten); void SendDeferredMessages(); static int OnThresholdEvent(struct socket* sock, uint32_t sb_free, void* ulp_info); int SendMsgInternalOrBuffer(nsTArray& 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); bool HasQueuedData(uint16_t aStream) const; // 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 mBufferedControl; // For partial DCEP messages (should be _really_ rare, since they're small) Maybe mRecvBuffer; // holds data that's come in before a channel is open nsTArray> 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_