From 33fa43c1184f61900eadaec012fd966a7b84a746 Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 15 Mar 2021 14:11:34 +0800 Subject: [PATCH 1/5] Init SRS/5. 5.0.0 --- README.md | 54 +++++++++++++++++----------- trunk/configure | 2 +- trunk/src/core/srs_core.hpp | 5 +-- trunk/src/core/srs_core_version3.hpp | 2 ++ trunk/src/core/srs_core_version4.hpp | 2 ++ trunk/src/core/srs_core_version5.cpp | 24 +++++++++++++ trunk/src/core/srs_core_version5.hpp | 31 ++++++++++++++++ 7 files changed, 95 insertions(+), 25 deletions(-) create mode 100644 trunk/src/core/srs_core_version5.cpp create mode 100644 trunk/src/core/srs_core_version5.hpp diff --git a/README.md b/README.md index f76b13bbc..e009cedb9 100755 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ Other documents: - [x] Edge server supports remuxing RTMP to HTTP-FLV([CN][v3_CN_SampleHttpFlv], [EN][v3_EN_SampleHttpFlv]). As for HLS([CN][v3_CN_DeliveryHLS], [EN][v3_EN_DeliveryHLS]) edge server, recomment to use HTTP edge server, such as [NGINX](http://nginx.org/). - [x] Support HLS with audio-only([CN][v3_CN_DeliveryHLS2], [EN][v3_EN_DeliveryHLS2]), which need to build the timestamp from AAC samples, so we enhanced it please read [#547][bug #547]. - [x] Support HLS with mp3(h.264+mp3) audio codec, please read [bug #301][bug #301]. -- [x] Support remuxing RTMP to http FLV/MP3/AAC/TS live streaming, please read wiki([CN][v2_CN_DeliveryHttpStream], [EN][v2_CN_DeliveryHttpStream]). +- [x] Support transmux RTMP to HTTP-FLV/MP3/AAC/TS, please read wiki([CN][v2_CN_DeliveryHttpStream], [EN][v2_CN_DeliveryHttpStream]). - [x] Support ingesting([CN][v1_CN_Ingest], [EN][v1_EN_Ingest]) other protocols to SRS by FFMPEG. - [x] Support RTMP long time(>4.6hours) publishing/playing, with the timestamp corrected. - [x] Support publishing h264 raw stream([CN][v3_CN_SrsLibrtmp2], [EN][v3_EN_SrsLibrtmp2]) by srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp]). @@ -140,42 +140,46 @@ Other documents: - [x] Support Vhost([CN][v1_CN_RtmpUrlVhost], [EN][v1_EN_RtmpUrlVhost]) and \_\_defaultVhost\_\_. - [x] Support reloading([CN][v1_CN_Reload], [EN][v1_EN_Reload]) to apply changes of config. - [x] Support listening at multiple ports. -- [x] Support forwarding([CN][v3_CN_Forward], [EN][v3_EN_Forward]) from master to slave server. -- [x] Support transcoding([CN][v3_CN_FFMPEG], [EN][v3_EN_FFMPEG]) live streaming by FFMPEG. +- [x] Support forwarding([CN][v3_CN_Forward], [EN][v3_EN_Forward]) to other RTMP servers. +- [x] Support transcoding([CN][v3_CN_FFMPEG], [EN][v3_EN_FFMPEG]) by FFMPEG. - [x] All wikis are writen in [Chinese][v3_CN_Home] and [English][v3_EN_Home]. - [x] Enhanced json, replace NXJSON(LGPL) with json-parser(BSD), read [#904][bug #904]. - [x] Support valgrind and latest ARM by patching ST, read [ST#1](https://github.com/ossrs/state-threads/issues/1) and [ST#2](https://github.com/ossrs/state-threads/issues/2). -- [x] Support tracable and session-based log([CN][v1_CN_SrsLog], [EN][v1_EN_SrsLog]). -- [x] High concurrency and performance([CN][v1_CN_Performance], [EN][v1_EN_Performance]), 6000+ connections(200kbps), CPU 82%, 203MB. +- [x] Support traceable and session-based log([CN][v1_CN_SrsLog], [EN][v1_EN_SrsLog]). +- [x] High performance([CN][v1_CN_Performance], [EN][v1_EN_Performance]) RTMP/HTTP-FLV, 6000+ connections. - [x] Enhanced complex error code with description and stack, read [#913][bug #913]. - [x] Enhanced RTMP url which supports vhost in stream, read [#1059][bug #1059]. - [x] Support origin cluster, please read [#464][bug #464], [RTMP 302][bug #92]. - [x] Support listen at IPv4 and IPv6, read [#460][bug #460]. -- [x] Support SO_REUSEPORT, to improve edge server performance, read [#775][bug #775]. - [x] Improve test coverage for core/kernel/protocol/service. -- [x] [Experimental] Support docker by [srs-docker](https://github.com/ossrs/srs-docker). +- [x] Support docker by [srs-docker](https://github.com/ossrs/srs-docker). +- [x] Support multiple processes by ReusePort([CN][v3_CN_REUSEPORT], [EN][v3_EN_REUSEPORT]), [#775][bug #775]. +- [x] Support a simple [mgmt console][console], please read [srs-ngb][srs-ngb]. +- [x] [Experimental] Support playing stream by WebRTC, [#307][bug #307]. +- [x] [Experimental] Support publishing stream by WebRTC, [#307][bug #307]. +- [x] [Experimental] Support mux RTP/RTCP/DTLS/SRTP on one port for WebRTC, [#307][bug #307]. +- [x] [Experimental] Support client address changing for WebRTC, [#307][bug #307]. +- [x] [Experimental] Support transcode RTMP/AAC to WebRTC/Opus, [#307][bug #307]. +- [x] [Experimental] Enhance HTTP Stream Server for HTTP-FLV, HTTPS, HLS etc. [#1657][bug #1657]. +- [x] [Experimental] Support push stream by GB28181, [#1500][bug #1500]. - [x] [Experimental] Support DVR in MP4 format, read [#738][bug #738]. - [x] [Experimental] Support MPEG-DASH, the future live streaming protocol, read [#299][bug #299]. - [x] [Experimental] Support pushing MPEG-TS over UDP, please read [bug #250][bug #250]. - [x] [Experimental] Support pushing RTSP, please read [bug #133][bug #133]. -- [x] [Experimental] Support pushing FLV over HTTP POST, please read [wiki]([CN][v2_CN_Streamer2], [EN][v2_EN_Streamer2]). -- [x] [Experimental] Support multiple processes by [dolphin][srs-dolphin] or [oryx][oryx]. -- [x] [Experimental] Support a simple [mgmt console][console], please read [srs-ngb][srs-ngb]. -- [x] [Experimental] Support RTMP client library: srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp]) +- [x] [Experimental] Support pushing FLV over HTTP POST, please read wiki([CN][v2_CN_Streamer2], [EN][v2_EN_Streamer2]). - [x] [Experimental] Support HTTP RAW API, please read [#459][bug #459], [#470][bug #470], [#319][bug #319]. - [x] [Experimental] Support SRT server, read [#1147][bug #1147]. -- [x] [Experimental] Support playing stream by WebRTC, [#307][bug #307]. -- [x] [Experimental] Support publishing stream by WebRTC, [#307][bug #307]. -- [x] [Experimental] Support push stream by GB28181, [#1500][bug #1500]. -- [x] [Experimental] Enhance HTTP Stream Server for HTTP-FLV, HTTPS, HLS etc. [#1657][bug #1657]. +- [x] [Deprecated] Support RTMP client library: srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp]) - [x] [Deprecated] Support Adobe HDS(f4m), please read wiki([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]) and [#1535][bug #1535]. - [x] [Deprecated] Support bandwidth testing([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]), please read [#1535][bug #1535]. - [x] [Deprecated] Support Adobe FMS/AMS token traverse([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication, please read [#1535][bug #1535]. -- [ ] Enhanced forwarding with vhost and variables. -- [ ] Support source cleanup for idle streams. -- [ ] Support H.265 by pushing H.265 over RTMP, deliverying in HLS, read [#465][bug #465]. -- [ ] Support UDP protocol such as QUIC or KCP in cluster. -- [ ] Support H.264+Opus codec for WebRTC, [#307][bug #307]. +- [ ] Enhanced forwarding with vhost and variables, [#1342][bug #1342]. +- [ ] Support DVR to Cloud Storage, [#1193][bug #1193]. +- [ ] Support transmux RTC to RTMP, [#2093][bug #2093]. +- [ ] Support H.265 over RTMP and HLS, [#465][bug #465]. +- [ ] Support IETF-QUIC for WebRTC Cluster, [#2091][bug #2091]. +- [ ] Improve RTC performance to 5K by multiple threading, [#2188][bug #2188]. +- [ ] Support source cleanup for idle streams, [#413][bug #413]. - [ ] Support change user to run SRS, [#1111][bug #1111]. - [ ] Support HLS variant, [#463][bug #463]. @@ -184,6 +188,10 @@ Other documents: +## V5 changes + +* 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 @@ -1848,6 +1856,12 @@ Winlin [bug #1987]: https://github.com/ossrs/srs/issues/1987 [bug #1548]: https://github.com/ossrs/srs/issues/1548 [bug #1694]: https://github.com/ossrs/srs/issues/1694 +[bug #413]: https://github.com/ossrs/srs/issues/413 +[bug #2091]: https://github.com/ossrs/srs/issues/2091 +[bug #1342]: https://github.com/ossrs/srs/issues/1342 +[bug #2093]: https://github.com/ossrs/srs/issues/2093 +[bug #2188]: https://github.com/ossrs/srs/issues/2188 +[bug #1193]: https://github.com/ossrs/srs/issues/1193 [bug #yyyyyyyyyyyyy]: https://github.com/ossrs/srs/issues/yyyyyyyyyyyyy [bug #1631]: https://github.com/ossrs/srs/issues/1631 diff --git a/trunk/configure b/trunk/configure index 70a8319f9..9fba358e6 100755 --- a/trunk/configure +++ b/trunk/configure @@ -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[@]}" diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 0fbe07c39..af46019db 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -25,10 +25,7 @@ #define SRS_CORE_HPP // The version config. -#define VERSION_MAJOR 4 -#define VERSION_MINOR 0 -#include -#define VERSION_REVISION SRS_VERSION4_REVISION +#include // The macros generated by configure script. #include diff --git a/trunk/src/core/srs_core_version3.hpp b/trunk/src/core/srs_core_version3.hpp index b4c8f7273..dae57fe2f 100644 --- a/trunk/src/core/srs_core_version3.hpp +++ b/trunk/src/core/srs_core_version3.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 diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index ddca1c39d..0e7f31831 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -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 diff --git a/trunk/src/core/srs_core_version5.cpp b/trunk/src/core/srs_core_version5.cpp new file mode 100644 index 000000000..e5071d6ef --- /dev/null +++ b/trunk/src/core/srs_core_version5.cpp @@ -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 diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp new file mode 100644 index 000000000..5e6449255 --- /dev/null +++ b/trunk/src/core/srs_core_version5.hpp @@ -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 0 + +#endif From 35431749c431eb7b5e28d6cf4ec07157a577b67f Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 24 Dec 2020 18:59:29 +0800 Subject: [PATCH 2/5] Live: Support follow client protocol for edge. --- trunk/conf/full.conf | 5 ++++ trunk/src/app/srs_app_config.cpp | 24 +++++++++++++++++++- trunk/src/app/srs_app_config.hpp | 2 ++ trunk/src/app/srs_app_edge.cpp | 13 ++++++++++- trunk/src/protocol/srs_rtmp_stack.cpp | 6 +++++ trunk/src/protocol/srs_rtmp_stack.hpp | 6 +++++ trunk/src/protocol/srs_service_http_conn.cpp | 3 +++ 7 files changed, 57 insertions(+), 2 deletions(-) diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index e1b64f10d..70d199e4a 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -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; } } diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 7e538389b..cbf710c7a 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -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; diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 0ace96eb6..f880da403 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -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, diff --git a/trunk/src/app/srs_app_edge.cpp b/trunk/src/app/srs_app_edge.cpp index 64fbe61fa..20b0b39ed 100644 --- a/trunk/src/app/srs_app_edge.cpp +++ b/trunk/src/app/srs_app_edge.cpp @@ -240,6 +240,8 @@ 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()); } + srs_trace("Edge: Connect to %s ok", url.c_str()); + srs_freep(reader_); reader_ = new SrsHttpFileReader(hr_->body_reader()); @@ -446,8 +448,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 { diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index f80cf77cd..25c0b7acc 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -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"); } diff --git a/trunk/src/protocol/srs_rtmp_stack.hpp b/trunk/src/protocol/srs_rtmp_stack.hpp index 6f311383f..2f4741fe2 100644 --- a/trunk/src/protocol/srs_rtmp_stack.hpp +++ b/trunk/src/protocol/srs_rtmp_stack.hpp @@ -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. diff --git a/trunk/src/protocol/srs_service_http_conn.cpp b/trunk/src/protocol/srs_service_http_conn.cpp index d239972b2..49b3defdd 100644 --- a/trunk/src/protocol/srs_service_http_conn.cpp +++ b/trunk/src/protocol/srs_service_http_conn.cpp @@ -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; } From 4f1d213c91d658cf8366999a80aae8657949514a Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 17 Mar 2021 15:50:12 +0800 Subject: [PATCH 3/5] Live: Support follow HTTP/302 for HTTP/HTTPS FLV edge. --- trunk/src/app/srs_app_edge.cpp | 57 +++++++++++++++++++-- trunk/src/app/srs_app_edge.hpp | 5 ++ trunk/src/protocol/srs_protocol_utility.cpp | 4 ++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/trunk/src/app/srs_app_edge.cpp b/trunk/src/app/srs_app_edge.cpp index 20b0b39ed..9cdbaf5c4 100644 --- a/trunk/src/app/srs_app_edge.cpp +++ b/trunk/src/app/srs_app_edge.cpp @@ -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,7 +261,36 @@ 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()); } - srs_trace("Edge: Connect to %s ok", url.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()); @@ -332,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) diff --git a/trunk/src/app/srs_app_edge.hpp b/trunk/src/app/srs_app_edge.hpp index 80d9a1b31..6c50814d2 100644 --- a/trunk/src/app/srs_app_edge.hpp +++ b/trunk/src/app/srs_app_edge.hpp @@ -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(); diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp index ece4ef0bc..6b61aceb5 100644 --- a/trunk/src/protocol/srs_protocol_utility.cpp +++ b/trunk/src/protocol/srs_protocol_utility.cpp @@ -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); From 4329c7e7cbdacf4f44bdf6c1028925b884223b69 Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 17 Mar 2021 16:58:40 +0800 Subject: [PATCH 4/5] Live: Refine edge to follow client and HTTP/302. 5.0.1 --- README.md | 1 + trunk/src/core/srs_core_version5.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e009cedb9..5a7f7a13d 100755 --- a/README.md +++ b/README.md @@ -190,6 +190,7 @@ Other documents: ## 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 diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp index 5e6449255..7c598a58e 100644 --- a/trunk/src/core/srs_core_version5.hpp +++ b/trunk/src/core/srs_core_version5.hpp @@ -26,6 +26,6 @@ #define VERSION_MAJOR 5 #define VERSION_MINOR 0 -#define VERSION_REVISION 0 +#define VERSION_REVISION 1 #endif From 25145b945db4bb3247ee056b2609ef8584f0d24f Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 22 Mar 2021 16:25:08 +0800 Subject: [PATCH 5/5] RTC: Use send_rtcp to encrypt and send RTCP bytes --- trunk/src/app/srs_app_rtc_conn.cpp | 40 ++++-------------------------- 1 file changed, 5 insertions(+), 35 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index e6afab909..65fb9b421 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -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)