diff --git a/include/uvgrtp/media_stream.hh b/include/uvgrtp/media_stream.hh index 46af012..2b43936 100644 --- a/include/uvgrtp/media_stream.hh +++ b/include/uvgrtp/media_stream.hh @@ -94,24 +94,6 @@ namespace uvgrtp { * \retval RTP_NOT_SUPPORTED If user-managed SRTP was not specified in create_stream() */ rtp_error_t add_srtp_ctx(uint8_t *key, uint8_t *salt); - /** - * - * \brief Add keying information for user-managed SRTP session - * - * \details For user-managed SRTP session (flag RCE_SRTP_KMNGMNT_USER), - * the media stream is not started until SRTP key has been added and all calls - * to push_frame() will fail. - * - * \param key SRTP master key, default is 128-bit long - * \param salt 112-bit long salt - * - * \return RTP error code - * - * \retval RTP_OK On success - * \retval RTP_INVALID_VALUE If key or salt is invalid - * \retval RTP_NOT_SUPPORTED If user-managed SRTP was not specified in create_stream() */ - rtp_error_t add_zrtp_ctx(); - /** * \brief Send data to remote participant with a custom timestamp * @@ -372,8 +354,6 @@ namespace uvgrtp { */ uint32_t get_ssrc() const; - bool start_receiving(); - private: /* Initialize the connection by initializing the socket * and binding ourselves to specified interface and creating @@ -405,7 +385,6 @@ namespace uvgrtp { std::shared_ptr socket_; std::shared_ptr rtp_; std::shared_ptr rtcp_; - std::shared_ptr zrtp_; std::shared_ptr sfp_; diff --git a/src/media_stream.cc b/src/media_stream.cc index aa08258..842ed10 100644 --- a/src/media_stream.cc +++ b/src/media_stream.cc @@ -39,7 +39,6 @@ uvgrtp::media_stream::media_stream(std::string cname, std::string remote_addr, socket_(nullptr), rtp_(nullptr), rtcp_(nullptr), - zrtp_(nullptr), sfp_(sfp), remote_sockaddr_(), remote_sockaddr_ip6_(), @@ -301,13 +300,68 @@ rtp_error_t uvgrtp::media_stream::init() rtp_error_t uvgrtp::media_stream::init(std::shared_ptr zrtp) { - if (!zrtp) { - UVG_LOG_ERROR("No ZRTP found"); + if (init_connection() != RTP_OK) { + log_platform_error("Failed to initialize the underlying socket"); return RTP_GENERIC_ERROR; } - zrtp_ = zrtp; + if (!new_socket_) { + reception_flow_ = sfp_->get_reception_flow_ptr(socket_); + } + else { + reception_flow_ = sfp_->install_reception_flow(socket_); + } - return RTP_OK; + rtp_ = std::shared_ptr(new uvgrtp::rtp(fmt_, ssrc_, ipv6_)); + + bool perform_dh = !(rce_flags_ & RCE_ZRTP_MULTISTREAM_MODE); + if (!perform_dh) + { + UVG_LOG_DEBUG("Sleeping non-DH performing stream until DH has finished"); + std::chrono::system_clock::time_point tp = std::chrono::system_clock::now(); + + while (!zrtp->has_dh_finished()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + if (std::chrono::duration_cast(std::chrono::system_clock::now() - tp).count() > 10) + { + UVG_LOG_ERROR("Giving up on DH after 10 seconds"); + return free_resources(RTP_TIMEOUT); + } + } + } + + rtp_error_t ret = RTP_OK; + if ((ret = zrtp->init(rtp_->get_ssrc(), socket_, remote_sockaddr_, remote_sockaddr_ip6_, perform_dh, ipv6_)) != RTP_OK) { + UVG_LOG_WARN("Failed to initialize ZRTP for media stream!"); + return free_resources(ret); + } + + srtp_ = std::shared_ptr(new uvgrtp::srtp(rce_flags_)); + if ((ret = init_srtp_with_zrtp(rce_flags_, SRTP, srtp_, zrtp)) != RTP_OK) + return free_resources(ret); + + srtcp_ = std::shared_ptr(new uvgrtp::srtcp()); + if ((ret = init_srtp_with_zrtp(rce_flags_, SRTCP, srtcp_, zrtp)) != RTP_OK) + return free_resources(ret); + + zrtp->dh_has_finished(); // only after the DH stream has gotten its keys, do we let non-DH stream perform ZRTP + + rtcp_ = std::shared_ptr(new uvgrtp::rtcp(rtp_, ssrc_, remote_ssrc_, cname_, sfp_, srtcp_, rce_flags_)); + + socket_->install_handler(rtcp_.get(), rtcp_->send_packet_handler_vec); + socket_->install_handler(srtp_.get(), srtp_->send_packet_handler); + + rtp_handler_key_ = reception_flow_->install_handler(rtp_->packet_handler); + zrtp_handler_key_ = reception_flow_->install_handler(zrtp->packet_handler); + + reception_flow_->map_handler_key(rtp_handler_key_, remote_ssrc_); + reception_flow_->map_handler_key(zrtp_handler_key_, remote_ssrc_); + + reception_flow_->install_aux_handler(rtp_handler_key_, srtp_.get(), srtp_->recv_packet_handler, nullptr); + reception_flow_->install_aux_handler(rtp_handler_key_, rtcp_.get(), rtcp_->recv_packet_handler, nullptr); + + return start_components(); } rtp_error_t uvgrtp::media_stream::add_srtp_ctx(uint8_t *key, uint8_t *salt) @@ -365,78 +419,6 @@ rtp_error_t uvgrtp::media_stream::add_srtp_ctx(uint8_t *key, uint8_t *salt) return start_components(); } -rtp_error_t uvgrtp::media_stream::add_zrtp_ctx() -{ - if (!zrtp_) { - UVG_LOG_ERROR("No ZRTP found"); - return RTP_GENERIC_ERROR; - } - unsigned int srtp_rce_flags = RCE_SRTP | RCE_SRTP_KMNGMNT_ZRTP; - if ((rce_flags_ & srtp_rce_flags) != srtp_rce_flags) - return free_resources(RTP_NOT_SUPPORTED); - - if (init_connection() != RTP_OK) { - log_platform_error("Failed to initialize the underlying socket"); - return RTP_GENERIC_ERROR; - } - if (!new_socket_) { - reception_flow_ = sfp_->get_reception_flow_ptr(socket_); - } - else { - reception_flow_ = sfp_->install_reception_flow(socket_); - } - - rtp_ = std::shared_ptr(new uvgrtp::rtp(fmt_, ssrc_, ipv6_)); - - bool perform_dh = !(rce_flags_ & RCE_ZRTP_MULTISTREAM_MODE); - if (!perform_dh) - { - UVG_LOG_DEBUG("Sleeping non-DH performing stream until DH has finished"); - std::chrono::system_clock::time_point tp = std::chrono::system_clock::now(); - - while (!zrtp_->has_dh_finished()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - - if (std::chrono::duration_cast(std::chrono::system_clock::now() - tp).count() > 10) - { - UVG_LOG_ERROR("Giving up on DH after 10 seconds"); - return free_resources(RTP_TIMEOUT); - } - } - } - rtp_error_t ret = RTP_OK; - if ((ret = zrtp_->init(rtp_->get_ssrc(), socket_, remote_sockaddr_, remote_sockaddr_ip6_, perform_dh, ipv6_)) != RTP_OK) { - UVG_LOG_WARN("Failed to initialize ZRTP for media stream!"); - return free_resources(ret); - } - srtp_ = std::shared_ptr(new uvgrtp::srtp(rce_flags_)); - if ((ret = init_srtp_with_zrtp(rce_flags_, SRTP, srtp_, zrtp_)) != RTP_OK) - return free_resources(ret); - - srtcp_ = std::shared_ptr(new uvgrtp::srtcp()); - if ((ret = init_srtp_with_zrtp(rce_flags_, SRTCP, srtcp_, zrtp_)) != RTP_OK) - return free_resources(ret); - - UVG_LOG_DEBUG("DH negotiation finished!"); - - rtcp_ = std::shared_ptr(new uvgrtp::rtcp(rtp_, ssrc_, remote_ssrc_, cname_, sfp_, srtcp_, rce_flags_)); - - socket_->install_handler(srtp_.get(), srtp_->send_packet_handler); - socket_->install_handler(rtcp_.get(), rtcp_->send_packet_handler_vec); - - rtp_handler_key_ = reception_flow_->install_handler(rtp_->packet_handler); - zrtp_handler_key_ = reception_flow_->install_handler(zrtp_->packet_handler); - - reception_flow_->map_handler_key(rtp_handler_key_, remote_ssrc_); - reception_flow_->map_handler_key(zrtp_handler_key_, remote_ssrc_); - - reception_flow_->install_aux_handler(rtp_handler_key_, srtp_.get(), srtp_->recv_packet_handler, nullptr); - reception_flow_->install_aux_handler(rtp_handler_key_, rtcp_.get(), rtcp_->recv_packet_handler, nullptr); - - return start_components(); -} - rtp_error_t uvgrtp::media_stream::start_components() { if (create_media(fmt_) != RTP_OK) @@ -474,7 +456,10 @@ rtp_error_t uvgrtp::media_stream::start_components() } initialized_ = true; - UVG_LOG_DEBUG("Stream initialized"); + if (new_socket_) { + return reception_flow_->start(socket_, 0); + } + return RTP_OK; } @@ -850,13 +835,6 @@ uint32_t uvgrtp::media_stream::get_ssrc() const return *ssrc_.get(); } -bool uvgrtp::media_stream::start_receiving() -{ - if (new_socket_) { - return reception_flow_->start(socket_, 0); - } -} - rtp_error_t uvgrtp::media_stream::init_srtp_with_zrtp(int rce_flags, int type, std::shared_ptr srtp, std::shared_ptr zrtp) {