mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	For #307: WebRTC: Support use domain name as CANDIDATE. v4.0.259
This commit is contained in:
		
							parent
							
								
									88ba3d25f8
								
							
						
					
					
						commit
						4a225c5640
					
				
					 6 changed files with 116 additions and 44 deletions
				
			
		| 
						 | 
				
			
			@ -394,16 +394,9 @@ rtc_server {
 | 
			
		|||
    listen 8000;
 | 
			
		||||
    # The exposed candidate IPs, response in SDP candidate line. It can be:
 | 
			
		||||
    #       *           Retrieve server IP automatically, from all network interfaces.
 | 
			
		||||
    #       eth0        Retrieve server IP by specified network interface name. # TODO: Implements it.
 | 
			
		||||
    #       $CANDIDATE  Read the IP from ENV variable, use * if not set.
 | 
			
		||||
    #       x.x.x.x     A specified IP address or DNS name, which can be access by client such as Chrome.
 | 
			
		||||
    # You can specific more than one interface name:
 | 
			
		||||
    #       eth0 eth1   Use network interface eth0 and eth1. # TODO: Implements it.
 | 
			
		||||
    # Also by IP or DNS names:
 | 
			
		||||
    #       192.168.1.3 10.1.2.3 rtc.me # TODO: Implements it.
 | 
			
		||||
    # And by multiple ENV variables:
 | 
			
		||||
    #       $CANDIDATE $EIP # TODO: Implements it.
 | 
			
		||||
    # @remark For Firefox, the candidate MUST be IP, MUST NOT be DNS name.
 | 
			
		||||
    #       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
 | 
			
		||||
    # default: *
 | 
			
		||||
    candidate *;
 | 
			
		||||
| 
						 | 
				
			
			@ -412,6 +405,19 @@ rtc_server {
 | 
			
		|||
    # in this case, the r.ossrs.net and 39.107.238.185 will be added 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.
 | 
			
		||||
    # 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
 | 
			
		||||
    # Default: off
 | 
			
		||||
    keep_api_domain off;
 | 
			
		||||
    # Whether use network interface IP which is detected automatically, filtered by ip_family.
 | 
			
		||||
    # Note that browser might fail if no CANDIDATE specified.
 | 
			
		||||
    # Default: on
 | 
			
		||||
    use_auto_detect_network_ip on;
 | 
			
		||||
    # The IP family filter for auto discover candidate, it can be:
 | 
			
		||||
    #       ipv4        Filter IP v4 candidates.
 | 
			
		||||
    #       ipv6        Filter IP v6 candidates.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ The changelog for SRS.
 | 
			
		|||
 | 
			
		||||
## SRS 4.0 Changelog
 | 
			
		||||
 | 
			
		||||
* v4.0, 2022-09-02, For [#307](https://github.com/ossrs/srs/issues/307): WebRTC: Support use domain name as CANDIDATE. v4.0.259
 | 
			
		||||
* v4.0, 2022-08-29, Copy libxml2-dev for FFmpeg. v4.0.258
 | 
			
		||||
* v4.0, 2022-08-24, STAT: Support config server_id and generate one if empty. v4.0.257
 | 
			
		||||
* v4.0, 2022-08-24, For [#2136](https://github.com/ossrs/srs/issues/2136): API: Cleanup no active streams for statistics. v4.0.256
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2545,7 +2545,8 @@ srs_error_t SrsConfig::check_normal_config()
 | 
			
		|||
            string n = conf->at(i)->name;
 | 
			
		||||
            if (n != "enabled" && n != "listen" && n != "dir" && n != "candidate" && n != "ecdsa"
 | 
			
		||||
                && n != "encrypt" && n != "reuseport" && n != "merge_nalus" && n != "black_hole"
 | 
			
		||||
                && n != "ip_family" && n != "api_as_candidates") {
 | 
			
		||||
                && n != "ip_family" && n != "api_as_candidates" && n != "resolve_api_domain"
 | 
			
		||||
                && n != "keep_api_domain" && n != "use_auto_detect_network_ip") {
 | 
			
		||||
                return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal rtc_server.%s", n.c_str());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -3662,6 +3663,57 @@ bool SrsConfig::get_api_as_candidates()
 | 
			
		|||
    return SRS_CONF_PERFER_TRUE(conf->arg0());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SrsConfig::get_resolve_api_domain()
 | 
			
		||||
{
 | 
			
		||||
    static bool DEFAULT = true;
 | 
			
		||||
 | 
			
		||||
    SrsConfDirective* conf = root->get("rtc_server");
 | 
			
		||||
    if (!conf) {
 | 
			
		||||
        return DEFAULT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    conf = conf->get("resolve_api_domain");
 | 
			
		||||
    if (!conf || conf->arg0().empty()) {
 | 
			
		||||
        return DEFAULT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return SRS_CONF_PERFER_TRUE(conf->arg0());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SrsConfig::get_keep_api_domain()
 | 
			
		||||
{
 | 
			
		||||
    static bool DEFAULT = false;
 | 
			
		||||
 | 
			
		||||
    SrsConfDirective* conf = root->get("rtc_server");
 | 
			
		||||
    if (!conf) {
 | 
			
		||||
        return DEFAULT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    conf = conf->get("keep_api_domain");
 | 
			
		||||
    if (!conf || conf->arg0().empty()) {
 | 
			
		||||
        return DEFAULT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return SRS_CONF_PERFER_FALSE(conf->arg0());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SrsConfig::get_use_auto_detect_network_ip()
 | 
			
		||||
{
 | 
			
		||||
    static bool DEFAULT = true;
 | 
			
		||||
 | 
			
		||||
    SrsConfDirective* conf = root->get("rtc_server");
 | 
			
		||||
    if (!conf) {
 | 
			
		||||
        return DEFAULT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    conf = conf->get("use_auto_detect_network_ip");
 | 
			
		||||
    if (!conf || conf->arg0().empty()) {
 | 
			
		||||
        return DEFAULT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return SRS_CONF_PERFER_TRUE(conf->arg0());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string SrsConfig::get_rtc_server_ip_family()
 | 
			
		||||
{
 | 
			
		||||
    static string DEFAULT = "ipv4";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -473,6 +473,9 @@ public:
 | 
			
		|||
    virtual int get_rtc_server_listen();
 | 
			
		||||
    virtual std::string get_rtc_server_candidates();
 | 
			
		||||
    virtual bool get_api_as_candidates();
 | 
			
		||||
    virtual bool get_resolve_api_domain();
 | 
			
		||||
    virtual bool get_keep_api_domain();
 | 
			
		||||
    virtual bool get_use_auto_detect_network_ip();
 | 
			
		||||
    virtual std::string get_rtc_server_ip_family();
 | 
			
		||||
    virtual bool get_rtc_server_ecdsa();
 | 
			
		||||
    virtual bool get_rtc_server_encrypt();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -158,12 +158,7 @@ srs_error_t api_server_as_candidates(string api, set<string>& candidate_ips)
 | 
			
		|||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SrsHttpUri uri;
 | 
			
		||||
    if ((err = uri.initialize(api)) != srs_success) {
 | 
			
		||||
        return srs_error_wrap(err, "parse %s", api.c_str());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    string hostname = uri.get_host();
 | 
			
		||||
    string hostname = api;
 | 
			
		||||
    if (hostname.empty() || hostname == SRS_CONSTS_LOCALHOST_NAME) {
 | 
			
		||||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -171,15 +166,27 @@ srs_error_t api_server_as_candidates(string api, set<string>& candidate_ips)
 | 
			
		|||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Try to parse the domain name if not IP.
 | 
			
		||||
    int family = 0;
 | 
			
		||||
    string ip = srs_dns_resolve(hostname, family);
 | 
			
		||||
    if (ip.empty() || ip == SRS_CONSTS_LOCALHOST || ip == SRS_CONSTS_LOOPBACK || ip == SRS_CONSTS_LOOPBACK6) {
 | 
			
		||||
        return err;
 | 
			
		||||
    // Whether add domain name.
 | 
			
		||||
    if (!srs_is_ipv4(hostname) && _srs_config->get_keep_api_domain()) {
 | 
			
		||||
        candidate_ips.insert(hostname);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Try to add the API server ip as candidates.
 | 
			
		||||
    candidate_ips.insert(ip);
 | 
			
		||||
    // Try to parse the domain name if not IP.
 | 
			
		||||
    if (!srs_is_ipv4(hostname) && _srs_config->get_resolve_api_domain()) {
 | 
			
		||||
        int family = 0;
 | 
			
		||||
        string ip = srs_dns_resolve(hostname, family);
 | 
			
		||||
        if (ip.empty() || ip == SRS_CONSTS_LOCALHOST || ip == SRS_CONSTS_LOOPBACK || ip == SRS_CONSTS_LOOPBACK6) {
 | 
			
		||||
            return err;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Try to add the API server ip as candidates.
 | 
			
		||||
        candidate_ips.insert(ip);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If hostname is IP, use it.
 | 
			
		||||
    if (srs_is_ipv4(hostname)) {
 | 
			
		||||
        candidate_ips.insert(hostname);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return err;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -195,8 +202,8 @@ static set<string> discover_candidates(SrsRtcUserConfig* ruc)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // Try to discover from api of request, if api_as_candidates enabled.
 | 
			
		||||
    if ((err = api_server_as_candidates(ruc->api_, candidate_ips)) != srs_success) {
 | 
			
		||||
        srs_warn("ignore discovering ip from api %s, err %s", ruc->api_.c_str(), srs_error_summary(err).c_str());
 | 
			
		||||
    if ((err = api_server_as_candidates(ruc->req_->host, candidate_ips)) != srs_success) {
 | 
			
		||||
        srs_warn("ignore discovering ip from api %s, err %s", ruc->req_->host.c_str(), srs_error_summary(err).c_str());
 | 
			
		||||
        srs_freep(err);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -207,29 +214,32 @@ static set<string> discover_candidates(SrsRtcUserConfig* ruc)
 | 
			
		|||
        return candidate_ips;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Discover from local network interface addresses.
 | 
			
		||||
    // All automatically detected IP list.
 | 
			
		||||
    vector<SrsIPAddress*>& ips = srs_get_local_ips();
 | 
			
		||||
    if (ips.empty()) {
 | 
			
		||||
        return candidate_ips;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We try to find the best match candidates, no loopback.
 | 
			
		||||
    string family = _srs_config->get_rtc_server_ip_family();
 | 
			
		||||
    for (int i = 0; i < (int)ips.size(); ++i) {
 | 
			
		||||
        SrsIPAddress* ip = ips[i];
 | 
			
		||||
        if (ip->is_loopback) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
    // Discover from local network interface addresses.
 | 
			
		||||
    if (_srs_config->get_use_auto_detect_network_ip()) {
 | 
			
		||||
        // We try to find the best match candidates, no loopback.
 | 
			
		||||
        string family = _srs_config->get_rtc_server_ip_family();
 | 
			
		||||
        for (int i = 0; i < (int) ips.size(); ++i) {
 | 
			
		||||
            SrsIPAddress* ip = ips[i];
 | 
			
		||||
            if (ip->is_loopback) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        if (family == "ipv4" && !ip->is_ipv4) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (family == "ipv6" && ip->is_ipv4) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
            if (family == "ipv4" && !ip->is_ipv4) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (family == "ipv6" && ip->is_ipv4) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        candidate_ips.insert(ip->ip);
 | 
			
		||||
        srs_trace("Best matched ip=%s, ifname=%s", ip->ip.c_str(), ip->ifname.c_str());
 | 
			
		||||
            candidate_ips.insert(ip->ip);
 | 
			
		||||
            srs_trace("Best matched ip=%s, ifname=%s", ip->ip.c_str(), ip->ifname.c_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!candidate_ips.empty()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -248,7 +258,7 @@ static set<string> discover_candidates(SrsRtcUserConfig* ruc)
 | 
			
		|||
        return candidate_ips;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We use the first one.
 | 
			
		||||
    // We use the first one, to make sure there will be at least one CANDIDATE.
 | 
			
		||||
    if (candidate_ips.empty()) {
 | 
			
		||||
        SrsIPAddress* ip = ips[0];
 | 
			
		||||
        candidate_ips.insert(ip->ip);
 | 
			
		||||
| 
						 | 
				
			
			@ -577,7 +587,7 @@ srs_error_t SrsRtcServer::do_create_session(SrsRtcUserConfig* ruc, SrsSdp& local
 | 
			
		|||
        set<string> candidates = discover_candidates(ruc);
 | 
			
		||||
        for (set<string>::iterator it = candidates.begin(); it != candidates.end(); ++it) {
 | 
			
		||||
            string hostname; int port = listen_port;
 | 
			
		||||
            srs_parse_hostport(*it, hostname,port);
 | 
			
		||||
            srs_parse_hostport(*it, hostname, port);
 | 
			
		||||
            local_sdp.add_candidate(hostname, port, "host");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,6 @@
 | 
			
		|||
 | 
			
		||||
#define VERSION_MAJOR       4
 | 
			
		||||
#define VERSION_MINOR       0
 | 
			
		||||
#define VERSION_REVISION    258
 | 
			
		||||
#define VERSION_REVISION    259
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue