blob: 0509cad2c8a13e0152ecedc0bfb08b2f6711ff95 [file] [log] [blame]
deadbeefe814a0d2017-02-25 18:15:09 -08001/*
2 * Copyright 2017 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "ortc/rtptransportadapter.h"
deadbeefe814a0d2017-02-25 18:15:09 -080012
13#include <algorithm> // For std::find.
14#include <set>
15#include <sstream>
16#include <utility> // For std::move.
17
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/proxy.h"
19#include "rtc_base/logging.h"
deadbeefe814a0d2017-02-25 18:15:09 -080020
21namespace webrtc {
22
23BEGIN_OWNED_PROXY_MAP(RtpTransport)
24PROXY_SIGNALING_THREAD_DESTRUCTOR()
25PROXY_CONSTMETHOD0(PacketTransportInterface*, GetRtpPacketTransport)
26PROXY_CONSTMETHOD0(PacketTransportInterface*, GetRtcpPacketTransport)
sprangdb2a9fc2017-08-09 06:42:32 -070027PROXY_METHOD1(RTCError, SetParameters, const RtpTransportParameters&)
28PROXY_CONSTMETHOD0(RtpTransportParameters, GetParameters)
deadbeefe814a0d2017-02-25 18:15:09 -080029protected:
30RtpTransportAdapter* GetInternal() override {
31 return internal();
32}
33END_PROXY_MAP()
34
zhihuangd3501ad2017-03-03 14:39:06 -080035BEGIN_OWNED_PROXY_MAP(SrtpTransport)
36PROXY_SIGNALING_THREAD_DESTRUCTOR()
37PROXY_CONSTMETHOD0(PacketTransportInterface*, GetRtpPacketTransport)
38PROXY_CONSTMETHOD0(PacketTransportInterface*, GetRtcpPacketTransport)
sprangdb2a9fc2017-08-09 06:42:32 -070039PROXY_METHOD1(RTCError, SetParameters, const RtpTransportParameters&)
40PROXY_CONSTMETHOD0(RtpTransportParameters, GetParameters)
zhihuangd3501ad2017-03-03 14:39:06 -080041PROXY_METHOD1(RTCError, SetSrtpSendKey, const cricket::CryptoParams&)
42PROXY_METHOD1(RTCError, SetSrtpReceiveKey, const cricket::CryptoParams&)
43protected:
44RtpTransportAdapter* GetInternal() override {
45 return internal();
46}
47END_PROXY_MAP()
48
deadbeefe814a0d2017-02-25 18:15:09 -080049// static
50RTCErrorOr<std::unique_ptr<RtpTransportInterface>>
51RtpTransportAdapter::CreateProxied(
sprangdb2a9fc2017-08-09 06:42:32 -070052 const RtpTransportParameters& parameters,
deadbeefe814a0d2017-02-25 18:15:09 -080053 PacketTransportInterface* rtp,
54 PacketTransportInterface* rtcp,
55 RtpTransportControllerAdapter* rtp_transport_controller) {
56 if (!rtp) {
57 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
58 "Must provide an RTP packet transport.");
59 }
sprangdb2a9fc2017-08-09 06:42:32 -070060 if (!parameters.rtcp.mux && !rtcp) {
deadbeefe814a0d2017-02-25 18:15:09 -080061 LOG_AND_RETURN_ERROR(
62 RTCErrorType::INVALID_PARAMETER,
63 "Must provide an RTCP packet transport when RTCP muxing is not used.");
64 }
sprangdb2a9fc2017-08-09 06:42:32 -070065 if (parameters.rtcp.mux && rtcp) {
deadbeefe814a0d2017-02-25 18:15:09 -080066 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
67 "Creating an RtpTransport with RTCP muxing enabled, "
68 "with a separate RTCP packet transport?");
69 }
70 if (!rtp_transport_controller) {
71 // Since OrtcFactory::CreateRtpTransport creates an RtpTransportController
72 // automatically when one isn't passed in, this should never be reached.
73 RTC_NOTREACHED();
74 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
75 "Must provide an RTP transport controller.");
76 }
sprangdb2a9fc2017-08-09 06:42:32 -070077 std::unique_ptr<RtpTransportAdapter> transport_adapter(
78 new RtpTransportAdapter(parameters.rtcp, rtp, rtcp,
79 rtp_transport_controller,
80 false /*is_srtp_transport*/));
81 RTCError params_result = transport_adapter->SetParameters(parameters);
82 if (!params_result.ok()) {
83 return std::move(params_result);
84 }
85
deadbeefe814a0d2017-02-25 18:15:09 -080086 return RtpTransportProxyWithInternal<RtpTransportAdapter>::Create(
87 rtp_transport_controller->signaling_thread(),
sprangdb2a9fc2017-08-09 06:42:32 -070088 rtp_transport_controller->worker_thread(), std::move(transport_adapter));
zhihuangd3501ad2017-03-03 14:39:06 -080089}
90
91RTCErrorOr<std::unique_ptr<SrtpTransportInterface>>
92RtpTransportAdapter::CreateSrtpProxied(
sprangdb2a9fc2017-08-09 06:42:32 -070093 const RtpTransportParameters& parameters,
zhihuangd3501ad2017-03-03 14:39:06 -080094 PacketTransportInterface* rtp,
95 PacketTransportInterface* rtcp,
96 RtpTransportControllerAdapter* rtp_transport_controller) {
97 if (!rtp) {
98 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
99 "Must provide an RTP packet transport.");
100 }
sprangdb2a9fc2017-08-09 06:42:32 -0700101 if (!parameters.rtcp.mux && !rtcp) {
zhihuangd3501ad2017-03-03 14:39:06 -0800102 LOG_AND_RETURN_ERROR(
103 RTCErrorType::INVALID_PARAMETER,
104 "Must provide an RTCP packet transport when RTCP muxing is not used.");
105 }
sprangdb2a9fc2017-08-09 06:42:32 -0700106 if (parameters.rtcp.mux && rtcp) {
zhihuangd3501ad2017-03-03 14:39:06 -0800107 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
108 "Creating an RtpTransport with RTCP muxing enabled, "
109 "with a separate RTCP packet transport?");
110 }
111 if (!rtp_transport_controller) {
112 // Since OrtcFactory::CreateRtpTransport creates an RtpTransportController
113 // automatically when one isn't passed in, this should never be reached.
114 RTC_NOTREACHED();
115 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
116 "Must provide an RTP transport controller.");
117 }
sprangdb2a9fc2017-08-09 06:42:32 -0700118 std::unique_ptr<RtpTransportAdapter> transport_adapter(
119 new RtpTransportAdapter(parameters.rtcp, rtp, rtcp,
120 rtp_transport_controller,
121 true /*is_srtp_transport*/));
122 RTCError params_result = transport_adapter->SetParameters(parameters);
123 if (!params_result.ok()) {
124 return std::move(params_result);
125 }
126
zhihuangd3501ad2017-03-03 14:39:06 -0800127 return SrtpTransportProxyWithInternal<RtpTransportAdapter>::Create(
128 rtp_transport_controller->signaling_thread(),
sprangdb2a9fc2017-08-09 06:42:32 -0700129 rtp_transport_controller->worker_thread(), std::move(transport_adapter));
deadbeefe814a0d2017-02-25 18:15:09 -0800130}
131
132void RtpTransportAdapter::TakeOwnershipOfRtpTransportController(
133 std::unique_ptr<RtpTransportControllerInterface> controller) {
134 RTC_DCHECK_EQ(rtp_transport_controller_, controller->GetInternal());
135 RTC_DCHECK(owned_rtp_transport_controller_.get() == nullptr);
136 owned_rtp_transport_controller_ = std::move(controller);
137}
138
139RtpTransportAdapter::RtpTransportAdapter(
sprangdb2a9fc2017-08-09 06:42:32 -0700140 const RtcpParameters& rtcp_params,
deadbeefe814a0d2017-02-25 18:15:09 -0800141 PacketTransportInterface* rtp,
142 PacketTransportInterface* rtcp,
zhihuangd3501ad2017-03-03 14:39:06 -0800143 RtpTransportControllerAdapter* rtp_transport_controller,
144 bool is_srtp_transport)
deadbeefe814a0d2017-02-25 18:15:09 -0800145 : rtp_packet_transport_(rtp),
146 rtcp_packet_transport_(rtcp),
147 rtp_transport_controller_(rtp_transport_controller),
zhihuangd3501ad2017-03-03 14:39:06 -0800148 is_srtp_transport_(is_srtp_transport) {
sprangdb2a9fc2017-08-09 06:42:32 -0700149 parameters_.rtcp = rtcp_params;
deadbeefe814a0d2017-02-25 18:15:09 -0800150 // CNAME should have been filled by OrtcFactory if empty.
sprangdb2a9fc2017-08-09 06:42:32 -0700151 RTC_DCHECK(!parameters_.rtcp.cname.empty());
152 RTC_DCHECK(rtp_transport_controller);
deadbeefe814a0d2017-02-25 18:15:09 -0800153}
154
155RtpTransportAdapter::~RtpTransportAdapter() {
156 SignalDestroyed(this);
157}
158
159PacketTransportInterface* RtpTransportAdapter::GetRtpPacketTransport() const {
160 return rtp_packet_transport_;
161}
162
163PacketTransportInterface* RtpTransportAdapter::GetRtcpPacketTransport() const {
164 return rtcp_packet_transport_;
165}
166
sprangdb2a9fc2017-08-09 06:42:32 -0700167RTCError RtpTransportAdapter::SetParameters(
168 const RtpTransportParameters& parameters) {
169 if (!parameters.rtcp.mux && parameters_.rtcp.mux) {
deadbeefe814a0d2017-02-25 18:15:09 -0800170 LOG_AND_RETURN_ERROR(webrtc::RTCErrorType::INVALID_STATE,
171 "Can't disable RTCP muxing after enabling.");
172 }
sprangdb2a9fc2017-08-09 06:42:32 -0700173 if (!parameters.rtcp.cname.empty() &&
174 parameters.rtcp.cname != parameters_.rtcp.cname) {
deadbeefe814a0d2017-02-25 18:15:09 -0800175 LOG_AND_RETURN_ERROR(webrtc::RTCErrorType::UNSUPPORTED_OPERATION,
176 "Changing the RTCP CNAME is currently unsupported.");
177 }
178 // If the CNAME is empty, use the existing one.
sprangdb2a9fc2017-08-09 06:42:32 -0700179 RtpTransportParameters copy = parameters;
180 if (copy.rtcp.cname.empty()) {
181 copy.rtcp.cname = parameters_.rtcp.cname;
deadbeefe814a0d2017-02-25 18:15:09 -0800182 }
sprangdb2a9fc2017-08-09 06:42:32 -0700183 RTCError err =
184 rtp_transport_controller_->SetRtpTransportParameters(copy, this);
deadbeefe814a0d2017-02-25 18:15:09 -0800185 if (!err.ok()) {
186 return err;
187 }
sprangdb2a9fc2017-08-09 06:42:32 -0700188 parameters_ = copy;
189 if (parameters_.rtcp.mux) {
deadbeefe814a0d2017-02-25 18:15:09 -0800190 rtcp_packet_transport_ = nullptr;
191 }
192 return RTCError::OK();
193}
194
zhihuangd3501ad2017-03-03 14:39:06 -0800195RTCError RtpTransportAdapter::SetSrtpSendKey(
196 const cricket::CryptoParams& params) {
197 if (send_key_) {
198 LOG_AND_RETURN_ERROR(
199 webrtc::RTCErrorType::UNSUPPORTED_OPERATION,
200 "Setting the SRTP send key twice is currently unsupported.");
201 }
202 if (receive_key_ && receive_key_->cipher_suite != params.cipher_suite) {
203 LOG_AND_RETURN_ERROR(
204 webrtc::RTCErrorType::UNSUPPORTED_OPERATION,
205 "The send key and receive key must have the same cipher suite.");
206 }
207 send_key_ = rtc::Optional<cricket::CryptoParams>(params);
208 return RTCError::OK();
209}
210
211RTCError RtpTransportAdapter::SetSrtpReceiveKey(
212 const cricket::CryptoParams& params) {
213 if (receive_key_) {
214 LOG_AND_RETURN_ERROR(
215 webrtc::RTCErrorType::UNSUPPORTED_OPERATION,
216 "Setting the SRTP receive key twice is currently unsupported.");
217 }
218 if (send_key_ && send_key_->cipher_suite != params.cipher_suite) {
219 LOG_AND_RETURN_ERROR(
220 webrtc::RTCErrorType::UNSUPPORTED_OPERATION,
221 "The send key and receive key must have the same cipher suite.");
222 }
223 receive_key_ = rtc::Optional<cricket::CryptoParams>(params);
224 return RTCError::OK();
225}
226
deadbeefe814a0d2017-02-25 18:15:09 -0800227} // namespace webrtc