mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
For RTC publisher, support black-hole
This commit is contained in:
parent
e4329fd1a0
commit
7692e589ed
5 changed files with 146 additions and 17 deletions
|
@ -461,6 +461,16 @@ rtc_server {
|
||||||
# then system queue is 2000*4 = 8k, user can incrase reuseport to incrase the queue.
|
# then system queue is 2000*4 = 8k, user can incrase reuseport to incrase the queue.
|
||||||
# default: 2000
|
# default: 2000
|
||||||
queue_length 2000;
|
queue_length 2000;
|
||||||
|
# The black-hole to copy packet to, for debugging.
|
||||||
|
# For example, when debugging Chrome publish stream, the received packets are encrypted cipher,
|
||||||
|
# we can set the publisher black-hole, SRS will copy the plaintext packets to black-hole, and
|
||||||
|
# we are able to capture the plaintext packets by wireshark.
|
||||||
|
black_hole {
|
||||||
|
# Whether enable the black-hole.
|
||||||
|
enabled off;
|
||||||
|
# The black-hole address for publisher, or SRS as receiver.
|
||||||
|
publisher 127.0.0.1:10000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vhost rtc.vhost.srs.com {
|
vhost rtc.vhost.srs.com {
|
||||||
|
|
|
@ -3645,7 +3645,7 @@ srs_error_t SrsConfig::check_normal_config()
|
||||||
string n = conf->at(i)->name;
|
string n = conf->at(i)->name;
|
||||||
if (n != "enabled" && n != "listen" && n != "dir" && n != "candidate" && n != "ecdsa"
|
if (n != "enabled" && n != "listen" && n != "dir" && n != "candidate" && n != "ecdsa"
|
||||||
&& n != "sendmmsg" && n != "encrypt" && n != "reuseport" && n != "gso" && n != "merge_nalus"
|
&& n != "sendmmsg" && n != "encrypt" && n != "reuseport" && n != "gso" && n != "merge_nalus"
|
||||||
&& n != "padding" && n != "perf_stat" && n != "queue_length") {
|
&& n != "padding" && n != "perf_stat" && n != "queue_length" && n != "black_hole") {
|
||||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal rtc_server.%s", n.c_str());
|
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal rtc_server.%s", n.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4742,7 +4742,7 @@ std::string SrsConfig::get_rtc_server_candidates()
|
||||||
return DEFAULT;
|
return DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (conf->arg0().c_str());
|
return conf->arg0();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrsConfig::get_rtc_server_ecdsa()
|
bool SrsConfig::get_rtc_server_ecdsa()
|
||||||
|
@ -4943,6 +4943,50 @@ int SrsConfig::get_rtc_server_queue_length()
|
||||||
return ::atoi(conf->arg0().c_str());
|
return ::atoi(conf->arg0().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsConfig::get_rtc_server_black_hole()
|
||||||
|
{
|
||||||
|
static bool DEFAULT = false;
|
||||||
|
|
||||||
|
SrsConfDirective* conf = root->get("rtc_server");
|
||||||
|
if (!conf) {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf = conf->get("black_hole");
|
||||||
|
if (!conf) {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf = conf->get("enabled");
|
||||||
|
if (!conf || conf->arg0().empty()) {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SrsConfig::get_rtc_server_black_hole_publisher()
|
||||||
|
{
|
||||||
|
static string DEFAULT = "";
|
||||||
|
|
||||||
|
SrsConfDirective* conf = root->get("rtc_server");
|
||||||
|
if (!conf) {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf = conf->get("black_hole");
|
||||||
|
if (!conf) {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf = conf->get("publisher");
|
||||||
|
if (!conf || conf->arg0().empty()) {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return conf->arg0();
|
||||||
|
}
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_rtc(string vhost)
|
SrsConfDirective* SrsConfig::get_rtc(string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* conf = get_vhost(vhost);
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
|
|
@ -534,6 +534,8 @@ public:
|
||||||
virtual int get_rtc_server_padding();
|
virtual int get_rtc_server_padding();
|
||||||
virtual bool get_rtc_server_perf_stat();
|
virtual bool get_rtc_server_perf_stat();
|
||||||
virtual int get_rtc_server_queue_length();
|
virtual int get_rtc_server_queue_length();
|
||||||
|
virtual bool get_rtc_server_black_hole();
|
||||||
|
virtual std::string get_rtc_server_black_hole_publisher();
|
||||||
private:
|
private:
|
||||||
virtual int get_rtc_server_reuseport2();
|
virtual int get_rtc_server_reuseport2();
|
||||||
virtual bool get_rtc_server_gso2();
|
virtual bool get_rtc_server_gso2();
|
||||||
|
|
|
@ -62,6 +62,7 @@ using namespace std;
|
||||||
#include <srs_app_http_api.hpp>
|
#include <srs_app_http_api.hpp>
|
||||||
#include <srs_app_statistic.hpp>
|
#include <srs_app_statistic.hpp>
|
||||||
#include <srs_app_pithy_print.hpp>
|
#include <srs_app_pithy_print.hpp>
|
||||||
|
#include <srs_service_st.hpp>
|
||||||
|
|
||||||
// The RTP payload max size, reserved some paddings for SRTP as such:
|
// The RTP payload max size, reserved some paddings for SRTP as such:
|
||||||
// kRtpPacketSize = kRtpMaxPayloadSize + paddings
|
// kRtpPacketSize = kRtpMaxPayloadSize + paddings
|
||||||
|
@ -296,6 +297,12 @@ srs_error_t SrsDtlsSession::handshake(SrsUdpMuxSocket* skt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rtc_session->blackhole && rtc_session->blackhole_addr && rtc_session->blackhole_stfd) {
|
||||||
|
// Ignore any error for black-hole.
|
||||||
|
void* p = out_bio_data; int len = out_bio_len; SrsRtcSession* s = rtc_session;
|
||||||
|
srs_sendto(s->blackhole_stfd, p, len, (sockaddr*)s->blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,6 +321,12 @@ srs_error_t SrsDtlsSession::on_dtls(SrsUdpMuxSocket* skt)
|
||||||
return srs_error_new(ERROR_OpenSslBIOWrite, "BIO_write");
|
return srs_error_new(ERROR_OpenSslBIOWrite, "BIO_write");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rtc_session->blackhole && rtc_session->blackhole_addr && rtc_session->blackhole_stfd) {
|
||||||
|
// Ignore any error for black-hole.
|
||||||
|
void* p = skt->data(); int len = skt->size(); SrsRtcSession* s = rtc_session;
|
||||||
|
srs_sendto(s->blackhole_stfd, p, len, (sockaddr*)s->blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
if (!handshake_done) {
|
if (!handshake_done) {
|
||||||
err = handshake(skt);
|
err = handshake(skt);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2159,6 +2172,10 @@ SrsRtcSession::SrsRtcSession(SrsRtcServer* s, SrsRequest* r, const std::string&
|
||||||
session_state = INIT;
|
session_state = INIT;
|
||||||
last_stun_time = 0;
|
last_stun_time = 0;
|
||||||
sessionStunTimeout = 0;
|
sessionStunTimeout = 0;
|
||||||
|
|
||||||
|
blackhole = false;
|
||||||
|
blackhole_addr = NULL;
|
||||||
|
blackhole_stfd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsRtcSession::~SrsRtcSession()
|
SrsRtcSession::~SrsRtcSession()
|
||||||
|
@ -2167,6 +2184,8 @@ SrsRtcSession::~SrsRtcSession()
|
||||||
srs_freep(publisher);
|
srs_freep(publisher);
|
||||||
srs_freep(dtls_session);
|
srs_freep(dtls_session);
|
||||||
srs_freep(req);
|
srs_freep(req);
|
||||||
|
srs_close_stfd(blackhole_stfd);
|
||||||
|
srs_freep(blackhole_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsRtcSession::set_local_sdp(const SrsSdp& sdp)
|
void SrsRtcSession::set_local_sdp(const SrsSdp& sdp)
|
||||||
|
@ -2191,6 +2210,30 @@ srs_error_t SrsRtcSession::initialize()
|
||||||
sessionStunTimeout = _srs_config->get_rtc_stun_timeout(req->vhost);
|
sessionStunTimeout = _srs_config->get_rtc_stun_timeout(req->vhost);
|
||||||
last_stun_time = srs_get_system_time();
|
last_stun_time = srs_get_system_time();
|
||||||
|
|
||||||
|
blackhole = _srs_config->get_rtc_server_black_hole();
|
||||||
|
|
||||||
|
srs_trace("RTC init session, timeout=%dms, blackhole=%d", srsu2msi(sessionStunTimeout), blackhole);
|
||||||
|
|
||||||
|
if (blackhole) {
|
||||||
|
string blackhole_ep = _srs_config->get_rtc_server_black_hole_publisher();
|
||||||
|
if (!blackhole_ep.empty()) {
|
||||||
|
string host; int port;
|
||||||
|
srs_parse_hostport(blackhole_ep, host, port);
|
||||||
|
|
||||||
|
srs_freep(blackhole_addr);
|
||||||
|
blackhole_addr = new sockaddr_in();
|
||||||
|
blackhole_addr->sin_family = AF_INET;
|
||||||
|
blackhole_addr->sin_addr.s_addr = inet_addr(host.c_str());
|
||||||
|
blackhole_addr->sin_port = htons(port);
|
||||||
|
|
||||||
|
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
blackhole_stfd = srs_netfd_open_socket(fd);
|
||||||
|
srs_assert(blackhole_stfd);
|
||||||
|
|
||||||
|
srs_trace("RTC blackhole %s:%d, fd=%d", host.c_str(), port, fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2274,6 +2317,19 @@ srs_error_t SrsRtcSession::on_binding_request(SrsUdpMuxSocket* skt, SrsStunPacke
|
||||||
srs_trace("rtc session=%s, STUN done, waitting DTLS handshake.", id().c_str());
|
srs_trace("rtc session=%s, STUN done, waitting DTLS handshake.", id().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write STUN messages to blackhole.
|
||||||
|
if (blackhole && blackhole_addr && blackhole_stfd) {
|
||||||
|
// Ignore any error for black-hole.
|
||||||
|
void* p = skt->data(); int len = skt->size();
|
||||||
|
srs_sendto(blackhole_stfd, p, len, (sockaddr*)blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blackhole && blackhole_addr && blackhole_stfd) {
|
||||||
|
// Ignore any error for black-hole.
|
||||||
|
void* p = stream->data(); int len = stream->pos();
|
||||||
|
srs_sendto(blackhole_stfd, p, len, (sockaddr*)blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2610,6 +2666,12 @@ srs_error_t SrsRtcSession::on_rtcp(SrsUdpMuxSocket* skt)
|
||||||
return srs_error_wrap(err, "rtcp unprotect failed");
|
return srs_error_wrap(err, "rtcp unprotect failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (blackhole && blackhole_addr && blackhole_stfd) {
|
||||||
|
// Ignore any error for black-hole.
|
||||||
|
void* p = unprotected_buf; int len = nb_unprotected_buf;
|
||||||
|
srs_sendto(blackhole_stfd, p, len, (sockaddr*)blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
char* ph = unprotected_buf;
|
char* ph = unprotected_buf;
|
||||||
int nb_left = nb_unprotected_buf;
|
int nb_left = nb_unprotected_buf;
|
||||||
while (nb_left) {
|
while (nb_left) {
|
||||||
|
@ -2683,12 +2745,18 @@ srs_error_t SrsRtcSession::on_rtp(SrsUdpMuxSocket* skt)
|
||||||
return srs_error_new(ERROR_RTC_RTCP, "recv unexpect rtp packet before dtls done");
|
return srs_error_new(ERROR_RTC_RTCP, "recv unexpect rtp packet before dtls done");
|
||||||
}
|
}
|
||||||
|
|
||||||
char* unprotected_buf = new char[1460];
|
char* unprotected_buf = new char[kRtpPacketSize];
|
||||||
int nb_unprotected_buf = skt->size();
|
int nb_unprotected_buf = skt->size();
|
||||||
if ((err = dtls_session->unprotect_rtp(unprotected_buf, skt->data(), nb_unprotected_buf)) != srs_success) {
|
if ((err = dtls_session->unprotect_rtp(unprotected_buf, skt->data(), nb_unprotected_buf)) != srs_success) {
|
||||||
return srs_error_wrap(err, "rtp unprotect failed");
|
return srs_error_wrap(err, "rtp unprotect failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (blackhole && blackhole_addr && blackhole_stfd) {
|
||||||
|
// Ignore any error for black-hole.
|
||||||
|
void* p = unprotected_buf; int len = nb_unprotected_buf;
|
||||||
|
srs_sendto(blackhole_stfd, p, len, (sockaddr*)blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
return publisher->on_rtp(skt, unprotected_buf, nb_unprotected_buf);
|
return publisher->on_rtp(skt, unprotected_buf, nb_unprotected_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -305,6 +305,7 @@ public:
|
||||||
|
|
||||||
class SrsRtcSession
|
class SrsRtcSession
|
||||||
{
|
{
|
||||||
|
friend class SrsDtlsSession;
|
||||||
friend class SrsRtcSenderThread;
|
friend class SrsRtcSenderThread;
|
||||||
friend class SrsRtcPublisher;
|
friend class SrsRtcPublisher;
|
||||||
private:
|
private:
|
||||||
|
@ -327,6 +328,10 @@ private:
|
||||||
bool encrypt;
|
bool encrypt;
|
||||||
// The timeout of session, keep alive by STUN ping pong.
|
// The timeout of session, keep alive by STUN ping pong.
|
||||||
srs_utime_t sessionStunTimeout;
|
srs_utime_t sessionStunTimeout;
|
||||||
|
private:
|
||||||
|
bool blackhole;
|
||||||
|
sockaddr_in* blackhole_addr;
|
||||||
|
srs_netfd_t blackhole_stfd;
|
||||||
public:
|
public:
|
||||||
SrsRequest* req;
|
SrsRequest* req;
|
||||||
SrsSource* source;
|
SrsSource* source;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue