Index: webrtc/media/sctp/sctptransport.h |
diff --git a/webrtc/media/sctp/sctptransport.h b/webrtc/media/sctp/sctptransport.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6d3a41a8f16092be6b9e0b9179821b286b4fd944 |
--- /dev/null |
+++ b/webrtc/media/sctp/sctptransport.h |
@@ -0,0 +1,193 @@ |
+/* |
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
+ * |
+ * Use of this source code is governed by a BSD-style license |
+ * that can be found in the LICENSE file in the root of the source |
+ * tree. An additional intellectual property rights grant can be found |
+ * in the file PATENTS. All contributing project authors may |
+ * be found in the AUTHORS file in the root of the source tree. |
+ */ |
+ |
+#ifndef WEBRTC_MEDIA_SCTP_SCTPTRANSPORT_H_ |
+#define WEBRTC_MEDIA_SCTP_SCTPTRANSPORT_H_ |
+ |
+#include <errno.h> |
+ |
+#include <memory> // for unique_ptr. |
+#include <set> |
+#include <string> |
+#include <vector> |
+ |
+#include "webrtc/base/asyncinvoker.h" |
+#include "webrtc/base/constructormagic.h" |
+#include "webrtc/base/copyonwritebuffer.h" |
+#include "webrtc/base/sigslot.h" |
+#include "webrtc/base/thread.h" |
+// For SendDataParams/ReceiveDataParams. |
+#include "webrtc/media/base/mediachannel.h" |
+#include "webrtc/media/sctp/sctptransportinternal.h" |
+#include "webrtc/p2p/base/transportchannel.h" |
+ |
+// Defined by "usrsctplib/usrsctp.h" |
+struct sockaddr_conn; |
+struct sctp_assoc_change; |
+struct sctp_stream_reset_event; |
+// Defined by <sys/socket.h> |
+struct socket; |
+namespace cricket { |
+ |
+// Holds data to be passed on to a channel. |
+struct SctpInboundPacket; |
+ |
+// From channel calls, data flows like this: |
+// [network thread (although it can in princple be another thread)] |
+// 1. SctpTransport::SendData(data) |
+// 2. usrsctp_sendv(data) |
+// [network thread returns; sctp thread then calls the following] |
+// 3. OnSctpOutboundPacket(wrapped_data) |
+// [sctp thread returns having async invoked on the network thread] |
+// 4. SctpTransport::OnPacketFromSctpToNetwork(wrapped_data) |
+// 5. TransportChannel::SendPacket(wrapped_data) |
+// 6. ... across network ... a packet is sent back ... |
+// 7. SctpTransport::OnPacketReceived(wrapped_data) |
+// 8. usrsctp_conninput(wrapped_data) |
+// [network thread returns; sctp thread then calls the following] |
+// 9. OnSctpInboundData(data) |
+// [sctp thread returns having async invoked on the network thread] |
+// 10. SctpTransport::OnInboundPacketFromSctpToChannel(inboundpacket) |
+// 11. SctpTransport::OnDataFromSctpToChannel(data) |
+// 12. SctpTransport::SignalDataReceived(data) |
+// [from the same thread, methods registered/connected to |
+// SctpTransport are called with the recieved data] |
+class SctpTransport : public SctpTransportInternal, |
+ public sigslot::has_slots<> { |
+ public: |
+ // |network_thread| is where packets will be processed and callbacks from |
+ // this transport will be posted, and is the only thread on which public |
+ // methods can be called. |
+ // |channel| is required (must not be null). |
+ SctpTransport(rtc::Thread* network_thread, |
+ cricket::TransportChannel* channel); |
+ ~SctpTransport() override; |
+ |
+ // SctpTransportInternal overrides (see sctptransportinternal.h for comments). |
+ void SetTransportChannel(cricket::TransportChannel* channel) override; |
+ bool Start(int local_port, int remote_port) override; |
+ bool OpenStream(int sid) override; |
+ bool ResetStream(int sid) override; |
+ bool SendData(const SendDataParams& params, |
+ const rtc::CopyOnWriteBuffer& payload, |
+ SendDataResult* result = nullptr) override; |
+ bool ReadyToSendData() override; |
+ void set_debug_name_for_testing(const char* debug_name) override { |
+ debug_name_ = debug_name; |
+ } |
+ |
+ // Exposed to allow Post call from c-callbacks. |
+ // TODO(deadbeef): Remove this or at least make it return a const pointer. |
+ rtc::Thread* network_thread() const { return network_thread_; } |
+ |
+ private: |
+ void ConnectTransportChannelSignals(); |
+ void DisconnectTransportChannelSignals(); |
+ |
+ // Creates the socket and connects. |
+ bool Connect(); |
+ |
+ // Returns false when opening the socket failed. |
+ bool OpenSctpSocket(); |
+ // Helpet method to set socket options. |
+ bool ConfigureSctpSocket(); |
+ // Sets |sock_ |to nullptr. |
+ void CloseSctpSocket(); |
+ |
+ // Sends a SCTP_RESET_STREAM for all streams in closing_ssids_. |
+ bool SendQueuedStreamResets(); |
+ |
+ // Sets the "ready to send" flag and fires signal if needed. |
+ void SetReadyToSendData(); |
+ |
+ // Callbacks from DTLS channel. |
+ void OnWritableState(rtc::PacketTransportInterface* transport); |
+ virtual void OnPacketRead(rtc::PacketTransportInterface* transport, |
+ const char* data, |
+ size_t len, |
+ const rtc::PacketTime& packet_time, |
+ int flags); |
+ |
+ // Methods related to usrsctp callbacks. |
+ void OnSendThresholdCallback(); |
+ sockaddr_conn GetSctpSockAddr(int port); |
+ |
+ // Called using |invoker_| to send packet on the network. |
+ void OnPacketFromSctpToNetwork(const rtc::CopyOnWriteBuffer& buffer); |
+ // Called using |invoker_| to decide what to do with the packet. |
+ // The |flags| parameter is used by SCTP to distinguish notification packets |
+ // from other types of packets. |
+ void OnInboundPacketFromSctpToChannel(const rtc::CopyOnWriteBuffer& buffer, |
+ ReceiveDataParams params, |
+ int flags); |
+ void OnDataFromSctpToChannel(const ReceiveDataParams& params, |
+ const rtc::CopyOnWriteBuffer& buffer); |
+ void OnNotificationFromSctp(const rtc::CopyOnWriteBuffer& buffer); |
+ void OnNotificationAssocChange(const sctp_assoc_change& change); |
+ |
+ void OnStreamResetEvent(const struct sctp_stream_reset_event* evt); |
+ |
+ // Responsible for marshalling incoming data to the channels listeners, and |
+ // outgoing data to the network interface. |
+ rtc::Thread* network_thread_; |
+ // Helps pass inbound/outbound packets asynchronously to the network thread. |
+ rtc::AsyncInvoker invoker_; |
+ // Underlying DTLS channel. |
+ TransportChannel* transport_channel_; |
+ bool was_ever_writable_ = false; |
+ int local_port_ = kSctpDefaultPort; |
+ int remote_port_ = kSctpDefaultPort; |
+ struct socket* sock_ = nullptr; // The socket created by usrsctp_socket(...). |
+ |
+ // Has Start been called? Don't create SCTP socket until it has. |
+ bool started_ = false; |
+ // Are we ready to queue data (SCTP socket created, and not blocked due to |
+ // congestion control)? Different than |transport_channel_|'s "ready to |
+ // send". |
+ bool ready_to_send_data_ = false; |
+ |
+ typedef std::set<uint32_t> StreamSet; |
+ // When a data channel opens a stream, it goes into open_streams_. When we |
+ // want to close it, the stream's ID goes into queued_reset_streams_. When |
+ // we actually transmit a RE-CONFIG chunk with that stream ID, the ID goes |
+ // into sent_reset_streams_. When we get a response RE-CONFIG chunk back |
+ // acknowledging the reset, we remove the stream ID from |
+ // sent_reset_streams_. We use sent_reset_streams_ to differentiate |
+ // between acknowledgment RE-CONFIG and peer-initiated RE-CONFIGs. |
+ StreamSet open_streams_; |
+ StreamSet queued_reset_streams_; |
+ StreamSet sent_reset_streams_; |
+ |
+ // A static human-readable name for debugging messages. |
+ const char* debug_name_ = "SctpTransport"; |
+ // Hides usrsctp interactions from this header file. |
+ class UsrSctpWrapper; |
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(SctpTransport); |
+}; |
+ |
+class SctpTransportFactory : public SctpTransportInternalFactory { |
+ public: |
+ explicit SctpTransportFactory(rtc::Thread* network_thread) |
+ : network_thread_(network_thread) {} |
+ |
+ std::unique_ptr<SctpTransportInternal> CreateSctpTransport( |
+ TransportChannel* channel) override { |
+ return std::unique_ptr<SctpTransportInternal>( |
+ new SctpTransport(network_thread_, channel)); |
+ } |
+ |
+ private: |
+ rtc::Thread* network_thread_; |
+}; |
+ |
+} // namespace cricket |
+ |
+#endif // WEBRTC_MEDIA_SCTP_SCTPTRANSPORT_H_ |