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:
commit
719fc7cf85
17 changed files with 190 additions and 44 deletions
|
@ -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
|
||||
|
|
|
@ -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
2
trunk/configure
vendored
|
@ -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[@]}"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
24
trunk/src/core/srs_core_version5.cpp
Normal file
24
trunk/src/core/srs_core_version5.cpp
Normal 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>
|
31
trunk/src/core/srs_core_version5.hpp
Normal file
31
trunk/src/core/srs_core_version5.hpp
Normal 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
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue