From 42e2135dd92b2c4bf406116506b39b6d4ed6ac53 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 4 Sep 2022 08:25:22 +0800 Subject: [PATCH] WebRTC: Support reuse HTTPS port for WebRTC over TCP. --- trunk/conf/full.conf | 20 ++++++++++++ trunk/doc/CHANGELOG.md | 1 + trunk/src/app/srs_app_config.cpp | 44 ++++++++++++++++++++++++++ trunk/src/app/srs_app_server.cpp | 47 +++++++++++++++++++--------- trunk/src/core/srs_core_version5.hpp | 2 +- 5 files changed, 98 insertions(+), 16 deletions(-) diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index f7e5ee80233..b174c96e075 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -116,6 +116,7 @@ auto_reload_for_docker on; # the rtmp listen ports, split by space, each listen entry is <[ip:]port> # for example, 192.168.1.100:1935 10.10.10.100:1935 # where the ip is optional, default to 0.0.0.0, that is 1935 equals to 0.0.0.0:1935 +# Overwrite by env SRS_LISTEN listen 1935; # the default chunk size is 128, max is 65536, # some client does not support chunk size change, @@ -135,12 +136,14 @@ chunk_size 60000; # where the cli can only be used in shell/terminate. http_api { # whether http api is enabled. + # Overwrite by env SRS_HTTP_API_ENABLED # default: off enabled on; # The http api listen entry is <[ip:]port>, For example, 192.168.1.100:8080, where the ip is optional, default to # 0.0.0.0, that is 8080 equals to 0.0.0.0:8080. # Note that you're able to use a dedicated port for HTTP API, such as 1985, to be different with HTTP server. In # this situation, you you must also set another HTTPS API port. + # Overwrite by env SRS_HTTP_API_LISTEN # Default: 1985 listen 8080; # whether enable crossdomain request. @@ -164,11 +167,13 @@ http_api { # For https_api or HTTPS API. https { # Whether enable HTTPS API. + # Overwrite by env SRS_HTTP_API_HTTPS_ENABLED # default: off enabled on; # The listen endpoint for HTTPS API. # Note that you're able to use a dedicated port for HTTPS API, such as 1990, and the HTTP API should not be # the same of HTTP server(8080) neither. + # Overwrite by env SRS_HTTP_API_HTTPS_LISTEN # Default: 1990 listen 8088; # The SSL private key file, generated by: @@ -193,12 +198,14 @@ http_api { # need to open the feature http of vhost. http_server { # whether http streaming service is enabled. + # Overwrite by env SRS_HTTP_SERVER_ENABLED # default: off enabled on; # the http streaming listen entry is <[ip:]port> # for example, 192.168.1.100:8080 # where the ip is optional, default to 0.0.0.0, that is 8080 equals to 0.0.0.0:8080 # @remark, if use lower port, for instance 80, user must start srs by root. + # Overwrite by env SRS_HTTP_SERVER_LISTEN # default: 8080 listen 8080; # the default dir for http root. @@ -211,9 +218,11 @@ http_server { # For https_server or HTTPS Streaming. https { # Whether enable HTTPS Streaming. + # Overwrite by env SRS_HTTP_SERVER_HTTTPS_ENABLED # default: off enabled on; # The listen endpoint for HTTPS Streaming. + # Overwrite by env SRS_HTTP_SERVER_HTTTPS_LISTEN # default: 8088 listen 8088; # The SSL private key file, generated by: @@ -297,9 +306,11 @@ vhost srt.vhost.srs.com { ############################################################################################# rtc_server { # Whether enable WebRTC server. + # Overwrite by env SRS_RTC_SERVER_ENABLED # default: off enabled on; # The udp listen port, we will reuse it for connections. + # Overwrite by env SRS_RTC_SERVER_LISTEN # default: 8000 listen 8000; # For WebRTC over TCP directly, not TURN, see https://github.com/ossrs/srs/issues/2852 @@ -329,11 +340,13 @@ rtc_server { # x.x.x.x A specified IP address or DNS name, use * if 0.0.0.0. # @remark For Firefox, the candidate MUST be IP, MUST NOT be DNS name, see https://bugzilla.mozilla.org/show_bug.cgi?id=1239006 # @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate + # Overwrite by env SRS_RTC_SERVER_CANDIDATE # default: * candidate *; # If candidate is * or 0.0.0.0, means SRS could detect IP automatically, filtered by ip_family. # You can config this to off to disable the detecting, then SRS will try to parse the API hostname. # Note that browser might fail if no CANDIDATE specified. + # Overwrite by env SRS_RTC_SERVER_USE_AUTO_DETECT_NETWORK_IP # Default: on use_auto_detect_network_ip on; # The IP family filter for auto discover candidate, it can be: @@ -341,20 +354,24 @@ rtc_server { # ipv6 Filter IP v6 candidates. # all Filter all IP v4 or v6 candidates. # For example, if set to ipv4, we only use the IPv4 address as candidate. + # Overwrite by env SRS_RTC_SERVER_IP_FAMILY # default: ipv4 ip_family ipv4; # If api_as_candidates is on, SRS would try to use the IP of api server, specified by srs.sdk.js request: # api:string "http://r.ossrs.net:1985/rtc/v1/play/" # in this case, the r.ossrs.net and 39.107.238.185 will be added as candidates. + # Overwrite by env SRS_RTC_SERVER_API_AS_CANDIDATES # Default: on api_as_candidates on; # If use api as CANDIDATE, whether resolve the api hostname. # Note that use original domain name as CANDIDATE, which might make Firefox failed, see https://bugzilla.mozilla.org/show_bug.cgi?id=1239006 # Note that if hostname is IPv4 address, always directly use it. + # Overwrite by env SRS_RTC_SERVER_RESOLVE_API_DOMAIN # Default: on resolve_api_domain on; # If use api as CANDIDATE, whether keep original api domain name as CANDIDATE. # Note that use original domain name as CANDIDATE, which might make Firefox failed, see https://bugzilla.mozilla.org/show_bug.cgi?id=1239006 + # Overwrite by env SRS_RTC_SERVER_KEEP_API_DOMAIN # Default: off keep_api_domain off; # Whether use ECDSA certificate. @@ -390,6 +407,7 @@ rtc_server { vhost rtc.vhost.srs.com { rtc { # Whether enable WebRTC server. + # Overwrite by env SRS_VHOST_RTC_ENABLED for all vhosts. # default: off enabled on; # Whether support NACK. @@ -420,6 +438,7 @@ vhost rtc.vhost.srs.com { ############################################################### # Whether enable transmuxing RTMP to RTC. # If enabled, transcode aac to opus. + # Overwrite by env SRS_VHOST_RTC_RTMP_TO_RTC for all vhosts. # default: off rtmp_to_rtc off; # Whether keep B-frame, which is normal feature in live streaming, @@ -428,6 +447,7 @@ vhost rtc.vhost.srs.com { keep_bframe off; ############################################################### # Whether enable transmuxing RTC to RTMP. + # Overwrite by env SRS_VHOST_RTC_RTC_TO_RTMP for all vhosts. # Default: off rtc_to_rtmp off; # The PLI interval in seconds, for RTC to RTMP. diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 2637c30804f..89c2e049953 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 5.0 Changelog +* v5.0, 2022-09-04, Fix [#2852](https://github.com/ossrs/srs/issues/2852): WebRTC: WebRTC over TCP directly, not TURN. v5.0.60 * v5.0, 2022-09-01, Fix [#1405](https://github.com/ossrs/srs/issues/1405): Restore the stream when parsing failed. v5.0.59 * v5.0, 2022-09-01, Fix [#1405](https://github.com/ossrs/srs/issues/1405): Support guessing IBMF first. v5.0.58 * v5.0, 2022-09-01, ST: Define and use a new jmpbuf. v5.0.57 diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 7aac3ad53ed..d8e181134eb 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -2868,6 +2868,12 @@ int SrsConfig::get_max_connections() vector SrsConfig::get_listens() { std::vector ports; + + // SRS_OVERWRITE_BY_ENV_STRING("SRS_LISTEN") + if (getenv("SRS_LISTEN")) { + ports.push_back(getenv("SRS_LISTEN")); + return ports; + } SrsConfDirective* conf = root->get("listen"); if (!conf) { @@ -3575,6 +3581,8 @@ bool SrsConfig::get_rtc_server_enabled() bool SrsConfig::get_rtc_server_enabled(SrsConfDirective* conf) { + SRS_OVERWRITE_BY_ENV_BOOL("SRS_RTC_SERVER_ENABLED"); + static bool DEFAULT = false; if (!conf) { @@ -3591,6 +3599,8 @@ bool SrsConfig::get_rtc_server_enabled(SrsConfDirective* conf) int SrsConfig::get_rtc_server_listen() { + SRS_OVERWRITE_BY_ENV_INT("SRS_RTC_SERVER_LISTEN"); + static int DEFAULT = 8000; SrsConfDirective* conf = root->get("rtc_server"); @@ -3608,6 +3618,8 @@ int SrsConfig::get_rtc_server_listen() std::string SrsConfig::get_rtc_server_candidates() { + SRS_OVERWRITE_BY_ENV_STRING("SRS_RTC_SERVER_CANDIDATE"); + static string DEFAULT = "*"; SrsConfDirective* conf = root->get("rtc_server"); @@ -3635,6 +3647,8 @@ std::string SrsConfig::get_rtc_server_candidates() bool SrsConfig::get_api_as_candidates() { + SRS_OVERWRITE_BY_ENV_BOOL2("SRS_RTC_SERVER_API_AS_CANDIDATES"); + static bool DEFAULT = true; SrsConfDirective* conf = root->get("rtc_server"); @@ -3652,6 +3666,8 @@ bool SrsConfig::get_api_as_candidates() bool SrsConfig::get_resolve_api_domain() { + SRS_OVERWRITE_BY_ENV_BOOL2("SRS_RTC_SERVER_RESOLVE_API_DOMAIN"); + static bool DEFAULT = true; SrsConfDirective* conf = root->get("rtc_server"); @@ -3669,6 +3685,8 @@ bool SrsConfig::get_resolve_api_domain() bool SrsConfig::get_keep_api_domain() { + SRS_OVERWRITE_BY_ENV_BOOL("SRS_RTC_SERVER_KEEP_API_DOMAIN"); + static bool DEFAULT = false; SrsConfDirective* conf = root->get("rtc_server"); @@ -3686,6 +3704,8 @@ bool SrsConfig::get_keep_api_domain() bool SrsConfig::get_use_auto_detect_network_ip() { + SRS_OVERWRITE_BY_ENV_BOOL2("SRS_RTC_SERVER_USE_AUTO_DETECT_NETWORK_IP"); + static bool DEFAULT = true; SrsConfDirective* conf = root->get("rtc_server"); @@ -3770,6 +3790,8 @@ std::string SrsConfig::get_rtc_server_protocol() std::string SrsConfig::get_rtc_server_ip_family() { + SRS_OVERWRITE_BY_ENV_STRING("SRS_RTC_SERVER_IP_FAMILY"); + static string DEFAULT = "ipv4"; SrsConfDirective* conf = root->get("rtc_server"); @@ -3919,6 +3941,8 @@ SrsConfDirective* SrsConfig::get_rtc(string vhost) bool SrsConfig::get_rtc_enabled(string vhost) { + SRS_OVERWRITE_BY_ENV_BOOL("SRS_VHOST_RTC_ENABLED"); + static bool DEFAULT = false; SrsConfDirective* conf = get_rtc(vhost); @@ -3955,6 +3979,8 @@ bool SrsConfig::get_rtc_keep_bframe(string vhost) bool SrsConfig::get_rtc_from_rtmp(string vhost) { + SRS_OVERWRITE_BY_ENV_BOOL("SRS_VHOST_RTC_RTMP_TO_RTC"); + static bool DEFAULT = false; SrsConfDirective* conf = get_rtc(vhost); @@ -4062,6 +4088,8 @@ int SrsConfig::get_rtc_drop_for_pt(string vhost) bool SrsConfig::get_rtc_to_rtmp(string vhost) { + SRS_OVERWRITE_BY_ENV_BOOL("SRS_VHOST_RTC_RTC_TO_RTMP"); + static bool DEFAULT = false; SrsConfDirective* conf = get_rtc(vhost); @@ -6686,6 +6714,8 @@ bool SrsConfig::get_http_api_enabled() bool SrsConfig::get_http_api_enabled(SrsConfDirective* conf) { + SRS_OVERWRITE_BY_ENV_BOOL("SRS_HTTP_API_ENABLED"); + static bool DEFAULT = false; if (!conf) { @@ -6702,6 +6732,8 @@ bool SrsConfig::get_http_api_enabled(SrsConfDirective* conf) string SrsConfig::get_http_api_listen() { + SRS_OVERWRITE_BY_ENV_STRING("SRS_HTTP_API_LISTEN"); + static string DEFAULT = "1985"; SrsConfDirective* conf = root->get("http_api"); @@ -6803,6 +6835,8 @@ SrsConfDirective* SrsConfig::get_https_api() bool SrsConfig::get_https_api_enabled() { + SRS_OVERWRITE_BY_ENV_BOOL("SRS_HTTP_API_HTTPS_ENABLED"); + static bool DEFAULT = false; SrsConfDirective* conf = get_https_api(); @@ -6820,6 +6854,8 @@ bool SrsConfig::get_https_api_enabled() string SrsConfig::get_https_api_listen() { + SRS_OVERWRITE_BY_ENV_STRING("SRS_HTTP_API_HTTPS_LISTEN"); + #ifdef SRS_UTEST // We should not use static default, because we need to reset for different testcase. string DEFAULT = ""; @@ -7178,6 +7214,8 @@ bool SrsConfig::get_http_stream_enabled() bool SrsConfig::get_http_stream_enabled(SrsConfDirective* conf) { + SRS_OVERWRITE_BY_ENV_BOOL("SRS_HTTP_SERVER_ENABLED"); + static bool DEFAULT = false; if (!conf) { @@ -7194,6 +7232,8 @@ bool SrsConfig::get_http_stream_enabled(SrsConfDirective* conf) string SrsConfig::get_http_stream_listen() { + SRS_OVERWRITE_BY_ENV_STRING("SRS_HTTP_SERVER_LISTEN"); + static string DEFAULT = "8080"; SrsConfDirective* conf = root->get("http_server"); @@ -7255,6 +7295,8 @@ SrsConfDirective* SrsConfig::get_https_stream() bool SrsConfig::get_https_stream_enabled() { + SRS_OVERWRITE_BY_ENV_BOOL("SRS_HTTP_SERVER_HTTTPS_ENABLED"); + static bool DEFAULT = false; SrsConfDirective* conf = get_https_stream(); @@ -7272,6 +7314,8 @@ bool SrsConfig::get_https_stream_enabled() string SrsConfig::get_https_stream_listen() { + SRS_OVERWRITE_BY_ENV_STRING("SRS_HTTP_SERVER_HTTTPS_LISTEN"); + static string DEFAULT = "8088"; SrsConfDirective* conf = get_https_stream(); diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 20ed47094e6..d041e86206e 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -659,22 +659,31 @@ srs_error_t SrsServer::initialize(ISrsServerCycle* ch) return srs_error_wrap(err, "handler initialize"); } + bool stream = _srs_config->get_http_stream_enabled(); + string http_listen = _srs_config->get_http_stream_listen(); + string https_listen = _srs_config->get_https_stream_listen(); + #ifdef SRS_RTC + bool rtc = _srs_config->get_rtc_server_enabled(); + bool rtc_tcp = _srs_config->get_rtc_server_tcp_enabled(); + string rtc_listen = srs_int2str(_srs_config->get_rtc_server_tcp_listen()); // If enabled and listen is the same value, resue port for WebRTC over TCP. - if (_srs_config->get_http_stream_enabled() && _srs_config->get_rtc_server_enabled() && _srs_config->get_rtc_server_tcp_enabled() - && _srs_config->get_http_stream_listen() == srs_int2str(_srs_config->get_rtc_server_tcp_listen()) - ) { - srs_trace("WebRTC reuse http=%s server", _srs_config->get_http_stream_listen().c_str()); + if (stream && rtc && rtc_tcp && http_listen == rtc_listen) { + srs_trace("WebRTC tcp=%s reuses http=%s server", rtc_listen.c_str(), http_listen.c_str()); + reuse_rtc_over_server_ = true; + } + if (stream && rtc && rtc_tcp && https_listen == rtc_listen) { + srs_trace("WebRTC tcp=%s reuses https=%s server", rtc_listen.c_str(), https_listen.c_str()); reuse_rtc_over_server_ = true; } #endif // If enabled and the listen is the same value, reuse port. - if (_srs_config->get_http_stream_enabled() && _srs_config->get_http_api_enabled() - && _srs_config->get_http_api_listen() == _srs_config->get_http_stream_listen() - && _srs_config->get_https_api_listen() == _srs_config->get_https_stream_listen() - ) { - srs_trace("API reuse http=%s and https=%s server", _srs_config->get_http_stream_listen().c_str(), _srs_config->get_https_stream_listen().c_str()); + bool api = _srs_config->get_http_api_enabled(); + string api_listen = _srs_config->get_http_api_listen(); + string apis_listen = _srs_config->get_https_api_listen(); + if (stream && api && api_listen == http_listen && apis_listen == https_listen) { + srs_trace("API reuses http=%s and https=%s server", http_listen.c_str(), https_listen.c_str()); reuse_api_over_server_ = true; } @@ -1498,17 +1507,25 @@ srs_error_t SrsServer::fd_to_resource(SrsListenerType type, srs_netfd_t& stfd, I SrsTcpConnection* skt = new SrsTcpConnection(fd2); SrsBufferedReader* io = new SrsBufferedReader(skt); - char buf[3]; int nn = sizeof(buf); - if ((err = io->peek(buf, &nn)) != srs_success) { + uint8_t b[10]; int nn = sizeof(b); + if ((err = io->peek((char*)b, &nn)) != srs_success) { srs_freep(io); srs_freep(skt); return srs_error_wrap(err, "peek"); } - // If first peeking bytes is text, serve as HTTP client; otherwise, WebRTC client over TCP. - if (nn == 3 && (buf[0] >= 'A' && buf[0] <= 'Z') && (buf[1] >= 'A' && buf[1] <= 'Z') && (buf[2] >= 'A' && buf[2] <= 'Z')) { - *pr = new SrsHttpxConn(type == SrsListenerHttpsStream, this, io, http_server, ip, port); - } else { + // If first message is BindingRequest(00 01), prefixed with length(2B), it's WebRTC client. Generally, the frame + // length minus message length should be 20, that is the header size of STUN is 20 bytes. For example: + // 00 6c # Frame length: 0x006c = 108 + // 00 01 # Message Type: Binding Request(0x0001) + // 00 58 # Message Length: 0x005 = 88 + // 21 12 a4 42 # Message Cookie: 0x2112a442 + // 48 32 6c 61 6b 42 35 71 42 35 4a 71 # Message Transaction ID: 12 bytes + if (nn == 10 && b[0] == 0 && b[2] == 0 && b[3] == 1 && b[1] - b[5] == 20 + && b[6] == 0x21 && b[7] == 0x12 && b[8] == 0xa4 && b[9] == 0x42 + ) { *pr = new SrsRtcTcpConn(io, ip, port, this); + } else { + *pr = new SrsHttpxConn(type == SrsListenerHttpsStream, this, io, http_server, ip, port); } return err; } diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp index 6960338f36c..2dfa82d4fdd 100644 --- a/trunk/src/core/srs_core_version5.hpp +++ b/trunk/src/core/srs_core_version5.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 5 #define VERSION_MINOR 0 -#define VERSION_REVISION 59 +#define VERSION_REVISION 60 #endif