From 42370aa3121982b274b89a316131ad2e521a193d Mon Sep 17 00:00:00 2001 From: cqm Date: Thu, 2 Mar 2023 11:54:22 +0800 Subject: [PATCH] fixed ice candidate error --- webrtc/IceServer.cpp | 26 +++++++++------ webrtc/IceServer.hpp | 7 ++-- webrtc/WebRtcSession.cpp | 6 ++-- webrtc/WebRtcTransport.cpp | 65 ++++++++++++++++++++++++-------------- webrtc/WebRtcTransport.h | 5 +-- 5 files changed, 69 insertions(+), 40 deletions(-) diff --git a/webrtc/IceServer.cpp b/webrtc/IceServer.cpp index 48709ab2..6b76b549 100644 --- a/webrtc/IceServer.cpp +++ b/webrtc/IceServer.cpp @@ -26,6 +26,10 @@ namespace RTC { /* Static. */ /* Instance methods. */ + bool isSameTuple(const TransportTuple* tuple1, const TransportTuple* tuple2) { + return tuple1 == tuple2; + // return memcmp(tuple1, tuple2, sizeof(RTC::TransportTuple)) == 0); + } IceServer::IceServer(Listener* listener, const std::string& usernameFragment, const std::string& password) : listener(listener), usernameFragment(usernameFragment), password(password) @@ -198,8 +202,12 @@ namespace RTC // Create a success response. RTC::StunPacket* response = packet->CreateSuccessResponse(); + sockaddr_storage peerAddr; + socklen_t addr_len = sizeof(peerAddr); + getpeername(tuple->getSock()->rawFD(), (struct sockaddr *)&peerAddr, &addr_len); + // Add XOR-MAPPED-ADDRESS. - response->SetXorMappedAddress(tuple); + response->SetXorMappedAddress((struct sockaddr *)&peerAddr); // Authenticate the response. if (this->oldPassword.empty()) @@ -260,9 +268,9 @@ namespace RTC for (; it != this->tuples.end(); ++it) { - RTC::TransportTuple* storedTuple = std::addressof(*it); + RTC::TransportTuple* storedTuple = *it; - if (memcmp(storedTuple, tuple, sizeof (RTC::TransportTuple)) == 0) + if (isSameTuple(storedTuple,tuple)) { removedTuple = storedTuple; @@ -287,7 +295,7 @@ namespace RTC // Mark the first tuple as selected tuple (if any). if (this->tuples.begin() != this->tuples.end()) { - SetSelectedTuple(std::addressof(*this->tuples.begin())); + SetSelectedTuple(*this->tuples.begin()); } // Or just emit 'disconnected'. else @@ -477,9 +485,9 @@ namespace RTC MS_TRACE(); // Add the new tuple at the beginning of the list. - this->tuples.push_front(*tuple); + this->tuples.push_front(tuple); - auto* storedTuple = std::addressof(*this->tuples.begin()); + auto* storedTuple = tuple; //std::addressof(*this->tuples.begin()); // Return the address of the inserted tuple. return storedTuple; @@ -495,15 +503,15 @@ namespace RTC return nullptr; // Check the current selected tuple. - if (memcmp(selectedTuple, tuple, sizeof (RTC::TransportTuple)) == 0) + if (isSameTuple(selectedTuple, tuple)) return this->selectedTuple; // Otherwise check other stored tuples. for (const auto& it : this->tuples) { - auto* storedTuple = const_cast(std::addressof(it)); + auto* storedTuple = const_cast(it); - if (memcmp(storedTuple, tuple, sizeof (RTC::TransportTuple)) == 0) + if (isSameTuple(storedTuple, tuple)) return storedTuple; } diff --git a/webrtc/IceServer.hpp b/webrtc/IceServer.hpp index 8b9742ad..b5c1e1b7 100644 --- a/webrtc/IceServer.hpp +++ b/webrtc/IceServer.hpp @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define MS_RTC_ICE_SERVER_HPP #include "StunPacket.hpp" +#include "Network/Session.h" #include "logger.h" #include "Utils.hpp" #include @@ -27,11 +28,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -using _TransportTuple = struct sockaddr; +//using _TransportTuple = struct sockaddr; namespace RTC { - using TransportTuple = _TransportTuple; + using TransportTuple = toolkit::Session; class IceServer { public: @@ -125,7 +126,7 @@ namespace RTC std::string oldUsernameFragment; std::string oldPassword; IceState state{ IceState::NEW }; - std::list tuples; + std::list tuples; RTC::TransportTuple* selectedTuple{ nullptr }; //最大不超过mtu static constexpr size_t StunSerializeBufferSize{ 1600 }; diff --git a/webrtc/WebRtcSession.cpp b/webrtc/WebRtcSession.cpp index c797ddb0..e51c7eae 100644 --- a/webrtc/WebRtcSession.cpp +++ b/webrtc/WebRtcSession.cpp @@ -94,7 +94,7 @@ void WebRtcSession::onRecv_l(const char *data, size_t len) { } _ticker.resetTime(); CHECK(_transport); - _transport->inputSockData((char *)data, len, (struct sockaddr *)&_peer_addr); + _transport->inputSockData((char *)data, len, this);// (struct sockaddr *)&_peer_addr); } void WebRtcSession::onRecv(const Buffer::Ptr &buffer) { @@ -114,9 +114,11 @@ void WebRtcSession::onError(const SockException &err) { if (!_transport) { return; } + auto self = shared_from_this(); auto transport = std::move(_transport); - getPoller()->async([transport] { + getPoller()->async([transport, self] { //延时减引用,防止使用transport对象时,销毁对象 + transport->RemoveTuple(self.get()); }, false); } diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index b4d1cb73..b97672be 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -75,6 +75,18 @@ static void translateIPFromEnv(std::vector &v) { } } +const char* sockTypeStr(Session* session) { + if (session) { + switch (session->getSock()->sockType()) { + case SockNum::Sock_TCP: + return "tcp"; + case SockNum::Sock_UDP: + return "udp"; + } + } + return "unknown"; +} + WebRtcTransport::WebRtcTransport(const EventPoller::Ptr &poller) { _poller = poller; _identifier = "zlm_" + to_string(++s_key); @@ -109,16 +121,17 @@ void WebRtcTransport::OnIceServerSendStunPacket( sendSockData((char *)packet->GetData(), packet->GetSize(), tuple); } -void WebRtcTransport::OnIceServerSelectedTuple(const RTC::IceServer *iceServer, RTC::TransportTuple *tuple) { - InfoL; +void WebRtcTransportImp::OnIceServerSelectedTuple(const RTC::IceServer *iceServer, RTC::TransportTuple *tuple) { + InfoL << getIdentifier() << " select tuple " << sockTypeStr(tuple) << " " << tuple->get_peer_ip() << ":" << tuple->get_peer_port(); + _selected_session = tuple->shared_from_this(); } void WebRtcTransport::OnIceServerConnected(const RTC::IceServer *iceServer) { - InfoL; + InfoL << getIdentifier(); } void WebRtcTransport::OnIceServerCompleted(const RTC::IceServer *iceServer) { - InfoL; + InfoL << getIdentifier(); if (_answer_sdp->media[0].role == DtlsRole::passive) { _dtls_transport->Run(RTC::DtlsTransport::Role::SERVER); } else { @@ -127,7 +140,7 @@ void WebRtcTransport::OnIceServerCompleted(const RTC::IceServer *iceServer) { } void WebRtcTransport::OnIceServerDisconnected(const RTC::IceServer *iceServer) { - InfoL; + InfoL << getIdentifier(); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -153,16 +166,16 @@ void WebRtcTransport::OnDtlsTransportSendData( } void WebRtcTransport::OnDtlsTransportConnecting(const RTC::DtlsTransport *dtlsTransport) { - InfoL; + InfoL << getIdentifier(); } void WebRtcTransport::OnDtlsTransportFailed(const RTC::DtlsTransport *dtlsTransport) { - InfoL; + InfoL << getIdentifier(); onShutdown(SockException(Err_shutdown, "dtls transport failed")); } void WebRtcTransport::OnDtlsTransportClosed(const RTC::DtlsTransport *dtlsTransport) { - InfoL; + InfoL << getIdentifier(); onShutdown(SockException(Err_shutdown, "dtls close notify received")); } @@ -178,7 +191,7 @@ void WebRtcTransport::OnDtlsTransportApplicationDataReceived( ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef ENABLE_SCTP void WebRtcTransport::OnSctpAssociationConnecting(RTC::SctpAssociation *sctpAssociation) { - TraceL; + TraceL << getIdentifier(); } void WebRtcTransport::OnSctpAssociationConnected(RTC::SctpAssociation *sctpAssociation) { @@ -293,7 +306,7 @@ static bool isDtls(char *buf) { } static string getPeerAddress(RTC::TransportTuple *tuple) { - return SockUtil::inet_ntoa(tuple); + return tuple->get_peer_ip();// SockUtil::inet_ntoa(tuple); } void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tuple) { @@ -409,24 +422,27 @@ void WebRtcTransportImp::onDestory() { } void WebRtcTransportImp::onSendSockData(Buffer::Ptr buf, bool flush, RTC::TransportTuple *tuple) { - if (!_selected_session) { - WarnL << "send data failed:" << buf->size(); - return; + if (tuple == nullptr) { + if (!_selected_session) { + WarnL << "send data failed:" << buf->size(); + return; + } + tuple = _selected_session.get(); } // 一次性发送一帧的rtp数据,提高网络io性能 - if (_selected_session->getSock()->sockType() == SockNum::Sock_TCP) { + if (tuple->getSock()->sockType() == SockNum::Sock_TCP) { // 增加tcp两字节头 auto len = buf->size(); char tcp_len[2] = { 0 }; tcp_len[0] = (len >> 8) & 0xff; tcp_len[1] = len & 0xff; - _selected_session->SockSender::send(tcp_len, 2); + tuple->SockSender::send(tcp_len, 2); } - _selected_session->send(std::move(buf)); + tuple->send(std::move(buf)); if (flush) { - _selected_session->flushAll(); + tuple->flushAll(); } } @@ -1048,15 +1064,16 @@ void WebRtcTransportImp::onShutdown(const SockException &ex) { } } +void WebRtcTransportImp::RemoveTuple(RTC::TransportTuple* tuple) +{ + InfoL << getIdentifier() << " RemoveTuple " << tuple->get_peer_ip() << ":" << tuple->get_peer_port(); + this->_history_sessions.erase(tuple); + this->_ice_server->RemoveTuple(tuple); +} + void WebRtcTransportImp::setSession(Session::Ptr session) { _history_sessions.emplace(session.get(), session); - if (_selected_session) { - InfoL << "rtc network changed: " << _selected_session->get_peer_ip() << ":" - << _selected_session->get_peer_port() << " -> " << session->get_peer_ip() << ":" - << session->get_peer_port() << ", id:" << getIdentifier(); - } - _selected_session = std::move(session); - _selected_session->setSendFlushFlag(false); + session->setSendFlushFlag(false); unrefSelf(); } diff --git a/webrtc/WebRtcTransport.h b/webrtc/WebRtcTransport.h index 3978864b..f93cec38 100644 --- a/webrtc/WebRtcTransport.h +++ b/webrtc/WebRtcTransport.h @@ -130,7 +130,6 @@ protected: protected: //// ice相关的回调 /// void OnIceServerSendStunPacket(const RTC::IceServer *iceServer, const RTC::StunPacket *packet, RTC::TransportTuple *tuple) override; - void OnIceServerSelectedTuple(const RTC::IceServer *iceServer, RTC::TransportTuple *tuple) override; void OnIceServerConnected(const RTC::IceServer *iceServer) override; void OnIceServerCompleted(const RTC::IceServer *iceServer) override; void OnIceServerDisconnected(const RTC::IceServer *iceServer) override; @@ -170,11 +169,11 @@ private: protected: RtcSession::Ptr _offer_sdp; RtcSession::Ptr _answer_sdp; + std::shared_ptr _ice_server; private: std::string _identifier; EventPoller::Ptr _poller; - std::shared_ptr _ice_server; std::shared_ptr _dtls_transport; std::shared_ptr _srtp_session_send; std::shared_ptr _srtp_session_recv; @@ -249,7 +248,9 @@ public: void createRtpChannel(const std::string &rid, uint32_t ssrc, MediaTrack &track); + void RemoveTuple(RTC::TransportTuple* tuple); protected: + void OnIceServerSelectedTuple(const RTC::IceServer *iceServer, RTC::TransportTuple *tuple) override; WebRtcTransportImp(const EventPoller::Ptr &poller,bool preferred_tcp = false); void OnDtlsTransportApplicationDataReceived(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) override; void onStartWebRTC() override;