1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

Merge branch 'develop' into merge/develop

This commit is contained in:
winlin 2021-03-24 11:01:19 +08:00
commit 719fc7cf85
17 changed files with 190 additions and 44 deletions

View file

@ -188,6 +188,11 @@ Other documents:
<a name="history"></a>
<a name="change-logs"></a>
## V5 changes
* v5.0, 2021-03-17, Live: Refine edge to follow client and HTTP/302. 5.0.1
* v5.0, 2021-03-15, Init SRS/5. 5.0.0
## V4 changes
* v4.0, 2021-03-09, DTLS: Fix ARQ bug, use openssl timeout. 4.0.84

View file

@ -708,6 +708,11 @@ vhost cluster.srs.com {
# flvs, Connect origin by HTTPS-FLV
# Default: rtmp
protocol rtmp;
# Whether follow client protocol to connect to origin.
# @remark The FLV might use different signature(in query string) to RTMP.
# Default: off
follow_client off;
}
}

2
trunk/configure vendored
View file

@ -204,7 +204,7 @@ fi
MODULE_ID="CORE"
MODULE_DEPENDS=()
ModuleLibIncs=(${SRS_OBJS_DIR})
MODULE_FILES=("srs_core" "srs_core_version4" "srs_core_autofree" "srs_core_performance"
MODULE_FILES=("srs_core" "srs_core_version5" "srs_core_autofree" "srs_core_performance"
"srs_core_time")
CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . auto/modules.sh
CORE_OBJS="${MODULE_OBJS[@]}"

View file

@ -3829,7 +3829,7 @@ srs_error_t SrsConfig::check_normal_config()
for (int j = 0; j < (int)conf->directives.size(); j++) {
string m = conf->at(j)->name;
if (m != "mode" && m != "origin" && m != "token_traverse" && m != "vhost" && m != "debug_srs_upnode" && m != "coworkers"
&& m != "origin_cluster" && m != "protocol") {
&& m != "origin_cluster" && m != "protocol" && m != "follow_client") {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.cluster.%s of %s", m.c_str(), vhost->arg0().c_str());
}
}
@ -6218,6 +6218,28 @@ string SrsConfig::get_vhost_edge_protocol(string vhost)
return conf->arg0();
}
bool SrsConfig::get_vhost_edge_follow_client(string vhost)
{
static bool DEFAULT = false;
SrsConfDirective* conf = get_vhost(vhost);
if (!conf) {
return DEFAULT;
}
conf = conf->get("cluster");
if (!conf) {
return DEFAULT;
}
conf = conf->get("follow_client");
if (!conf) {
return DEFAULT;
}
return SRS_CONF_PERFER_FALSE(conf->arg0());
}
bool SrsConfig::get_vhost_edge_token_traverse(string vhost)
{
static bool DEFAULT = false;

View file

@ -775,6 +775,8 @@ public:
virtual SrsConfDirective* get_vhost_edge_origin(std::string vhost);
// Get the procotol to connect to origin server.
virtual std::string get_vhost_edge_protocol(std::string vhost);
// Whether follow client protocol to connect to origin.
virtual bool get_vhost_edge_follow_client(std::string vhost);
// Whether edge token tranverse is enabled,
// If true, edge will send connect origin to verfy the token of client.
// For example, we verify all clients on the origin FMS by server-side as,

View file

@ -183,6 +183,7 @@ SrsEdgeFlvUpstream::SrsEdgeFlvUpstream(std::string schema)
hr_ = NULL;
reader_ = NULL;
decoder_ = NULL;
req_ = NULL;
}
SrsEdgeFlvUpstream::~SrsEdgeFlvUpstream()
@ -191,12 +192,24 @@ SrsEdgeFlvUpstream::~SrsEdgeFlvUpstream()
}
srs_error_t SrsEdgeFlvUpstream::connect(SrsRequest* r, SrsLbRoundRobin* lb)
{
// Because we might modify the r, which cause retry fail, so we must copy it.
SrsRequest* cp = r->copy();
// Free the request when close upstream.
srs_freep(req_);
req_ = cp;
return do_connect(cp, lb, 0);
}
srs_error_t SrsEdgeFlvUpstream::do_connect(SrsRequest* r, SrsLbRoundRobin* lb, int redirect_depth)
{
srs_error_t err = srs_success;
SrsRequest* req = r;
if (true) {
if (redirect_depth == 0) {
SrsConfDirective* conf = _srs_config->get_vhost_edge_origin(req->vhost);
// @see https://github.com/ossrs/srs/issues/79
@ -217,12 +230,20 @@ srs_error_t SrsEdgeFlvUpstream::connect(SrsRequest* r, SrsLbRoundRobin* lb)
// Remember the current selected server.
selected_ip = server;
selected_port = port;
} else {
// If HTTP redirect, use the server in location.
schema_ = req->schema;
selected_ip = req->host;
selected_port = req->port;
}
srs_freep(sdk_);
sdk_ = new SrsHttpClient();
string path = "/" + req->app + "/" + req->stream + ".flv";
string path = "/" + req->app + "/" + req->stream;
if (!srs_string_ends_with(req->stream, ".flv")) {
path += ".flv";
}
if (!req->param.empty()) {
path += req->param;
}
@ -240,6 +261,37 @@ srs_error_t SrsEdgeFlvUpstream::connect(SrsRequest* r, SrsLbRoundRobin* lb)
return srs_error_wrap(err, "edge get %s failed, path=%s", url.c_str(), path.c_str());
}
if (hr_->status_code() == 404) {
return srs_error_new(ERROR_RTMP_STREAM_NOT_FOUND, "Connect to %s, status=%d", url.c_str(), hr_->status_code());
}
string location;
if (hr_->status_code() == 302) {
location = hr_->header()->get("Location");
}
srs_trace("Edge: Connect to %s ok, status=%d, location=%s", url.c_str(), hr_->status_code(), location.c_str());
if (hr_->status_code() == 302) {
if (redirect_depth >= 3) {
return srs_error_new(ERROR_HTTP_302_INVALID, "redirect to %s fail, depth=%d", location.c_str(), redirect_depth);
}
string app;
string stream_name;
if (true) {
string tcUrl;
srs_parse_rtmp_url(location, tcUrl, stream_name);
int port;
string schema, host, vhost, param;
srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream_name, port, param);
r->schema = schema; r->host = host; r->port = port;
r->app = app; r->stream = stream_name; r->param = param;
}
return do_connect(r, lb, redirect_depth + 1);
}
srs_freep(reader_);
reader_ = new SrsHttpFileReader(hr_->body_reader());
@ -330,6 +382,7 @@ void SrsEdgeFlvUpstream::close()
srs_freep(hr_);
srs_freep(reader_);
srs_freep(decoder_);
srs_freep(req_);
}
void SrsEdgeFlvUpstream::selected(string& server, int& port)
@ -446,8 +499,17 @@ srs_error_t SrsEdgeIngester::do_cycle()
return srs_error_wrap(err, "do cycle pull");
}
srs_freep(upstream);
// Use protocol in config.
string edge_protocol = _srs_config->get_vhost_edge_protocol(req->vhost);
// If follow client protocol, change to protocol of client.
bool follow_client = _srs_config->get_vhost_edge_follow_client(req->vhost);
if (follow_client && !req->protocol.empty()) {
edge_protocol = req->protocol;
}
// Create object by protocol.
srs_freep(upstream);
if (edge_protocol == "flv" || edge_protocol == "flvs") {
upstream = new SrsEdgeFlvUpstream(edge_protocol == "flv"? "http" : "https");
} else {

View file

@ -127,6 +127,8 @@ private:
SrsHttpFileReader* reader_;
SrsFlvDecoder* decoder_;
private:
// We might modify the request by HTTP redirect.
SrsRequest* req_;
// Current selected server, the ip:port.
std::string selected_ip;
int selected_port;
@ -135,6 +137,9 @@ public:
virtual ~SrsEdgeFlvUpstream();
public:
virtual srs_error_t connect(SrsRequest* r, SrsLbRoundRobin* lb);
private:
virtual srs_error_t do_connect(SrsRequest* r, SrsLbRoundRobin* lb, int redirect_depth);
public:
virtual srs_error_t recv_message(SrsCommonMessage** pmsg);
virtual srs_error_t decode_message(SrsCommonMessage* msg, SrsPacket** ppacket);
virtual void close();

View file

@ -1327,12 +1327,7 @@ srs_error_t SrsRtcPublishStream::send_periodic_twcc()
return srs_error_wrap(err, "encode, count=%u", twcc_fb_count_);
}
int nb_protected_buf = buffer->pos();
if ((err = session_->transport_->protect_rtcp(pkt, &nb_protected_buf)) != srs_success) {
return srs_error_wrap(err, "protect rtcp, size=%u", nb_protected_buf);
}
return session_->sendonly_skt->sendto(pkt, nb_protected_buf, 0);
return session_->send_rtcp(pkt, buffer->pos());
}
srs_error_t SrsRtcPublishStream::on_rtcp(SrsRtcpCommon* rtcp)
@ -2366,17 +2361,11 @@ void SrsRtcConnection::check_send_nacks(SrsRtpNackForReceiver* nack, uint32_t ss
rtcpNack.encode(&stream);
// TODO: FIXME: Check error.
int nb_protected_buf = stream.pos();
transport_->protect_rtcp(stream.data(), &nb_protected_buf);
// TODO: FIXME: Check error.
sendonly_skt->sendto(stream.data(), nb_protected_buf, 0);
send_rtcp(stream.data(), stream.pos());
}
srs_error_t SrsRtcConnection::send_rtcp_rr(uint32_t ssrc, SrsRtpRingBuffer* rtp_queue, const uint64_t& last_send_systime, const SrsNtp& last_send_ntp)
{
srs_error_t err = srs_success;
++_srs_pps_srtcps->sugar;
// @see https://tools.ietf.org/html/rfc3550#section-6.4.2
@ -2412,18 +2401,11 @@ srs_error_t SrsRtcConnection::send_rtcp_rr(uint32_t ssrc, SrsRtpRingBuffer* rtp_
srs_info("RR ssrc=%u, fraction_lost=%u, cumulative_number_of_packets_lost=%u, extended_highest_sequence=%u, interarrival_jitter=%u",
ssrc, fraction_lost, cumulative_number_of_packets_lost, extended_highest_sequence, interarrival_jitter);
int nb_protected_buf = stream.pos();
if ((err = transport_->protect_rtcp(stream.data(), &nb_protected_buf)) != srs_success) {
return srs_error_wrap(err, "protect rtcp rr");
}
return sendonly_skt->sendto(stream.data(), nb_protected_buf, 0);
return send_rtcp(stream.data(), stream.pos());
}
srs_error_t SrsRtcConnection::send_rtcp_xr_rrtr(uint32_t ssrc)
{
srs_error_t err = srs_success;
++_srs_pps_srtcps->sugar;
/*
@ -2466,18 +2448,11 @@ srs_error_t SrsRtcConnection::send_rtcp_xr_rrtr(uint32_t ssrc)
stream.write_4bytes(cur_ntp.ntp_second_);
stream.write_4bytes(cur_ntp.ntp_fractions_);
int nb_protected_buf = stream.pos();
if ((err = transport_->protect_rtcp(stream.data(), &nb_protected_buf)) != srs_success) {
return srs_error_wrap(err, "protect rtcp xr");
}
return sendonly_skt->sendto(stream.data(), nb_protected_buf, 0);
return send_rtcp(stream.data(), stream.pos());
}
srs_error_t SrsRtcConnection::send_rtcp_fb_pli(uint32_t ssrc, const SrsContextId& cid_of_subscriber)
{
srs_error_t err = srs_success;
++_srs_pps_srtcps->sugar;
char buf[kRtpPacketSize];
@ -2498,12 +2473,7 @@ srs_error_t SrsRtcConnection::send_rtcp_fb_pli(uint32_t ssrc, const SrsContextId
_srs_blackhole->sendto(stream.data(), stream.pos());
}
int nb_protected_buf = stream.pos();
if ((err = transport_->protect_rtcp(stream.data(), &nb_protected_buf)) != srs_success) {
return srs_error_wrap(err, "protect rtcp psfb pli");
}
return sendonly_skt->sendto(stream.data(), nb_protected_buf, 0);
return send_rtcp(stream.data(), stream.pos());
}
void SrsRtcConnection::simulate_nack_drop(int nn)

View file

@ -25,10 +25,7 @@
#define SRS_CORE_HPP
// The version config.
#define VERSION_MAJOR 4
#define VERSION_MINOR 0
#include <srs_core_version4.hpp>
#define VERSION_REVISION SRS_VERSION4_REVISION
#include <srs_core_version5.hpp>
// The macros generated by configure script.
#include <srs_auto_headers.hpp>

View file

@ -24,6 +24,8 @@
#ifndef SRS_CORE_VERSION3_HPP
#define SRS_CORE_VERSION3_HPP
#define VERSION_MAJOR 3
#define VERSION_MINOR 0
#define SRS_VERSION3_REVISION 158
#endif

View file

@ -24,6 +24,8 @@
#ifndef SRS_CORE_VERSION4_HPP
#define SRS_CORE_VERSION4_HPP
#define VERSION_MAJOR 4
#define VERSION_MINOR 0
#define SRS_VERSION4_REVISION 85
#endif

View file

@ -0,0 +1,24 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 Winlin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <srs_core_version4.hpp>

View file

@ -0,0 +1,31 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 Winlin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SRS_CORE_VERSION5_HPP
#define SRS_CORE_VERSION5_HPP
#define VERSION_MAJOR 5
#define VERSION_MINOR 0
#define VERSION_REVISION 1
#endif

View file

@ -106,6 +106,10 @@ void srs_discovery_tc_url(string tcUrl, string& schema, string& host, string& vh
}
port = SRS_CONSTS_RTMP_DEFAULT_PORT;
if (schema == "https") {
port = SRS_DEFAULT_HTTPS_PORT;
}
if ((pos = host.find(":")) != std::string::npos) {
srs_parse_hostport(host, host, port);
srs_info("discovery host=%s, port=%d", host.c_str(), port);

View file

@ -1578,6 +1578,8 @@ SrsRequest::SrsRequest()
duration = -1;
port = SRS_CONSTS_RTMP_DEFAULT_PORT;
args = NULL;
protocol = "rtmp";
}
SrsRequest::~SrsRequest()
@ -1605,6 +1607,8 @@ SrsRequest* SrsRequest::copy()
if (args) {
cp->args = args->copy()->to_object();
}
cp->protocol = protocol;
return cp;
}
@ -1632,6 +1636,8 @@ void SrsRequest::update_auth(SrsRequest* req)
if (req->args) {
args = req->args->copy()->to_object();
}
protocol = req->protocol;
srs_info("update req of soruce for auth ok");
}

View file

@ -489,6 +489,12 @@ public:
public:
// Transform it as HTTP request.
virtual SrsRequest* as_http();
public:
// The protocol of client:
// rtmp, Adobe RTMP protocol.
// flv, HTTP-FLV protocol.
// flvs, HTTPS-FLV protocol.
std::string protocol;
};
// The response to client.

View file

@ -680,6 +680,9 @@ SrsRequest* SrsHttpMessage::to_request(string vhost)
if (!oip.empty()) {
req->ip = oip;
}
// The request streaming protocol.
req->protocol = (schema_ == "http")? "flv" : "flvs";
return req;
}