mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 04:31:37 +08:00
sdp完整性检查,与忽略大小写拼写
This commit is contained in:
parent
a1b2aa9abb
commit
daef7051ad
@ -12,19 +12,20 @@
|
|||||||
#define ZLMEDIAKIT_ASSERT_H
|
#define ZLMEDIAKIT_ASSERT_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
extern void Assert_Throw(int failed, const char *exp, const char *func, const char *file, int line);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
#ifdef assert
|
#ifdef assert
|
||||||
#undef assert
|
#undef assert
|
||||||
#endif//assert
|
#endif//assert
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
extern void Assert_Throw(int failed, const char *exp, const char *func, const char *file, int line);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define assert(exp) Assert_Throw(!(exp), #exp, __FUNCTION__, __FILE__, __LINE__);
|
#define assert(exp) Assert_Throw(!(exp), #exp, __FUNCTION__, __FILE__, __LINE__);
|
||||||
#else
|
#else
|
||||||
#define assert(e) ((void)0)
|
#define assert(e) ((void)0)
|
||||||
|
127
webrtc/Sdp.cpp
127
webrtc/Sdp.cpp
@ -3,10 +3,14 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "Sdp.h"
|
#include "Sdp.h"
|
||||||
|
#include "assert.h"
|
||||||
|
#include "Common/Parser.h"
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#define CHECK(exp) Assert_Throw(!(exp), #exp, __FUNCTION__, __FILE__, __LINE__);
|
||||||
|
|
||||||
using onCreateSdpItem = function<SdpItem::Ptr(const string &key, const string &value)>;
|
using onCreateSdpItem = function<SdpItem::Ptr(const string &key, const string &value)>;
|
||||||
static unordered_map<string, onCreateSdpItem> sdpItemCreator;
|
static map<string, onCreateSdpItem, StrCaseCompare> sdpItemCreator;
|
||||||
|
|
||||||
template <typename Item>
|
template <typename Item>
|
||||||
void registerSdpItem(){
|
void registerSdpItem(){
|
||||||
@ -89,17 +93,15 @@ static bool registerAllItem(){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackType getTrackType(const string &str){
|
static map<string, TrackType, StrCaseCompare> track_str_map = {
|
||||||
if (str == "video") {
|
{"video", TrackVideo},
|
||||||
return TrackVideo;
|
{"audio", TrackAudio},
|
||||||
}
|
{"application", TrackApplication}
|
||||||
if (str == "audio") {
|
};
|
||||||
return TrackAudio;
|
|
||||||
}
|
TrackType getTrackType(const string &str) {
|
||||||
if (str == "application") {
|
auto it = track_str_map.find(str);
|
||||||
return TrackApplication;
|
return it == track_str_map.end() ? TrackInvalid : it->second;
|
||||||
}
|
|
||||||
return TrackInvalid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* getTrackString(TrackType type){
|
const char* getTrackString(TrackType type){
|
||||||
@ -111,17 +113,15 @@ const char* getTrackString(TrackType type){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DtlsRole getDtlsRole(const string &str){
|
static map<string, DtlsRole, StrCaseCompare> dtls_role_map = {
|
||||||
if (str == "active") {
|
{"active", DtlsRole::active},
|
||||||
return DtlsRole::active;
|
{"passive", DtlsRole::passive},
|
||||||
}
|
{"actpass", DtlsRole::actpass}
|
||||||
if (str == "passive") {
|
};
|
||||||
return DtlsRole::passive;
|
|
||||||
}
|
DtlsRole getDtlsRole(const string &str) {
|
||||||
if (str == "actpass") {
|
auto it = dtls_role_map.find(str);
|
||||||
return DtlsRole::actpass;
|
return it == dtls_role_map.end() ? DtlsRole::invalid : it->second;
|
||||||
}
|
|
||||||
return DtlsRole::invalid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* getDtlsRoleString(DtlsRole role){
|
const char* getDtlsRoleString(DtlsRole role){
|
||||||
@ -133,20 +133,16 @@ const char* getDtlsRoleString(DtlsRole role){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpDirection getRtpDirection(const string &str){
|
static map<string, RtpDirection, StrCaseCompare> direction_map = {
|
||||||
if (str == "sendonly") {
|
{"sendonly", RtpDirection::sendonly},
|
||||||
return RtpDirection::sendonly;
|
{"recvonly", RtpDirection::recvonly},
|
||||||
}
|
{"sendrecv", RtpDirection::sendrecv},
|
||||||
if (str == "recvonly") {
|
{"inactive", RtpDirection::inactive}
|
||||||
return RtpDirection::recvonly;
|
};
|
||||||
}
|
|
||||||
if (str == "sendrecv") {
|
RtpDirection getRtpDirection(const string &str) {
|
||||||
return RtpDirection::sendrecv;
|
auto it = direction_map.find(str);
|
||||||
}
|
return it == direction_map.end() ? RtpDirection::invalid : it->second;
|
||||||
if (str == "inactive") {
|
|
||||||
return RtpDirection::inactive;
|
|
||||||
}
|
|
||||||
return RtpDirection::invalid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* getRtpDirectionString(RtpDirection val){
|
const char* getRtpDirectionString(RtpDirection val){
|
||||||
@ -182,14 +178,15 @@ RtpDirection RtcSdpBase::getDirection() const{
|
|||||||
return RtpDirection::invalid;
|
return RtpDirection::invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
SdpItem::Ptr RtcSdpBase::getItem(char key, const char *attr_key) const {
|
SdpItem::Ptr RtcSdpBase::getItem(char key_c, const char *attr_key) const {
|
||||||
for (auto item : items) {
|
for (auto item : items) {
|
||||||
if (item->getKey()[0] == key) {
|
string key(1, key_c);
|
||||||
|
if (strcasecmp(item->getKey(), key.data()) == 0) {
|
||||||
if (!attr_key) {
|
if (!attr_key) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
auto attr = dynamic_pointer_cast<SdpAttr>(item);
|
auto attr = dynamic_pointer_cast<SdpAttr>(item);
|
||||||
if (attr && !strcmp(attr->detail->getKey() , attr_key)) {
|
if (attr && !strcasecmp(attr->detail->getKey() , attr_key)) {
|
||||||
return attr->detail;
|
return attr->detail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -884,6 +881,7 @@ void RtcSession::loadFrom(const string &str) {
|
|||||||
session_info = sdp.getSessionInfo();
|
session_info = sdp.getSessionInfo();
|
||||||
connection = sdp.getConnection();
|
connection = sdp.getConnection();
|
||||||
bandwidth = sdp.getBandwidth();
|
bandwidth = sdp.getBandwidth();
|
||||||
|
time = sdp.getSessionTime();
|
||||||
msid_semantic = sdp.getItemClass<SdpAttrMsidSemantic>('a', "msid-semantic");
|
msid_semantic = sdp.getItemClass<SdpAttrMsidSemantic>('a', "msid-semantic");
|
||||||
for (auto &media : sdp.medias) {
|
for (auto &media : sdp.medias) {
|
||||||
auto mline = media.getItemClass<SdpMedia>('m');
|
auto mline = media.getItemClass<SdpMedia>('m');
|
||||||
@ -1036,7 +1034,7 @@ void RtcSession::loadFrom(const string &str) {
|
|||||||
|
|
||||||
string RtcCodecPlan::getFmtp(const char *key) const{
|
string RtcCodecPlan::getFmtp(const char *key) const{
|
||||||
for (auto &item : fmtp) {
|
for (auto &item : fmtp) {
|
||||||
if (item.first == key) {
|
if (strcasecmp(item.first.data(), key) == 0) {
|
||||||
return item.second;
|
return item.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1052,34 +1050,41 @@ const RtcCodecPlan *RtcMedia::getPlan(uint8_t pt) const{
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtcMedia::checkValid() const{
|
const RtcCodecPlan *RtcMedia::getPlan(const char *codec) const{
|
||||||
switch (direction) {
|
|
||||||
case RtpDirection::sendonly:
|
|
||||||
case RtpDirection::sendrecv: {
|
|
||||||
if (rtp_ssrc.empty()) {
|
|
||||||
throw std::invalid_argument("发送rtp但是未指定rtp ssrc");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
for (auto &item : plan) {
|
for (auto &item : plan) {
|
||||||
if (item.codec == "rtx") {
|
if (strcasecmp(item.codec.data(), codec) == 0) {
|
||||||
if (rtx_ssrc.empty()) {
|
return &item;
|
||||||
throw std::invalid_argument("指定开启rtx但是未指定rtx ssrc");
|
|
||||||
}
|
|
||||||
auto apt = atoi(item.getFmtp("apt").data());
|
|
||||||
if (!getPlan(apt)) {
|
|
||||||
throw std::invalid_argument("找不到rtx关联的plan信息");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtcMedia::checkValid() const{
|
||||||
|
CHECK(type != TrackInvalid);
|
||||||
|
CHECK(!mid.empty());
|
||||||
|
CHECK(!proto.empty());
|
||||||
|
CHECK(direction != RtpDirection::invalid || type == TrackApplication);
|
||||||
|
CHECK(!plan.empty() || type == TrackApplication );
|
||||||
|
bool send_rtp = (direction == RtpDirection::sendonly || direction == RtpDirection::sendrecv);
|
||||||
|
CHECK(!rtp_ssrc.empty() || !send_rtp);
|
||||||
|
auto rtx_plan = getPlan("rtx");
|
||||||
|
if (rtx_plan) {
|
||||||
|
//开启rtx后必须指定rtx_ssrc
|
||||||
|
CHECK(!rtx_ssrc.empty() || !send_rtp);
|
||||||
|
auto apt = atoi(rtx_plan->getFmtp("apt").data());
|
||||||
|
//开启rtx后必须指定其关联的其他的plan
|
||||||
|
CHECK(getPlan(apt));
|
||||||
}
|
}
|
||||||
//todo 校验更多信息
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtcSession::checkValid() const{
|
void RtcSession::checkValid() const{
|
||||||
|
CHECK(version == 0);
|
||||||
|
CHECK(!origin.empty());
|
||||||
|
CHECK(!session_name.empty());
|
||||||
|
CHECK(!msid_semantic.empty());
|
||||||
|
CHECK(!media.empty());
|
||||||
|
CHECK(group.mids.size() <= media.size());
|
||||||
for (auto &item : media) {
|
for (auto &item : media) {
|
||||||
item.checkValid();
|
item.checkValid();
|
||||||
}
|
}
|
||||||
//todo 校验更多信息
|
|
||||||
}
|
}
|
18
webrtc/Sdp.h
18
webrtc/Sdp.h
@ -134,6 +134,10 @@ public:
|
|||||||
void parse(const string &str) override;
|
void parse(const string &str) override;
|
||||||
string toString() const override;
|
string toString() const override;
|
||||||
const char* getKey() const override { return "o";}
|
const char* getKey() const override { return "o";}
|
||||||
|
bool empty() const {
|
||||||
|
return username.empty() || session_id.empty() || session_version.empty()
|
||||||
|
|| nettype.empty() || addrtype.empty() || address.empty();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SdpConnection : public SdpItem {
|
class SdpConnection : public SdpItem {
|
||||||
@ -233,6 +237,9 @@ public:
|
|||||||
void parse(const string &str) override;
|
void parse(const string &str) override;
|
||||||
string toString() const override;
|
string toString() const override;
|
||||||
const char* getKey() const override { return "msid-semantic";}
|
const char* getKey() const override { return "msid-semantic";}
|
||||||
|
bool empty() const {
|
||||||
|
return msid.empty();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SdpAttrRtcp : public SdpItem {
|
class SdpAttrRtcp : public SdpItem {
|
||||||
@ -467,10 +474,11 @@ public:
|
|||||||
SdpItem::Ptr getItem(char key, const char *attr_key = nullptr) const;
|
SdpItem::Ptr getItem(char key, const char *attr_key = nullptr) const;
|
||||||
|
|
||||||
template<typename cls>
|
template<typename cls>
|
||||||
vector<cls> getAllItem(char key, const char *attr_key = nullptr) const {
|
vector<cls> getAllItem(char key_c, const char *attr_key = nullptr) const {
|
||||||
vector<cls> ret;
|
vector<cls> ret;
|
||||||
for (auto item : items) {
|
for (auto item : items) {
|
||||||
if (item->getKey()[0] == key) {
|
string key(1, key_c);
|
||||||
|
if (strcasecmp(item->getKey(), key.data()) == 0) {
|
||||||
if (!attr_key) {
|
if (!attr_key) {
|
||||||
auto c = dynamic_pointer_cast<cls>(item);
|
auto c = dynamic_pointer_cast<cls>(item);
|
||||||
if (c) {
|
if (c) {
|
||||||
@ -478,7 +486,7 @@ public:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto attr = dynamic_pointer_cast<SdpAttr>(item);
|
auto attr = dynamic_pointer_cast<SdpAttr>(item);
|
||||||
if (attr && !strcmp(attr->detail->getKey(), attr_key)) {
|
if (attr && !strcasecmp(attr->detail->getKey(), attr_key)) {
|
||||||
auto c = dynamic_pointer_cast<cls>(attr->detail);
|
auto c = dynamic_pointer_cast<cls>(attr->detail);
|
||||||
if (c) {
|
if (c) {
|
||||||
ret.emplace_back(*c);
|
ret.emplace_back(*c);
|
||||||
@ -518,7 +526,7 @@ public:
|
|||||||
string mslabel;
|
string mslabel;
|
||||||
string label;
|
string label;
|
||||||
|
|
||||||
bool empty() const {return ssrc == 0;}
|
bool empty() const {return ssrc == 0 && cname.empty();}
|
||||||
};
|
};
|
||||||
|
|
||||||
//rtc传输编码方案
|
//rtc传输编码方案
|
||||||
@ -582,6 +590,7 @@ public:
|
|||||||
|
|
||||||
void checkValid() const;
|
void checkValid() const;
|
||||||
const RtcCodecPlan *getPlan(uint8_t pt) const;
|
const RtcCodecPlan *getPlan(uint8_t pt) const;
|
||||||
|
const RtcCodecPlan *getPlan(const char *codec) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RtcSession{
|
class RtcSession{
|
||||||
@ -590,6 +599,7 @@ public:
|
|||||||
SdpOrigin origin;
|
SdpOrigin origin;
|
||||||
string session_name;
|
string session_name;
|
||||||
string session_info;
|
string session_info;
|
||||||
|
SdpTime time;
|
||||||
SdpConnection connection;
|
SdpConnection connection;
|
||||||
SdpBandwidth bandwidth;
|
SdpBandwidth bandwidth;
|
||||||
SdpAttrMsidSemantic msid_semantic;
|
SdpAttrMsidSemantic msid_semantic;
|
||||||
|
Loading…
Reference in New Issue
Block a user