1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-12 19:31:53 +00:00

SRT: Support encrypt, with utest (#3223)

* SRT: support encrypt, with utest

* SRT: refine set srt option error log
This commit is contained in:
john 2022-10-28 16:55:35 +08:00 committed by GitHub
parent 8dcbcd1656
commit 7d9dc69ae1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 172 additions and 13 deletions

View file

@ -350,6 +350,19 @@ srt_server {
# Overwrite by env SRS_SRT_SERVER_RECVBUF
# default: 8192 * (1500-28)
recvbuf 2000000;
# The passphrase of SRT.
# If passphrase is no empty, all the srt client must be using the correct passphrase to publish or play,
# or the srt connection will reject. The length of passphrase must be in range 10~79.
# @see https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#srto_passphrase.
# Overwrite by env SRS_SRT_SERVER_PASSPHRASE
# default: ""
passphrase xxxxxxxxxxxx;
# The pbkeylen of SRT.
# The pbkeylen determined the AES encrypt algorithm, this option only allow 4 values which is 0, 16, 24, 32
# @see https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#srto_pbkeylen.
# Overwrite by env SRS_SRT_SERVER_PBKEYLEN
# default: 0
pbkeylen 16;
}
vhost srt.vhost.srs.com {

View file

@ -2332,7 +2332,7 @@ srs_error_t SrsConfig::check_normal_config()
&& n != "peerlatency" && n != "tlpkdrop" && n != "connect_timeout"
&& n != "sendbuf" && n != "recvbuf" && n != "payloadsize"
&& n != "default_app" && n != "sei_filter" && n != "mix_correct"
&& n != "tlpktdrop" && n != "tsbpdmode") {
&& n != "tlpktdrop" && n != "tsbpdmode" && n != "passphrase" && n != "pbkeylen") {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal srt_server.%s", n.c_str());
}
}
@ -7768,6 +7768,40 @@ int SrsConfig::get_srto_payloadsize()
return atoi(conf->arg0().c_str());
}
string SrsConfig::get_srto_passphrase()
{
SRS_OVERWRITE_BY_ENV_STRING("srs.srt_server.passphrase");
static string DEFAULT = "";
SrsConfDirective* conf = root->get("srt_server");
if (!conf) {
return DEFAULT;
}
conf = conf->get("passphrase");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
return conf->arg0();
}
int SrsConfig::get_srto_pbkeylen()
{
SRS_OVERWRITE_BY_ENV_INT("srs.srt_server.pbkeylen");
static int DEFAULT = 0;
SrsConfDirective* conf = root->get("srt_server");
if (!conf) {
return DEFAULT;
}
conf = conf->get("pbkeylen");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
return atoi(conf->arg0().c_str());
}
string SrsConfig::get_default_app_name()
{
SRS_OVERWRITE_BY_ENV_STRING("srs.srt_server.default_app");

View file

@ -684,6 +684,10 @@ public:
virtual int get_srto_recvbuf();
// SRTO_PAYLOADSIZE
virtual int get_srto_payloadsize();
// Get the srt SRTO_PASSPHRASE, default is empty.
virtual std::string get_srto_passphrase();
// Get the srt SRTO_PBKEYLEN, default is 0.
virtual int get_srto_pbkeylen();
// Get the default app.
virtual std::string get_default_app_name();
private:

View file

@ -66,51 +66,63 @@ srs_error_t SrsSrtAcceptor::set_srt_opt()
srs_error_t err = srs_success;
if ((err = srs_srt_set_maxbw(listener_->fd(), _srs_config->get_srto_maxbw())) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt maxbw=%d failed", _srs_config->get_srto_maxbw());
}
if ((err = srs_srt_set_mss(listener_->fd(), _srs_config->get_srto_mss())) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt mss=%d failed", _srs_config->get_srto_mss());
}
if ((err = srs_srt_set_tsbpdmode(listener_->fd(), _srs_config->get_srto_tsbpdmode())) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt tsbpdmode=%d failed", _srs_config->get_srto_tsbpdmode());
}
if ((err = srs_srt_set_latency(listener_->fd(), _srs_config->get_srto_latency())) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt latency=%d failed", _srs_config->get_srto_latency());
}
if ((err = srs_srt_set_rcv_latency(listener_->fd(), _srs_config->get_srto_recv_latency())) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt recvlatency=%d failed", _srs_config->get_srto_recv_latency());
}
if ((err = srs_srt_set_peer_latency(listener_->fd(), _srs_config->get_srto_peer_latency())) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt peerlatency=%d failed", _srs_config->get_srto_peer_latency());
}
if ((err = srs_srt_set_tlpktdrop(listener_->fd(), _srs_config->get_srto_tlpktdrop())) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt tlpkdrop=%d failed", _srs_config->get_srto_tlpktdrop());
}
if ((err = srs_srt_set_connect_timeout(listener_->fd(), srsu2msi(_srs_config->get_srto_conntimeout()))) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt connect_timeout=%d failed", _srs_config->get_srto_conntimeout());
}
if ((err = srs_srt_set_peer_idle_timeout(listener_->fd(), srsu2msi(_srs_config->get_srto_peeridletimeout()))) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt peer_idle_timeout=%d failed", _srs_config->get_srto_peeridletimeout());
}
if ((err = srs_srt_set_sndbuf(listener_->fd(), _srs_config->get_srto_sendbuf())) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt sendbuf=%d failed", _srs_config->get_srto_sendbuf());
}
if ((err = srs_srt_set_rcvbuf(listener_->fd(), _srs_config->get_srto_recvbuf())) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt recvbuf=%d failed", _srs_config->get_srto_recvbuf());
}
if ((err = srs_srt_set_payload_size(listener_->fd(), _srs_config->get_srto_payloadsize())) != srs_success) {
return srs_error_wrap(err, "set opt");
return srs_error_wrap(err, "set opt payload_size=%d failed", _srs_config->get_srto_payloadsize());
}
string passphrase = _srs_config->get_srto_passphrase();
if (! passphrase.empty()) {
if ((err = srs_srt_set_passphrase(listener_->fd(), passphrase)) != srs_success) {
return srs_error_wrap(err, "set opt passphrase=%s failed", passphrase.c_str());
}
int pbkeylen = _srs_config->get_srto_pbkeylen();
if ((err = srs_srt_set_pbkeylen(listener_->fd(), pbkeylen)) != srs_success) {
return srs_error_wrap(err, "set opt pbkeylen=%d failed", pbkeylen);
}
}
return err;

View file

@ -299,6 +299,18 @@ srs_error_t srs_srt_set_streamid(srs_srt_t srt_fd, const std::string& streamid)
return srs_success;
}
srs_error_t srs_srt_set_passphrase(srs_srt_t srt_fd, const std::string& passphrase)
{
SET_SRT_OPT_STR(srt_fd, SRTO_PASSPHRASE, passphrase.data(), passphrase.size());
return srs_success;
}
srs_error_t srs_srt_set_pbkeylen(srs_srt_t srt_fd, int pbkeylen)
{
SET_SRT_OPT(srt_fd, SRTO_PBKEYLEN, pbkeylen);
return srs_success;
}
srs_error_t srs_srt_get_maxbw(srs_srt_t srt_fd, int& maxbw)
{
GET_SRT_OPT(srt_fd, SRTO_MAXBW, maxbw);

View file

@ -47,6 +47,8 @@ extern srs_error_t srs_srt_set_latency(srs_srt_t srt_fd, int latency);
extern srs_error_t srs_srt_set_rcv_latency(srs_srt_t srt_fd, int rcv_latency);
extern srs_error_t srs_srt_set_peer_latency(srs_srt_t srt_fd, int peer_latency);
extern srs_error_t srs_srt_set_streamid(srs_srt_t srt_fd, const std::string& streamid);
extern srs_error_t srs_srt_set_passphrase(srs_srt_t srt_fd, const std::string& passphrase);
extern srs_error_t srs_srt_set_pbkeylen(srs_srt_t srt_fd, int pbkeylen);
// Get SRT options.
extern srs_error_t srs_srt_get_maxbw(srs_srt_t srt_fd, int& maxbw);

View file

@ -20,6 +20,8 @@ using namespace std;
extern SrsSrtEventLoop* _srt_eventloop;
// TODO: FIXME: set srt log handler.
// Test srt st service
VOID TEST(ServiceSrtPoller, SrtPollOperateSocket)
{
@ -146,6 +148,10 @@ public:
return err;
}
srs_srt_t fd() {
return srt_server_fd_;
}
srs_error_t listen(std::string ip, int port) {
srs_error_t err = srs_success;
@ -463,6 +469,82 @@ VOID TEST(ProtocolSrtTest, SrtStreamIdToRequest)
}
}
VOID TEST(ServiceSRTTest, Encrypt)
{
srs_error_t err = srs_success;
std::string server_ip = "127.0.0.1";
int server_port = 19000;
MockSrtServer srt_server;
HELPER_EXPECT_SUCCESS(srt_server.create_socket());
string passphrase = "srt_passphrase";
HELPER_EXPECT_SUCCESS(srs_srt_set_passphrase(srt_server.fd(), passphrase));
HELPER_EXPECT_SUCCESS(srt_server.listen(server_ip, server_port));
std::string streamid = "SRS_SRT_Streamid";
if (true) {
srs_srt_t srt_client_fd = srs_srt_socket_invalid();
HELPER_EXPECT_SUCCESS(srs_srt_socket_with_default_option(&srt_client_fd));
HELPER_EXPECT_SUCCESS(srs_srt_set_streamid(srt_client_fd, streamid));
SrsSrtSocket* srt_client_socket = new SrsSrtSocket(_srt_eventloop->poller(), srt_client_fd);
// SRT connect without passphrase, will reject.
HELPER_EXPECT_FAILED(srt_client_socket->connect(server_ip, server_port));
}
if (true) {
srs_srt_t srt_client_fd = srs_srt_socket_invalid();
HELPER_EXPECT_SUCCESS(srs_srt_socket_with_default_option(&srt_client_fd));
HELPER_EXPECT_SUCCESS(srs_srt_set_streamid(srt_client_fd, streamid));
HELPER_EXPECT_SUCCESS(srs_srt_set_passphrase(srt_client_fd, "wrong_passphrase"));
SrsSrtSocket* srt_client_socket = new SrsSrtSocket(_srt_eventloop->poller(), srt_client_fd);
// SRT connect with wrong passphrase, will reject.
HELPER_EXPECT_FAILED(srt_client_socket->connect(server_ip, server_port));
}
if (true) {
srs_srt_t srt_client_fd = srs_srt_socket_invalid();
HELPER_EXPECT_SUCCESS(srs_srt_socket_with_default_option(&srt_client_fd));
HELPER_EXPECT_SUCCESS(srs_srt_set_streamid(srt_client_fd, streamid));
// Set correct passphrase.
HELPER_EXPECT_SUCCESS(srs_srt_set_passphrase(srt_client_fd, passphrase));
SrsSrtSocket* srt_client_socket = new SrsSrtSocket(_srt_eventloop->poller(), srt_client_fd);
HELPER_EXPECT_SUCCESS(srt_client_socket->connect(server_ip, server_port));
srs_srt_t srt_server_accepted_fd = srs_srt_socket_invalid();
HELPER_EXPECT_SUCCESS(srt_server.accept(&srt_server_accepted_fd));
EXPECT_NE(srt_server_accepted_fd, srs_srt_socket_invalid());
std::string s;
HELPER_EXPECT_SUCCESS(srs_srt_get_streamid(srt_server_accepted_fd, s));
EXPECT_EQ(s, streamid);
}
if (true) {
int pbkeylens[4] = {0, 16, 24, 32};
for (int i = 0; i < sizeof(pbkeylens) / sizeof(pbkeylens[0]); ++i) {
srs_srt_t srt_client_fd = srs_srt_socket_invalid();
HELPER_EXPECT_SUCCESS(srs_srt_socket_with_default_option(&srt_client_fd));
HELPER_EXPECT_SUCCESS(srs_srt_set_streamid(srt_client_fd, streamid));
// Set correct passphrase.
HELPER_EXPECT_SUCCESS(srs_srt_set_passphrase(srt_client_fd, passphrase));
// Set different pbkeylen.
HELPER_EXPECT_SUCCESS(srs_srt_set_pbkeylen(srt_client_fd, pbkeylens[i]));
SrsSrtSocket* srt_client_socket = new SrsSrtSocket(_srt_eventloop->poller(), srt_client_fd);
HELPER_EXPECT_SUCCESS(srt_client_socket->connect(server_ip, server_port));
srs_srt_t srt_server_accepted_fd = srs_srt_socket_invalid();
HELPER_EXPECT_SUCCESS(srt_server.accept(&srt_server_accepted_fd));
EXPECT_NE(srt_server_accepted_fd, srs_srt_socket_invalid());
std::string s;
HELPER_EXPECT_SUCCESS(srs_srt_get_streamid(srt_server_accepted_fd, s));
EXPECT_EQ(s, streamid);
}
}
}
// TODO: FIXME: add mpegts conn test
// set srt option, recv srt client, get srt client opt and check.