From c31ffc40e41d163388c250f5cc57f5a6345adf92 Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 9 May 2020 10:53:52 +0800 Subject: [PATCH] Support filter RTC candidate by ip family, ipv4 by default. --- trunk/conf/full.conf | 7 ++++++ trunk/src/app/srs_app_config.cpp | 20 +++++++++++++++- trunk/src/app/srs_app_config.hpp | 1 + trunk/src/app/srs_app_rtc_conn.cpp | 38 ++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index b10ad8bf9..0b079133f 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -421,6 +421,13 @@ rtc_server { # $CANDIDATE $EIP # TODO: Implements it. # default: * candidate *; + # The IP family filter for candidate, it can be: + # ipv4 Filter IP v4 candidates. + # 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. + # default: ipv4 + ip_family ipv4; # Whether use ECDSA certificate. # If not, use RSA certificate. # default: on diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index a2bb2b55e..0603b7a4b 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3645,7 +3645,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 != "sendmmsg" && n != "encrypt" && n != "reuseport" && n != "gso" && n != "merge_nalus" - && n != "padding" && n != "perf_stat" && n != "queue_length" && n != "black_hole") { + && n != "padding" && n != "perf_stat" && n != "queue_length" && n != "black_hole" + && n != "ip_family") { return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal rtc_server.%s", n.c_str()); } } @@ -4747,6 +4748,23 @@ std::string SrsConfig::get_rtc_server_candidates() return conf->arg0(); } +std::string SrsConfig::get_rtc_server_ip_family() +{ + static string DEFAULT = "ipv4"; + + SrsConfDirective* conf = root->get("rtc_server"); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("ip_family"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + + return conf->arg0(); +} + bool SrsConfig::get_rtc_server_ecdsa() { static bool DEFAULT = true; diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 212143001..18f0be51c 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -525,6 +525,7 @@ public: virtual bool get_rtc_server_enabled(SrsConfDirective* conf); virtual int get_rtc_server_listen(); virtual std::string get_rtc_server_candidates(); + virtual std::string get_rtc_server_ip_family(); virtual bool get_rtc_server_ecdsa(); virtual int get_rtc_server_sendmmsg(); virtual bool get_rtc_server_encrypt(); diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index e26e62229..fb0ad93ec 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -118,13 +118,51 @@ static std::vector get_candidate_ips() // For * or 0.0.0.0, auto discovery expose ip addresses. std::vector& 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; } + if (family == "ipv4" && !ip->is_ipv4) { + continue; + } + if (family == "ipv6" && ip->is_ipv4) { + continue; + } + candidate_ips.push_back(ip->ip); + srs_warn("Best matched ip=%s, ifname=%s", ip->ip.c_str(), ip->ifname.c_str()); + } + + if (!candidate_ips.empty()) { + return candidate_ips; + } + + // Then, we use the ipv4 address. + for (int i = 0; i < (int)ips.size(); ++i) { + SrsIPAddress* ip = ips[i]; + if (!ip->is_ipv4) { + continue; + } + + candidate_ips.push_back(ip->ip); + srs_warn("No best matched, use first ip=%s, ifname=%s", ip->ip.c_str(), ip->ifname.c_str()); + return candidate_ips; + } + + // We use the first one. + if (candidate_ips.empty()) { + SrsIPAddress* ip = ips[0]; + candidate_ips.push_back(ip->ip); + srs_warn("No best matched, use first ip=%s, ifname=%s", ip->ip.c_str(), ip->ifname.c_str()); + return candidate_ips; } return candidate_ips;