diff --git a/conf/config.ini b/conf/config.ini index 4fb5cc1c..348b134d 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -362,6 +362,10 @@ port=554 sslport=0 #rtsp 转发是否使用低延迟模式,当开启时,不会缓存rtp包,来提高并发,可以降低一帧的延迟 lowLatency=0 +#强制协商rtp传输方式 (0:TCP,1:UDP,2:MULTICAST,-1:不限制) +#当客户端发起RTSP SETUP的时候如果传输类型和此配置不一致则返回461 Unsupported transport +#迫使客户端重新SETUP并切换到对应协议。目前支持FFMPEG和VLC +rtpTransportType=-1 [shell] #调试telnet服务器接受最大bufffer大小 maxReqSize=1024 diff --git a/src/Common/config.cpp b/src/Common/config.cpp index ce5d8935..5783b54c 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -209,6 +209,7 @@ const string kHandshakeSecond = RTSP_FIELD "handshakeSecond"; const string kKeepAliveSecond = RTSP_FIELD "keepAliveSecond"; const string kDirectProxy = RTSP_FIELD "directProxy"; const string kLowLatency = RTSP_FIELD"lowLatency"; +const string kRtpTransportType = RTSP_FIELD"rtpTransportType"; static onceToken token([]() { // 默认Md5方式认证 @@ -217,6 +218,7 @@ static onceToken token([]() { mINI::Instance()[kKeepAliveSecond] = 15; mINI::Instance()[kDirectProxy] = 1; mINI::Instance()[kLowLatency] = 0; + mINI::Instance()[kRtpTransportType] = -1; }); } // namespace Rtsp diff --git a/src/Common/config.h b/src/Common/config.h index ea874d64..74ea5d71 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -273,6 +273,11 @@ extern const std::string kDirectProxy; // rtsp 转发是否使用低延迟模式,当开启时,不会缓存rtp包,来提高并发,可以降低一帧的延迟 extern const std::string kLowLatency; + +//强制协商rtp传输方式 (0:TCP,1:UDP,2:MULTICAST,-1:不限制) +//当客户端发起RTSP SETUP的时候如果传输类型和此配置不一致则返回461 Unsupport Transport +//迫使客户端重新SETUP并切换到对应协议。目前支持FFMPEG和VLC +extern const std::string kRtpTransportType; } // namespace Rtsp ////////////RTMP服务器配置/////////// diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index 15db5aa8..e9c69ac2 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -634,19 +634,44 @@ void RtspSession::handleReq_Setup(const Parser &parser) { //已经初始化过该Track throw SockException(Err_shutdown, "can not setup one track twice"); } - trackRef->_inited = true; //现在初始化 - if(_rtp_type == Rtsp::RTP_Invalid){ - auto &strTransport = parser["Transport"]; - if(strTransport.find("TCP") != string::npos){ - _rtp_type = Rtsp::RTP_TCP; - }else if(strTransport.find("multicast") != string::npos){ - _rtp_type = Rtsp::RTP_MULTICAST; - }else{ - _rtp_type = Rtsp::RTP_UDP; + static auto getRtpTypeStr = [](const int type) { + switch (type) + { + case Rtsp::RTP_TCP: + return "TCP"; + case Rtsp::RTP_UDP: + return "UDP"; + case Rtsp::RTP_MULTICAST: + return "MULTICAST"; + default: + return "Invalid"; } + }; + + if (_rtp_type == Rtsp::RTP_Invalid) { + auto &strTransport = parser["Transport"]; + auto rtpType = Rtsp::RTP_Invalid; + if (strTransport.find("TCP") != string::npos) { + rtpType = Rtsp::RTP_TCP; + } else if (strTransport.find("multicast") != string::npos) { + rtpType = Rtsp::RTP_MULTICAST; + } else { + rtpType = Rtsp::RTP_UDP; + } + //检查RTP传输类型限制 + GET_CONFIG(int, transport, Rtsp::kRtpTransportType); + if (transport != Rtsp::RTP_Invalid && transport != rtpType) { + WarnL << "rtsp client setup transport " << getRtpTypeStr(rtpType) << " but config force transport " << getRtpTypeStr(transport); + //配置限定RTSP传输方式,但是客户端握手方式不一致,返回461 + sendRtspResponse("461 Unsupported transport"); + return; + } + _rtp_type = rtpType; } + trackRef->_inited = true; //现在初始化 + //允许接收rtp、rtcp包 RtspSplitter::enableRecvRtp(_rtp_type == Rtsp::RTP_TCP);