/* * Copyright 2017 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. */ #include "webrtc/ortc/rtptransportadapter.h" #include // For std::find. #include #include #include // For std::move. #include "webrtc/api/proxy.h" #include "webrtc/rtc_base/logging.h" namespace webrtc { BEGIN_OWNED_PROXY_MAP(RtpTransport) PROXY_SIGNALING_THREAD_DESTRUCTOR() PROXY_CONSTMETHOD0(PacketTransportInterface*, GetRtpPacketTransport) PROXY_CONSTMETHOD0(PacketTransportInterface*, GetRtcpPacketTransport) PROXY_METHOD1(RTCError, SetRtcpParameters, const RtcpParameters&) PROXY_CONSTMETHOD0(RtcpParameters, GetRtcpParameters) protected: RtpTransportAdapter* GetInternal() override { return internal(); } END_PROXY_MAP() BEGIN_OWNED_PROXY_MAP(SrtpTransport) PROXY_SIGNALING_THREAD_DESTRUCTOR() PROXY_CONSTMETHOD0(PacketTransportInterface*, GetRtpPacketTransport) PROXY_CONSTMETHOD0(PacketTransportInterface*, GetRtcpPacketTransport) PROXY_METHOD1(RTCError, SetRtcpParameters, const RtcpParameters&) PROXY_CONSTMETHOD0(RtcpParameters, GetRtcpParameters) PROXY_METHOD1(RTCError, SetSrtpSendKey, const cricket::CryptoParams&) PROXY_METHOD1(RTCError, SetSrtpReceiveKey, const cricket::CryptoParams&) protected: RtpTransportAdapter* GetInternal() override { return internal(); } END_PROXY_MAP() // static RTCErrorOr> RtpTransportAdapter::CreateProxied( const RtcpParameters& rtcp_parameters, PacketTransportInterface* rtp, PacketTransportInterface* rtcp, RtpTransportControllerAdapter* rtp_transport_controller) { if (!rtp) { LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Must provide an RTP packet transport."); } if (!rtcp_parameters.mux && !rtcp) { LOG_AND_RETURN_ERROR( RTCErrorType::INVALID_PARAMETER, "Must provide an RTCP packet transport when RTCP muxing is not used."); } if (rtcp_parameters.mux && rtcp) { LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Creating an RtpTransport with RTCP muxing enabled, " "with a separate RTCP packet transport?"); } if (!rtp_transport_controller) { // Since OrtcFactory::CreateRtpTransport creates an RtpTransportController // automatically when one isn't passed in, this should never be reached. RTC_NOTREACHED(); LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Must provide an RTP transport controller."); } return RtpTransportProxyWithInternal::Create( rtp_transport_controller->signaling_thread(), rtp_transport_controller->worker_thread(), std::unique_ptr(new RtpTransportAdapter( rtcp_parameters, rtp, rtcp, rtp_transport_controller, /*is_srtp_transport*/ false))); } RTCErrorOr> RtpTransportAdapter::CreateSrtpProxied( const RtcpParameters& rtcp_parameters, PacketTransportInterface* rtp, PacketTransportInterface* rtcp, RtpTransportControllerAdapter* rtp_transport_controller) { if (!rtp) { LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Must provide an RTP packet transport."); } if (!rtcp_parameters.mux && !rtcp) { LOG_AND_RETURN_ERROR( RTCErrorType::INVALID_PARAMETER, "Must provide an RTCP packet transport when RTCP muxing is not used."); } if (rtcp_parameters.mux && rtcp) { LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Creating an RtpTransport with RTCP muxing enabled, " "with a separate RTCP packet transport?"); } if (!rtp_transport_controller) { // Since OrtcFactory::CreateRtpTransport creates an RtpTransportController // automatically when one isn't passed in, this should never be reached. RTC_NOTREACHED(); LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Must provide an RTP transport controller."); } return SrtpTransportProxyWithInternal::Create( rtp_transport_controller->signaling_thread(), rtp_transport_controller->worker_thread(), std::unique_ptr(new RtpTransportAdapter( rtcp_parameters, rtp, rtcp, rtp_transport_controller, /*is_srtp_transport*/ true))); } void RtpTransportAdapter::TakeOwnershipOfRtpTransportController( std::unique_ptr controller) { RTC_DCHECK_EQ(rtp_transport_controller_, controller->GetInternal()); RTC_DCHECK(owned_rtp_transport_controller_.get() == nullptr); owned_rtp_transport_controller_ = std::move(controller); } RtpTransportAdapter::RtpTransportAdapter( const RtcpParameters& rtcp_parameters, PacketTransportInterface* rtp, PacketTransportInterface* rtcp, RtpTransportControllerAdapter* rtp_transport_controller, bool is_srtp_transport) : rtp_packet_transport_(rtp), rtcp_packet_transport_(rtcp), rtp_transport_controller_(rtp_transport_controller), rtcp_parameters_(rtcp_parameters), is_srtp_transport_(is_srtp_transport) { RTC_DCHECK(rtp_transport_controller); // CNAME should have been filled by OrtcFactory if empty. RTC_DCHECK(!rtcp_parameters_.cname.empty()); } RtpTransportAdapter::~RtpTransportAdapter() { SignalDestroyed(this); } PacketTransportInterface* RtpTransportAdapter::GetRtpPacketTransport() const { return rtp_packet_transport_; } PacketTransportInterface* RtpTransportAdapter::GetRtcpPacketTransport() const { return rtcp_packet_transport_; } RTCError RtpTransportAdapter::SetRtcpParameters( const RtcpParameters& parameters) { if (!parameters.mux && rtcp_parameters_.mux) { LOG_AND_RETURN_ERROR(webrtc::RTCErrorType::INVALID_STATE, "Can't disable RTCP muxing after enabling."); } if (!parameters.cname.empty() && parameters.cname != rtcp_parameters_.cname) { LOG_AND_RETURN_ERROR(webrtc::RTCErrorType::UNSUPPORTED_OPERATION, "Changing the RTCP CNAME is currently unsupported."); } // If the CNAME is empty, use the existing one. RtcpParameters copy = parameters; if (copy.cname.empty()) { copy.cname = rtcp_parameters_.cname; } RTCError err = rtp_transport_controller_->SetRtcpParameters(copy, this); if (!err.ok()) { return err; } rtcp_parameters_ = copy; if (rtcp_parameters_.mux) { rtcp_packet_transport_ = nullptr; } return RTCError::OK(); } RTCError RtpTransportAdapter::SetSrtpSendKey( const cricket::CryptoParams& params) { if (send_key_) { LOG_AND_RETURN_ERROR( webrtc::RTCErrorType::UNSUPPORTED_OPERATION, "Setting the SRTP send key twice is currently unsupported."); } if (receive_key_ && receive_key_->cipher_suite != params.cipher_suite) { LOG_AND_RETURN_ERROR( webrtc::RTCErrorType::UNSUPPORTED_OPERATION, "The send key and receive key must have the same cipher suite."); } send_key_ = rtc::Optional(params); return RTCError::OK(); } RTCError RtpTransportAdapter::SetSrtpReceiveKey( const cricket::CryptoParams& params) { if (receive_key_) { LOG_AND_RETURN_ERROR( webrtc::RTCErrorType::UNSUPPORTED_OPERATION, "Setting the SRTP receive key twice is currently unsupported."); } if (send_key_ && send_key_->cipher_suite != params.cipher_suite) { LOG_AND_RETURN_ERROR( webrtc::RTCErrorType::UNSUPPORTED_OPERATION, "The send key and receive key must have the same cipher suite."); } receive_key_ = rtc::Optional(params); return RTCError::OK(); } } // namespace webrtc