DataChannelUsrsctp.h (4851B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef NETWERK_SCTP_DATACHANNEL_DATACHANNELUSRSCTP_H_ 8 #define NETWERK_SCTP_DATACHANNEL_DATACHANNELUSRSCTP_H_ 9 10 #include "DataChannel.h" 11 12 extern "C" { 13 struct socket; 14 struct sctp_rcvinfo; 15 } 16 17 #ifndef EALREADY 18 # define EALREADY WSAEALREADY 19 #endif 20 21 namespace mozilla { 22 23 // for queuing incoming data messages before the Open or 24 // external negotiation is indicated to us 25 class QueuedDataMessage { 26 public: 27 QueuedDataMessage(uint16_t stream, uint32_t ppid, uint16_t messageId, 28 int flags, const uint8_t* data, uint32_t length) 29 : mStream(stream), 30 mPpid(ppid), 31 mMessageId(messageId), 32 mFlags(flags), 33 mData(data, length) {} 34 35 const uint16_t mStream; 36 const uint32_t mPpid; 37 const uint16_t mMessageId; 38 const int mFlags; 39 const nsTArray<uint8_t> mData; 40 }; 41 42 class DataChannelConnectionUsrsctp : public DataChannelConnection { 43 virtual ~DataChannelConnectionUsrsctp(); 44 45 public: 46 DataChannelConnectionUsrsctp(DataConnectionListener* aListener, 47 nsISerialEventTarget* aTarget, 48 MediaTransportHandler* aHandler); 49 void Destroy() override; 50 bool RaiseStreamLimitTo(uint16_t aNewLimit) override; 51 void OnTransportReady() override; 52 bool Init(const uint16_t aLocalPort, const uint16_t aNumStreams) override; 53 int SendMessage(DataChannel& aChannel, OutgoingMsg&& aMsg) override; 54 void OnSctpPacketReceived(const MediaPacket& packet) override; 55 bool ResetStreams(nsTArray<uint16_t>& aStreams) override; 56 void OnStreamOpen(uint16_t stream) override; 57 58 // Called on data reception from the SCTP library 59 // must(?) be public so my c->c++ trampoline can call it 60 // May be called with (STS thread) or without the lock 61 int ReceiveCallback(struct socket* sock, void* data, size_t datalen, 62 struct sctp_rcvinfo rcv, int flags); 63 int SendSctpPacket(const uint8_t* buffer, size_t length); 64 65 private: 66 void HandleAssociationChangeEvent(const struct sctp_assoc_change* sac); 67 void HandlePeerAddressChangeEvent(const struct sctp_paddr_change* spc); 68 void HandleRemoteErrorEvent(const struct sctp_remote_error* sre); 69 void HandleShutdownEvent(const struct sctp_shutdown_event* sse); 70 void HandleAdaptationIndication(const struct sctp_adaptation_event* sai); 71 void HandlePartialDeliveryEvent(const struct sctp_pdapi_event* spde); 72 void HandleSendFailedEvent(const struct sctp_send_failed_event* ssfe); 73 void HandleStreamResetEvent(const struct sctp_stream_reset_event* strrst); 74 void HandleStreamChangeEvent(const struct sctp_stream_change_event* strchg); 75 void HandleNotification(const union sctp_notification* notif, size_t n); 76 int SendMsgInternal(OutgoingMsg& msg, size_t* aWritten); 77 bool SendBufferedMessages(nsTArray<OutgoingMsg>& buffer, size_t* aWritten); 78 void SendDeferredMessages(); 79 static int OnThresholdEvent(struct socket* sock, uint32_t sb_free, 80 void* ulp_info); 81 int SendMsgInternalOrBuffer(nsTArray<OutgoingMsg>& buffer, OutgoingMsg&& msg, 82 bool* aBuffered, size_t* aWritten); 83 uint32_t UpdateCurrentStreamIndex(); 84 uint32_t GetCurrentStreamIndex(); 85 // Finish Destroy on STS to avoid SCTP race condition with ABORT from far end 86 void DestroyOnSTS(); 87 void HandleMessageChunk(const void* buffer, size_t length, uint32_t ppid, 88 uint16_t messageId, uint16_t stream, int flags); 89 void HandleDataMessageChunk(const void* data, size_t length, uint32_t ppid, 90 uint16_t stream, uint16_t messageId, int flags); 91 void HandleDCEPMessageChunk(const void* buffer, size_t length, uint32_t ppid, 92 uint16_t stream, int flags); 93 bool HasQueuedData(uint16_t aStream) const; 94 95 // All STS only 96 bool mSendInterleaved = false; 97 // Keeps track of whose turn it is in the round robin 98 uint32_t mCurrentStream = 0; 99 PendingType mPendingType = PendingType::None; 100 // holds outgoing control messages if usrsctp is not ready to send them 101 nsTArray<OutgoingMsg> mBufferedControl; 102 // For partial DCEP messages (should be _really_ rare, since they're small) 103 Maybe<IncomingMsg> mRecvBuffer; 104 // holds data that's come in before a channel is open 105 nsTArray<UniquePtr<QueuedDataMessage>> mQueuedData; 106 // accessed from STS thread 107 // Set once on main in Init, STS-only thereafter 108 struct socket* mSocket = nullptr; 109 bool mSctpConfigured = false; 110 }; 111 112 } // namespace mozilla 113 114 #endif // NETWERK_SCTP_DATACHANNEL_DATACHANNELUSRSCTP_H_