From d66845425cf6ec72bd5d2e82bf7659f1f12d7b93 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sun, 8 May 2022 00:26:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84ipv6=E7=BD=91=E7=BB=9C?= =?UTF-8?q?=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3rdpart/ZLToolKit | 2 +- src/Rtp/RtpProcess.cpp | 6 +++--- src/Rtp/RtpProcess.h | 2 +- src/Rtp/RtpServer.cpp | 11 +++++++---- src/Rtp/RtpSession.cpp | 4 ++-- src/Rtp/RtpSession.h | 2 +- src/Rtsp/RtspPlayer.cpp | 40 ++++++++++++++++---------------------- src/Rtsp/RtspPusher.cpp | 19 +++++++----------- src/Rtsp/RtspSession.cpp | 27 ++++++++++--------------- src/Rtsp/RtspSession.h | 2 +- src/Rtsp/UDPServer.cpp | 3 +-- tests/test_rtp.cpp | 4 ++-- webrtc/WebRtcSession.cpp | 4 ++-- webrtc/WebRtcSession.h | 2 +- webrtc/WebRtcTransport.cpp | 2 +- 15 files changed, 57 insertions(+), 73 deletions(-) diff --git a/3rdpart/ZLToolKit b/3rdpart/ZLToolKit index 442f682b..d1bd0e54 160000 --- a/3rdpart/ZLToolKit +++ b/3rdpart/ZLToolKit @@ -1 +1 @@ -Subproject commit 442f682b1aebc67ee60a1c43718b8bf66e3c1667 +Subproject commit d1bd0e5459f5138b59d8e012ef148b0f562d1f29 diff --git a/src/Rtp/RtpProcess.cpp b/src/Rtp/RtpProcess.cpp index 1a8eeb6b..5a110aef 100644 --- a/src/Rtp/RtpProcess.cpp +++ b/src/Rtp/RtpProcess.cpp @@ -80,7 +80,7 @@ bool RtpProcess::inputRtp(bool is_udp, const Socket::Ptr &sock, const char *data if (!_sock) { //第一次运行本函数 _sock = sock; - _addr = *addr; + _addr = *((struct sockaddr_storage *)addr); emitOnPublish(); } @@ -198,11 +198,11 @@ void RtpProcess::setOnDetach(const function &cb) { } string RtpProcess::get_peer_ip() { - return SockUtil::inet_ntoa(((struct sockaddr_in &) _addr).sin_addr); + return SockUtil::inet_ntoa((struct sockaddr *)&_addr); } uint16_t RtpProcess::get_peer_port() { - return ntohs(((struct sockaddr_in &) _addr).sin_port); + return SockUtil::inet_port((struct sockaddr *)&_addr); } string RtpProcess::get_local_ip() { diff --git a/src/Rtp/RtpProcess.h b/src/Rtp/RtpProcess.h index c05bed64..cdad5949 100644 --- a/src/Rtp/RtpProcess.h +++ b/src/Rtp/RtpProcess.h @@ -84,7 +84,7 @@ private: private: uint32_t _dts = 0; uint64_t _total_bytes = 0; - struct sockaddr _addr{0}; + struct sockaddr_storage _addr{0}; toolkit::Socket::Ptr _sock; MediaInfo _media_info; toolkit::Ticker _last_frame_time; diff --git a/src/Rtp/RtpServer.cpp b/src/Rtp/RtpServer.cpp index 0311ad8c..4893c302 100644 --- a/src/Rtp/RtpServer.cpp +++ b/src/Rtp/RtpServer.cpp @@ -53,7 +53,7 @@ public: } if (!strong_self->_rtcp_addr) { //只设置一次rtcp对端端口 - strong_self->_rtcp_addr = std::make_shared(); + strong_self->_rtcp_addr = std::make_shared(); memcpy(strong_self->_rtcp_addr.get(), addr, addr_len); } auto rtcps = RtcpHeader::loadFromBytes(buf->data(), buf->size()); @@ -71,10 +71,13 @@ private: } _ticker.resetTime(); - auto rtcp_addr = _rtcp_addr.get(); + auto rtcp_addr = (struct sockaddr *)_rtcp_addr.get(); if (!rtcp_addr) { //默认的,rtcp端口为rtp端口+1 - ((sockaddr_in *) addr)->sin_port = htons(ntohs(((sockaddr_in *) addr)->sin_port) + 1); + switch(addr->sa_family){ + case AF_INET: ((sockaddr_in *) addr)->sin_port = htons(ntohs(((sockaddr_in *) addr)->sin_port) + 1); break; + case AF_INET6: ((sockaddr_in6 *) addr)->sin6_port = htons(ntohs(((sockaddr_in6 *) addr)->sin6_port) + 1); break; + } //未收到rtcp打洞包时,采用默认的rtcp端口 rtcp_addr = addr; } @@ -85,7 +88,7 @@ private: Ticker _ticker; Socket::Ptr _rtcp_sock; uint32_t _sample_rate; - std::shared_ptr _rtcp_addr; + std::shared_ptr _rtcp_addr; }; void RtpServer::start(uint16_t local_port, const string &stream_id, bool enable_tcp, const char *local_ip, bool re_use_port, uint32_t ssrc) { diff --git a/src/Rtp/RtpSession.cpp b/src/Rtp/RtpSession.cpp index c16da709..1fd5a820 100644 --- a/src/Rtp/RtpSession.cpp +++ b/src/Rtp/RtpSession.cpp @@ -40,7 +40,7 @@ void RtpSession::attachServer(const Server &server) { RtpSession::RtpSession(const Socket::Ptr &sock) : Session(sock) { DebugP(this); socklen_t addr_len = sizeof(_addr); - getpeername(sock->rawFD(), &_addr, &addr_len); + getpeername(sock->rawFD(), (struct sockaddr *)&_addr, &addr_len); } RtpSession::~RtpSession() { @@ -110,7 +110,7 @@ void RtpSession::onRtpPacket(const char *data, size_t len) { WarnP(this) << "ssrc不匹配,rtp已丢弃:" << rtp_ssrc << " != " << _ssrc; return; } - _process->inputRtp(false, getSock(), data, len, &_addr); + _process->inputRtp(false, getSock(), data, len, (struct sockaddr *)&_addr); } catch (RtpTrack::BadRtpException &ex) { if (!_is_udp) { WarnL << ex.what() << ",开始搜索ssrc以便恢复上下文"; diff --git a/src/Rtp/RtpSession.h b/src/Rtp/RtpSession.h index f788858a..8389c298 100644 --- a/src/Rtp/RtpSession.h +++ b/src/Rtp/RtpSession.h @@ -50,7 +50,7 @@ private: uint32_t _ssrc = 0; toolkit::Ticker _ticker; std::string _stream_id; - struct sockaddr _addr; + struct sockaddr_storage _addr; RtpProcess::Ptr _process; std::shared_ptr > _statistic_tcp; std::shared_ptr > _statistic_udp; diff --git a/src/Rtsp/RtspPlayer.cpp b/src/Rtsp/RtspPlayer.cpp index bb23d07a..da8530b5 100644 --- a/src/Rtsp/RtspPlayer.cpp +++ b/src/Rtsp/RtspPlayer.cpp @@ -292,7 +292,8 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int track_idx) { //udp组播 auto multiAddr = transport_map["destination"]; pRtpSockRef = createSocket(); - if (!pRtpSockRef->bindUdpSock(rtp_port, "::")) { + //目前组播仅支持ipv4 + if (!pRtpSockRef->bindUdpSock(rtp_port, "0.0.0.0")) { pRtpSockRef.reset(); throw std::runtime_error("open udp sock err"); } @@ -303,45 +304,38 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int track_idx) { //设置rtcp发送端口 pRtcpSockRef = createSocket(); - if (!pRtcpSockRef->bindUdpSock(0, "::")) { + //目前组播仅支持ipv4 + if (!pRtcpSockRef->bindUdpSock(0, "0.0.0.0")) { //分配端口失败 throw runtime_error("open udp socket failed"); } //设置发送地址和发送端口 - struct sockaddr_in rtpto; - rtpto.sin_port = ntohs(rtcp_port); - rtpto.sin_family = AF_INET; - rtpto.sin_addr.s_addr = inet_addr(get_peer_ip().data()); - pRtcpSockRef->bindPeerAddr((struct sockaddr *)&(rtpto)); + auto dst = SockUtil::make_sockaddr(get_peer_ip().data(), rtcp_port); + pRtcpSockRef->bindPeerAddr((struct sockaddr *)&(dst)); } else { createUdpSockIfNecessary(track_idx); //udp单播 - struct sockaddr_in rtpto; - rtpto.sin_port = ntohs(rtp_port); - rtpto.sin_family = AF_INET; - rtpto.sin_addr.s_addr = inet_addr(get_peer_ip().data()); - pRtpSockRef->bindPeerAddr((struct sockaddr *)&(rtpto)); + auto dst = SockUtil::make_sockaddr(get_peer_ip().data(), rtp_port); + pRtpSockRef->bindPeerAddr((struct sockaddr *)&(dst)); //发送rtp打洞包 pRtpSockRef->send("\xce\xfa\xed\xfe", 4); + dst = SockUtil::make_sockaddr(get_peer_ip().data(), rtcp_port); //设置rtcp发送目标,为后续发送rtcp做准备 - rtpto.sin_port = ntohs(rtcp_port); - rtpto.sin_family = AF_INET; - rtpto.sin_addr.s_addr = inet_addr(get_peer_ip().data()); - pRtcpSockRef->bindPeerAddr((struct sockaddr *)&(rtpto)); + pRtcpSockRef->bindPeerAddr((struct sockaddr *)&(dst)); } - auto srcIP = inet_addr(get_peer_ip().data()); + auto peer_ip = get_peer_ip(); weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); //设置rtp over udp接收回调处理函数 - pRtpSockRef->setOnRead([srcIP, track_idx, weakSelf](const Buffer::Ptr &buf, struct sockaddr *addr , int addr_len) { + pRtpSockRef->setOnRead([peer_ip, track_idx, weakSelf](const Buffer::Ptr &buf, struct sockaddr *addr , int addr_len) { auto strongSelf = weakSelf.lock(); if (!strongSelf) { return; } - if (((struct sockaddr_in *) addr)->sin_addr.s_addr != srcIP) { - WarnL << "收到其他地址的rtp数据:" << SockUtil::inet_ntoa(((struct sockaddr_in *) addr)->sin_addr); + if (SockUtil::inet_ntoa(addr) != peer_ip) { + WarnL << "收到其他地址的rtp数据:" << SockUtil::inet_ntoa(addr); return; } strongSelf->handleOneRtp(track_idx, strongSelf->_sdp_track[track_idx]->_type, @@ -350,13 +344,13 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int track_idx) { if(pRtcpSockRef) { //设置rtcp over udp接收回调处理函数 - pRtcpSockRef->setOnRead([srcIP, track_idx, weakSelf](const Buffer::Ptr &buf, struct sockaddr *addr , int addr_len) { + pRtcpSockRef->setOnRead([peer_ip, track_idx, weakSelf](const Buffer::Ptr &buf, struct sockaddr *addr , int addr_len) { auto strongSelf = weakSelf.lock(); if (!strongSelf) { return; } - if (((struct sockaddr_in *) addr)->sin_addr.s_addr != srcIP) { - WarnL << "收到其他地址的rtcp数据:" << SockUtil::inet_ntoa(((struct sockaddr_in *) addr)->sin_addr); + if (SockUtil::inet_ntoa(addr) != peer_ip) { + WarnL << "收到其他地址的rtcp数据:" << SockUtil::inet_ntoa(addr); return; } strongSelf->onRtcpPacket(track_idx, strongSelf->_sdp_track[track_idx], (uint8_t *) buf->data(), buf->size()); diff --git a/src/Rtsp/RtspPusher.cpp b/src/Rtsp/RtspPusher.cpp index 942e2cfe..7b9cb3e2 100644 --- a/src/Rtsp/RtspPusher.cpp +++ b/src/Rtsp/RtspPusher.cpp @@ -307,30 +307,25 @@ void RtspPusher::handleResSetup(const Parser &parser, unsigned int track_idx) { auto &rtp_sock = _rtp_sock[track_idx]; auto &rtcp_sock = _rtcp_sock[track_idx]; - struct sockaddr_in rtpto; + auto rtpto = SockUtil::make_sockaddr(get_peer_ip().data(), rtp_port); //设置rtp发送目标,为后续发送rtp做准备 - rtpto.sin_port = ntohs(rtp_port); - rtpto.sin_family = AF_INET; - rtpto.sin_addr.s_addr = inet_addr(get_peer_ip().data()); rtp_sock->bindPeerAddr((struct sockaddr *) &(rtpto)); //设置rtcp发送目标,为后续发送rtcp做准备 - rtpto.sin_port = ntohs(rtcp_port); - rtpto.sin_family = AF_INET; - rtpto.sin_addr.s_addr = inet_addr(get_peer_ip().data()); - rtcp_sock->bindPeerAddr((struct sockaddr *)&(rtpto)); + auto rtcpto = SockUtil::make_sockaddr(get_peer_ip().data(), rtcp_port); + rtcp_sock->bindPeerAddr((struct sockaddr *)&(rtcpto)); - auto srcIP = inet_addr(get_peer_ip().data()); + auto peer_ip = get_peer_ip(); weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); if(rtcp_sock) { //设置rtcp over udp接收回调处理函数 - rtcp_sock->setOnRead([srcIP, track_idx, weakSelf](const Buffer::Ptr &buf, struct sockaddr *addr , int addr_len) { + rtcp_sock->setOnRead([peer_ip, track_idx, weakSelf](const Buffer::Ptr &buf, struct sockaddr *addr , int addr_len) { auto strongSelf = weakSelf.lock(); if (!strongSelf) { return; } - if (((struct sockaddr_in *) addr)->sin_addr.s_addr != srcIP) { - WarnL << "收到其他地址的rtcp数据:" << SockUtil::inet_ntoa(((struct sockaddr_in *) addr)->sin_addr); + if (SockUtil::inet_ntoa(addr) != peer_ip) { + WarnL << "收到其他地址的rtcp数据:" << SockUtil::inet_ntoa(addr); return; } strongSelf->onRtcpPacket(track_idx, strongSelf->_track_vec[track_idx], (uint8_t *) buf->data(), buf->size()); diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index bd9e35be..4e6bdd1d 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -705,19 +705,12 @@ void RtspSession::handleReq_Setup(const Parser &parser) { uint16_t ui16RtpPort = atoi(FindField(strClientPort.data(), NULL, "-").data()); uint16_t ui16RtcpPort = atoi(FindField(strClientPort.data(), "-", NULL).data()); - struct sockaddr_in peerAddr; + auto peerAddr = SockUtil::make_sockaddr(get_peer_ip().data(), ui16RtpPort); //设置rtp发送目标地址 - peerAddr.sin_family = AF_INET; - peerAddr.sin_port = htons(ui16RtpPort); - peerAddr.sin_addr.s_addr = inet_addr(get_peer_ip().data()); - bzero(&(peerAddr.sin_zero), sizeof peerAddr.sin_zero); pr.first->bindPeerAddr((struct sockaddr *) (&peerAddr)); //设置rtcp发送目标地址 - peerAddr.sin_family = AF_INET; - peerAddr.sin_port = htons(ui16RtcpPort); - peerAddr.sin_addr.s_addr = inet_addr(get_peer_ip().data()); - bzero(&(peerAddr.sin_zero), sizeof peerAddr.sin_zero); + peerAddr = SockUtil::make_sockaddr(get_peer_ip().data(), ui16RtcpPort); pr.second->bindPeerAddr((struct sockaddr *) (&peerAddr)); //尝试获取客户端nat映射地址 @@ -953,7 +946,7 @@ void RtspSession::onRtpSorted(RtpPacket::Ptr rtp, int track_idx) { } } -void RtspSession::onRcvPeerUdpData(int interleaved, const Buffer::Ptr &buf, const struct sockaddr &addr) { +void RtspSession::onRcvPeerUdpData(int interleaved, const Buffer::Ptr &buf, const struct sockaddr_storage &addr) { //这是rtcp心跳包,说明播放器还存活 _alive_ticker.resetTime(); @@ -965,13 +958,13 @@ void RtspSession::onRcvPeerUdpData(int interleaved, const Buffer::Ptr &buf, cons } else if (!_udp_connected_flags.count(interleaved)) { //这是rtsp播放器的rtp打洞包 _udp_connected_flags.emplace(interleaved); - _rtp_socks[interleaved / 2]->bindPeerAddr(&addr); + _rtp_socks[interleaved / 2]->bindPeerAddr((struct sockaddr *)&addr); } } else { //rtcp包 if (!_udp_connected_flags.count(interleaved)) { _udp_connected_flags.emplace(interleaved); - _rtcp_socks[(interleaved - 1) / 2]->bindPeerAddr(&addr); + _rtcp_socks[(interleaved - 1) / 2]->bindPeerAddr((struct sockaddr *)&addr); } onRtcpPacket((interleaved - 1) / 2, _sdp_track[(interleaved - 1) / 2], buf->data(), buf->size()); } @@ -979,20 +972,20 @@ void RtspSession::onRcvPeerUdpData(int interleaved, const Buffer::Ptr &buf, cons void RtspSession::startListenPeerUdpData(int track_idx) { weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); - auto srcIP = inet_addr(get_peer_ip().data()); - auto onUdpData = [weakSelf,srcIP](const Buffer::Ptr &buf, struct sockaddr *peer_addr, int interleaved){ + auto peer_ip = get_peer_ip(); + auto onUdpData = [weakSelf,peer_ip](const Buffer::Ptr &buf, struct sockaddr *peer_addr, int interleaved){ auto strongSelf = weakSelf.lock(); if (!strongSelf) { return false; } - if (((struct sockaddr_in *) peer_addr)->sin_addr.s_addr != srcIP) { + if (SockUtil::inet_ntoa(peer_addr) != peer_ip) { WarnP(strongSelf.get()) << ((interleaved % 2 == 0) ? "收到其他地址的rtp数据:" : "收到其他地址的rtcp数据:") - << SockUtil::inet_ntoa(((struct sockaddr_in *) peer_addr)->sin_addr); + << SockUtil::inet_ntoa(peer_addr); return true; } - struct sockaddr addr = *peer_addr; + struct sockaddr_storage addr = *((struct sockaddr_storage *)peer_addr); strongSelf->async([weakSelf, buf, addr, interleaved]() { auto strongSelf = weakSelf.lock(); if (!strongSelf) { diff --git a/src/Rtsp/RtspSession.h b/src/Rtsp/RtspSession.h index b272d6c8..d6dbe9d8 100644 --- a/src/Rtsp/RtspSession.h +++ b/src/Rtsp/RtspSession.h @@ -133,7 +133,7 @@ private: int getTrackIndexByControlUrl(const std::string &control_url); int getTrackIndexByInterleaved(int interleaved); //一般用于接收udp打洞包,也用于rtsp推流 - void onRcvPeerUdpData(int interleaved, const toolkit::Buffer::Ptr &buf, const struct sockaddr &addr); + void onRcvPeerUdpData(int interleaved, const toolkit::Buffer::Ptr &buf, const struct sockaddr_storage &addr); //配合onRcvPeerUdpData使用 void startListenPeerUdpData(int track_idx); ////rtsp专有认证相关//// diff --git a/src/Rtsp/UDPServer.cpp b/src/Rtsp/UDPServer.cpp index fdf56adc..4f648ddf 100644 --- a/src/Rtsp/UDPServer.cpp +++ b/src/Rtsp/UDPServer.cpp @@ -75,8 +75,7 @@ void UDPServer::onErr(const string &key, const SockException &err) { } void UDPServer::onRecv(int interleaved, const Buffer::Ptr &buf, struct sockaddr* peer_addr) { - struct sockaddr_in *in = (struct sockaddr_in *) peer_addr; - string peer_ip = SockUtil::inet_ntoa(in->sin_addr); + string peer_ip = SockUtil::inet_ntoa(peer_addr); lock_guard lck(_mtx_on_recv); auto it0 = _on_recv_map.find(peer_ip); if (it0 == _on_recv_map.end()) { diff --git a/tests/test_rtp.cpp b/tests/test_rtp.cpp index 0b17ed3f..18047b8a 100644 --- a/tests/test_rtp.cpp +++ b/tests/test_rtp.cpp @@ -37,7 +37,7 @@ static bool loadFile(const char *path){ uint32_t timeStamp_last = 0; uint16_t len; char rtp[0xFFFF]; - struct sockaddr addr = {0}; + struct sockaddr_storage addr = {0}; auto sock = Socket::createSocket(); size_t total_size = 0; while (true) { @@ -58,7 +58,7 @@ static bool loadFile(const char *path){ total_size += len; uint32_t timeStamp; - RtpSelector::Instance().inputRtp(sock, rtp, len, &addr, &timeStamp); + RtpSelector::Instance().inputRtp(sock, rtp, len, (struct sockaddr *)&addr, &timeStamp); auto diff = timeStamp - timeStamp_last; if (diff > 0 && diff < 500) { usleep(diff * 1000); diff --git a/webrtc/WebRtcSession.cpp b/webrtc/WebRtcSession.cpp index ec645c56..1cb428f1 100644 --- a/webrtc/WebRtcSession.cpp +++ b/webrtc/WebRtcSession.cpp @@ -46,7 +46,7 @@ EventPoller::Ptr WebRtcSession::queryPoller(const Buffer::Ptr &buffer) { WebRtcSession::WebRtcSession(const Socket::Ptr &sock) : UdpSession(sock) { socklen_t addr_len = sizeof(_peer_addr); - getpeername(sock->rawFD(), &_peer_addr, &addr_len); + getpeername(sock->rawFD(), (struct sockaddr *)&_peer_addr, &addr_len); } WebRtcSession::~WebRtcSession() { @@ -67,7 +67,7 @@ void WebRtcSession::onRecv(const Buffer::Ptr &buffer) { } _ticker.resetTime(); CHECK(_transport); - _transport->inputSockData(buffer->data(), buffer->size(), &_peer_addr); + _transport->inputSockData(buffer->data(), buffer->size(), (struct sockaddr *)&_peer_addr); } void WebRtcSession::onError(const SockException &err) { diff --git a/webrtc/WebRtcSession.h b/webrtc/WebRtcSession.h index c3cd0290..dcbd079c 100644 --- a/webrtc/WebRtcSession.h +++ b/webrtc/WebRtcSession.h @@ -32,7 +32,7 @@ private: std::string _identifier; bool _find_transport = true; Ticker _ticker; - struct sockaddr _peer_addr; + struct sockaddr_storage _peer_addr; std::shared_ptr _transport; }; diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 7d548ff1..b6649597 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -274,7 +274,7 @@ static bool is_rtcp(char *buf) { } static string getPeerAddress(RTC::TransportTuple *tuple){ - return SockUtil::inet_ntoa(((struct sockaddr_in *)tuple)->sin_addr) + ":" + to_string(ntohs(((struct sockaddr_in *)tuple)->sin_port)); + return SockUtil::inet_ntoa(tuple); } void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tuple) {