mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-12 19:24:22 +08:00
feat: 增加webrtc代理拉流 (#4389)
- 增加客户端模式,支持主动拉流、推流: - addStreamProxy接口新增支持whep主动拉流,拉流地址目前只兼容zlm的whep url。 - addStreamPusherProxy接口新增支持whip主动推流,推流地址目前只兼容zlm的whip url。 - 以上推流url格式为webrtc[s]://server_host:server_port/app/stream_id?key=value, 内部会自动转换为http[s]://server_host:server_port/index/api/[whip/whep]?app=app&stream=stream_id&key=value。 - 增加WebRtc p2p 模式: - 增加 ICE FULL模式。 - 增加STUN/TURN 服务器。 - 增加websocket 信令。 - 增加P2P代理拉流。 --------- Co-authored-by: xia-chu <771730766@qq.com> Co-authored-by: mtdxc <mtdxc@126.com> Co-authored-by: cqm <cqm@97kid.com>
This commit is contained in:
146
srt/Crypto.cpp
146
srt/Crypto.cpp
@@ -49,11 +49,11 @@ inline const EVP_CIPHER* aes_key_len_mapping_ctr_cipher(int key_len) {
|
||||
static bool aes_wrap(const uint8_t* in, int in_len, uint8_t* out, int* outLen, uint8_t* key, int key_len) {
|
||||
|
||||
#if defined(ENABLE_OPENSSL)
|
||||
EVP_CIPHER_CTX* ctx = NULL;
|
||||
EVP_CIPHER_CTX* ctx = NULL;
|
||||
|
||||
*outLen = 0;
|
||||
|
||||
do {
|
||||
do {
|
||||
if (!(ctx = EVP_CIPHER_CTX_new())) {
|
||||
WarnL << "EVP_CIPHER_CTX_new fail";
|
||||
break;
|
||||
@@ -62,29 +62,29 @@ static bool aes_wrap(const uint8_t* in, int in_len, uint8_t* out, int* outLen, u
|
||||
|
||||
if (1 != EVP_EncryptInit_ex(ctx, aes_key_len_mapping_wrap_cipher(key_len), NULL, key, NULL)) {
|
||||
WarnL << "EVP_EncryptInit_ex fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int len1 = 0;
|
||||
if (1 != EVP_EncryptUpdate(ctx, (uint8_t*)out, &len1, (uint8_t*)in, in_len)) {
|
||||
int len1 = 0;
|
||||
if (1 != EVP_EncryptUpdate(ctx, (uint8_t*)out, &len1, (uint8_t*)in, in_len)) {
|
||||
WarnL << "EVP_EncryptUpdate fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int len2 = 0;
|
||||
if (1 != EVP_EncryptFinal_ex(ctx, (uint8_t*)out + len1, &len2)) {
|
||||
int len2 = 0;
|
||||
if (1 != EVP_EncryptFinal_ex(ctx, (uint8_t*)out + len1, &len2)) {
|
||||
WarnL << "EVP_EncryptFinal_ex fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*outLen = len1 + len2;
|
||||
} while (0);
|
||||
*outLen = len1 + len2;
|
||||
} while (0);
|
||||
|
||||
if (ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
if (ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
|
||||
return *outLen != 0;
|
||||
return *outLen != 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
@@ -103,11 +103,11 @@ static bool aes_wrap(const uint8_t* in, int in_len, uint8_t* out, int* outLen, u
|
||||
static bool aes_unwrap(const uint8_t* in, int in_len, uint8_t* out, int* outLen, uint8_t* key, int key_len) {
|
||||
|
||||
#if defined(ENABLE_OPENSSL)
|
||||
EVP_CIPHER_CTX* ctx = NULL;
|
||||
EVP_CIPHER_CTX* ctx = NULL;
|
||||
|
||||
*outLen = 0;
|
||||
|
||||
do {
|
||||
do {
|
||||
|
||||
if (!(ctx = EVP_CIPHER_CTX_new())) {
|
||||
WarnL << "EVP_CIPHER_CTX_new fail";
|
||||
@@ -117,8 +117,8 @@ static bool aes_unwrap(const uint8_t* in, int in_len, uint8_t* out, int* outLen,
|
||||
|
||||
if (1 != EVP_DecryptInit_ex(ctx, aes_key_len_mapping_wrap_cipher(key_len), NULL, key, NULL)) {
|
||||
WarnL << "EVP_DecryptInit_ex fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//设置pkcs7padding
|
||||
if (1 != EVP_CIPHER_CTX_set_padding(ctx, 1)) {
|
||||
@@ -126,26 +126,26 @@ static bool aes_unwrap(const uint8_t* in, int in_len, uint8_t* out, int* outLen,
|
||||
break;
|
||||
}
|
||||
|
||||
int len1 = 0;
|
||||
if (1 != EVP_DecryptUpdate(ctx, (uint8_t*)out, &len1, (uint8_t*)in, in_len)) {
|
||||
int len1 = 0;
|
||||
if (1 != EVP_DecryptUpdate(ctx, (uint8_t*)out, &len1, (uint8_t*)in, in_len)) {
|
||||
WarnL << "EVP_DecryptUpdate fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int len2 = 0;
|
||||
if (1 != EVP_DecryptFinal_ex(ctx, (uint8_t*)out + len1, &len2)) {
|
||||
int len2 = 0;
|
||||
if (1 != EVP_DecryptFinal_ex(ctx, (uint8_t*)out + len1, &len2)) {
|
||||
WarnL << "EVP_DecryptFinal_ex fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*outLen = len1 + len2;
|
||||
} while (0);
|
||||
*outLen = len1 + len2;
|
||||
} while (0);
|
||||
|
||||
if (ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
if (ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
|
||||
return *outLen != 0;
|
||||
return *outLen != 0;
|
||||
|
||||
#else
|
||||
return false;
|
||||
@@ -166,11 +166,11 @@ static bool aes_unwrap(const uint8_t* in, int in_len, uint8_t* out, int* outLen,
|
||||
static bool aes_ctr_encrypt(const uint8_t* in, int in_len, uint8_t* out, int* outLen, uint8_t* key, int key_len, uint8_t* iv) {
|
||||
|
||||
#if defined(ENABLE_OPENSSL)
|
||||
EVP_CIPHER_CTX* ctx = NULL;
|
||||
EVP_CIPHER_CTX* ctx = NULL;
|
||||
|
||||
*outLen = 0;
|
||||
|
||||
do {
|
||||
do {
|
||||
if (!(ctx = EVP_CIPHER_CTX_new())) {
|
||||
WarnL << "EVP_CIPHER_CTX_new fail";
|
||||
break;
|
||||
@@ -178,29 +178,29 @@ static bool aes_ctr_encrypt(const uint8_t* in, int in_len, uint8_t* out, int* ou
|
||||
|
||||
if (1 != EVP_EncryptInit_ex(ctx, aes_key_len_mapping_ctr_cipher(key_len), NULL, key, iv)) {
|
||||
WarnL << "EVP_EncryptInit_ex fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int len1 = 0;
|
||||
if (1 != EVP_EncryptUpdate(ctx, (uint8_t*)out, &len1, (uint8_t*)in, in_len)) {
|
||||
int len1 = 0;
|
||||
if (1 != EVP_EncryptUpdate(ctx, (uint8_t*)out, &len1, (uint8_t*)in, in_len)) {
|
||||
WarnL << "EVP_EncryptUpdate fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int len2 = 0;
|
||||
if (1 != EVP_EncryptFinal_ex(ctx, (uint8_t*)out + len1, &len2)) {
|
||||
int len2 = 0;
|
||||
if (1 != EVP_EncryptFinal_ex(ctx, (uint8_t*)out + len1, &len2)) {
|
||||
WarnL << "EVP_EncryptFinal_ex fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*outLen = len1 + len2;
|
||||
} while (0);
|
||||
*outLen = len1 + len2;
|
||||
} while (0);
|
||||
|
||||
if (ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
if (ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
|
||||
return *outLen != 0;
|
||||
return *outLen != 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
@@ -221,42 +221,42 @@ static bool aes_ctr_encrypt(const uint8_t* in, int in_len, uint8_t* out, int* ou
|
||||
static bool aes_ctr_decrypt(const uint8_t* in, int in_len, uint8_t* out, int* outLen, uint8_t* key, int key_len, uint8_t* iv) {
|
||||
|
||||
#if defined(ENABLE_OPENSSL)
|
||||
EVP_CIPHER_CTX* ctx = NULL;
|
||||
EVP_CIPHER_CTX* ctx = NULL;
|
||||
|
||||
*outLen = 0;
|
||||
|
||||
do {
|
||||
do {
|
||||
|
||||
if (!(ctx = EVP_CIPHER_CTX_new())) {
|
||||
WarnL << "EVP_CIPHER_CTX_new fail";
|
||||
break;
|
||||
}
|
||||
|
||||
if (1 != EVP_DecryptInit_ex(ctx, aes_key_len_mapping_ctr_cipher(key_len), NULL, key, iv)) {
|
||||
if (1 != EVP_DecryptInit_ex(ctx, aes_key_len_mapping_ctr_cipher(key_len), NULL, key, iv)) {
|
||||
WarnL << "EVP_DecryptInit_ex fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int len1 = 0;
|
||||
if (1 != EVP_DecryptUpdate(ctx, (uint8_t*)out, &len1, (uint8_t*)in, in_len)) {
|
||||
int len1 = 0;
|
||||
if (1 != EVP_DecryptUpdate(ctx, (uint8_t*)out, &len1, (uint8_t*)in, in_len)) {
|
||||
WarnL << "EVP_DecryptUpdate fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int len2 = 0;
|
||||
if (1 != EVP_DecryptFinal_ex(ctx, (uint8_t*)out + len1, &len2)) {
|
||||
int len2 = 0;
|
||||
if (1 != EVP_DecryptFinal_ex(ctx, (uint8_t*)out + len1, &len2)) {
|
||||
WarnL << "EVP_DecryptFinal_ex fail";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*outLen = len1 + len2;
|
||||
} while (0);
|
||||
*outLen = len1 + len2;
|
||||
} while (0);
|
||||
|
||||
if (ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
if (ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
|
||||
return *outLen != 0;
|
||||
return *outLen != 0;
|
||||
|
||||
#else
|
||||
return false;
|
||||
|
||||
@@ -353,7 +353,7 @@ bool HandshakePacket::loadExtMessage(uint8_t *buf, size_t len) {
|
||||
case HSExt::SRT_CMD_SID: ext = std::make_shared<HSExtStreamID>(); break;
|
||||
case HSExt::SRT_CMD_KMREQ:
|
||||
case HSExt::SRT_CMD_KMRSP:
|
||||
ext = std::make_shared<HSExtKeyMaterial>(); break;
|
||||
ext = std::make_shared<HSExtKeyMaterial>(); break;
|
||||
default: WarnL << "not support ext " << type; break;
|
||||
}
|
||||
if (ext) {
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
#ifndef ZLMEDIAKIT_SRT_SESSION_H
|
||||
#define ZLMEDIAKIT_SRT_SESSION_H
|
||||
|
||||
#include "Network/Session.h"
|
||||
#include "SrtTransport.hpp"
|
||||
|
||||
namespace SRT {
|
||||
|
||||
using namespace toolkit;
|
||||
|
||||
class SrtSession : public Session {
|
||||
public:
|
||||
SrtSession(const Socket::Ptr &sock);
|
||||
|
||||
void onRecv(const Buffer::Ptr &) override;
|
||||
void onError(const SockException &err) override;
|
||||
void onManager() override;
|
||||
void attachServer(const toolkit::Server &server) override;
|
||||
static EventPoller::Ptr queryPoller(const Buffer::Ptr &buffer);
|
||||
|
||||
private:
|
||||
bool _find_transport = true;
|
||||
Ticker _ticker;
|
||||
struct sockaddr_storage _peer_addr;
|
||||
SrtTransport::Ptr _transport;
|
||||
};
|
||||
|
||||
} // namespace SRT
|
||||
#endif // ZLMEDIAKIT_SRT_SESSION_H
|
||||
#ifndef ZLMEDIAKIT_SRT_SESSION_H
|
||||
#define ZLMEDIAKIT_SRT_SESSION_H
|
||||
|
||||
#include "Network/Session.h"
|
||||
#include "SrtTransport.hpp"
|
||||
|
||||
namespace SRT {
|
||||
|
||||
using namespace toolkit;
|
||||
|
||||
class SrtSession : public Session {
|
||||
public:
|
||||
SrtSession(const Socket::Ptr &sock);
|
||||
|
||||
void onRecv(const Buffer::Ptr &) override;
|
||||
void onError(const SockException &err) override;
|
||||
void onManager() override;
|
||||
void attachServer(const toolkit::Server &server) override;
|
||||
static EventPoller::Ptr queryPoller(const Buffer::Ptr &buffer);
|
||||
|
||||
private:
|
||||
bool _find_transport = true;
|
||||
Ticker _ticker;
|
||||
struct sockaddr_storage _peer_addr;
|
||||
SrtTransport::Ptr _transport;
|
||||
};
|
||||
|
||||
} // namespace SRT
|
||||
#endif // ZLMEDIAKIT_SRT_SESSION_H
|
||||
|
||||
@@ -400,7 +400,7 @@ void SrtTransport::sendMsgDropReq(uint32_t first, uint32_t last) {
|
||||
}
|
||||
|
||||
void SrtTransport::tryAnnounceKeyMaterial() {
|
||||
//TraceL;
|
||||
//TraceL;
|
||||
|
||||
if (!_crypto) {
|
||||
return;
|
||||
|
||||
@@ -169,8 +169,8 @@ private:
|
||||
|
||||
// for encryption
|
||||
Crypto::Ptr _crypto;
|
||||
Timer::Ptr _announce_timer;
|
||||
KeyMaterialPacket::Ptr _announce_req;
|
||||
Timer::Ptr _announce_timer;
|
||||
KeyMaterialPacket::Ptr _announce_req;
|
||||
};
|
||||
|
||||
class SrtTransportManager {
|
||||
|
||||
Reference in New Issue
Block a user