1 /*
2  *  Copyright 2019 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef PC_DATAGRAM_RTP_TRANSPORT_H_
12 #define PC_DATAGRAM_RTP_TRANSPORT_H_
13 
14 #include <map>
15 #include <memory>
16 #include <string>
17 #include <vector>
18 
19 #include "api/crypto/crypto_options.h"
20 #include "api/transport/datagram_transport_interface.h"
21 #include "api/transport/media/media_transport_interface.h"
22 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
23 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
24 #include "p2p/base/ice_transport_internal.h"
25 #include "p2p/base/packet_transport_internal.h"
26 #include "pc/rtp_transport_internal.h"
27 #include "rtc_base/buffer.h"
28 #include "rtc_base/buffer_queue.h"
29 #include "rtc_base/constructor_magic.h"
30 #include "rtc_base/ssl_stream_adapter.h"
31 #include "rtc_base/stream.h"
32 #include "rtc_base/strings/string_builder.h"
33 #include "rtc_base/thread_checker.h"
34 
35 namespace webrtc {
36 
37 constexpr int kDatagramDtlsAdaptorComponent = -1;
38 
39 // RTP transport which uses the DatagramTransportInterface to send and receive
40 // packets.
41 class DatagramRtpTransport : public RtpTransportInternal,
42                              public webrtc::DatagramSinkInterface,
43                              public webrtc::MediaTransportStateCallback {
44  public:
45   DatagramRtpTransport(
46       const std::vector<webrtc::RtpExtension>& rtp_header_extensions,
47       cricket::IceTransportInternal* ice_transport,
48       DatagramTransportInterface* datagram_transport);
49 
50   ~DatagramRtpTransport() override;
51 
52   // =====================================================
53   // Overrides for webrtc::DatagramTransportSinkInterface
54   // and MediaTransportStateCallback
55   // =====================================================
56   void OnDatagramReceived(rtc::ArrayView<const uint8_t> data) override;
57 
58   void OnDatagramSent(webrtc::DatagramId datagram_id) override;
59 
60   void OnDatagramAcked(const webrtc::DatagramAck& ack) override;
61 
62   void OnDatagramLost(webrtc::DatagramId datagram_id) override;
63 
64   void OnStateChanged(webrtc::MediaTransportState state) override;
65 
66   // =====================================================
67   // RtpTransportInternal overrides
68   // =====================================================
69   bool SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
70                      const rtc::PacketOptions& options,
71                      int flags) override;
72 
73   bool SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
74                       const rtc::PacketOptions& options,
75                       int flags) override;
76 
77   const std::string& transport_name() const override;
78 
79   // Datagram transport always muxes RTCP.
rtcp_mux_enabled()80   bool rtcp_mux_enabled() const override { return true; }
SetRtcpMuxEnabled(bool enable)81   void SetRtcpMuxEnabled(bool enable) override {}
82 
83   int SetRtpOption(rtc::Socket::Option opt, int value) override;
84   int SetRtcpOption(rtc::Socket::Option opt, int value) override;
85 
86   bool IsReadyToSend() const override;
87 
88   bool IsWritable(bool rtcp) const override;
89 
IsSrtpActive()90   bool IsSrtpActive() const override { return false; }
91 
92   void UpdateRtpHeaderExtensionMap(
93       const cricket::RtpHeaderExtensions& header_extensions) override;
94 
95   bool RegisterRtpDemuxerSink(const RtpDemuxerCriteria& criteria,
96                               RtpPacketSinkInterface* sink) override;
97 
98   bool UnregisterRtpDemuxerSink(RtpPacketSinkInterface* sink) override;
99 
100  private:
101   // RTP/RTCP packet info stored for each sent packet.
102   struct SentPacketInfo {
103     // RTP packet info with ssrc and transport sequence number.
SentPacketInfoSentPacketInfo104     SentPacketInfo(int64_t packet_id,
105                    uint32_t ssrc,
106                    uint16_t transport_sequence_number)
107         : ssrc(ssrc),
108           transport_sequence_number(transport_sequence_number),
109           packet_id(packet_id) {}
110 
111     // Packet info without SSRC and transport sequence number used for RTCP
112     // packets, RTP packets when transport sequence number is not provided or
113     // when feedback translation is disabled.
SentPacketInfoSentPacketInfo114     explicit SentPacketInfo(int64_t packet_id) : packet_id(packet_id) {}
115 
116     SentPacketInfo() = default;
117 
118     absl::optional<uint32_t> ssrc;
119 
120     // Transport sequence number (if it was provided in outgoing RTP packet).
121     // It is used to re-create RTCP feedback packets from datagram ACKs.
122     absl::optional<uint16_t> transport_sequence_number;
123 
124     // Packet id from rtc::PacketOptions. It is required to propagage sent
125     // notification up the stack (SignalSentPacket).
126     int64_t packet_id = 0;
127   };
128 
129   // Finds SentPacketInfo for given |datagram_id| and removes map entry.
130   // Returns false if entry was not found.
131   bool GetAndRemoveSentPacketInfo(webrtc::DatagramId datagram_id,
132                                   SentPacketInfo* sent_packet_info);
133 
134   // Sends datagram to datagram_transport.
135   bool SendDatagram(rtc::ArrayView<const uint8_t> data,
136                     webrtc::DatagramId datagram_id);
137 
138   // Propagates network route changes from ICE.
139   void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route);
140 
141   rtc::ThreadChecker thread_checker_;
142   cricket::IceTransportInternal* ice_transport_;
143   webrtc::DatagramTransportInterface* datagram_transport_;
144 
145   RtpDemuxer rtp_demuxer_;
146 
147   MediaTransportState state_ = MediaTransportState::kPending;
148 
149   // Extension map for parsing transport sequence numbers.
150   webrtc::RtpHeaderExtensionMap rtp_header_extension_map_;
151 
152   // Keeps information about sent RTP packet until they are Acked or Lost.
153   std::map<webrtc::DatagramId, SentPacketInfo> sent_rtp_packet_map_;
154 
155   // Current datagram_id, incremented after each sent RTP packets.
156   // Datagram id is passed to datagram transport when we send datagram and we
157   // get it back in notifications about Sent, Acked and Lost datagrams.
158   int64_t current_datagram_id_ = 0;
159 
160   // TODO(sukhanov): Previous nonzero timestamp is required for workaround for
161   // zero timestamps received, which sometimes are received from datagram
162   // transport. Investigate if we can eliminate zero timestamps.
163   int64_t previous_nonzero_timestamp_us_ = 0;
164 
165   // Disable datagram to RTCP feedback translation and enable RTCP feedback
166   // loop (note that having both RTCP and datagram feedback loops is
167   // inefficient, but can be useful in tests and experiments).
168   const bool disable_datagram_to_rtcp_feeback_translation_;
169 };
170 
171 }  // namespace webrtc
172 
173 #endif  // PC_DATAGRAM_RTP_TRANSPORT_H_
174