API for periodically regathering ICE candidates
Adds to the RTCConfiguration `ice_regather_interval_range` which, when set, specifies the randomized delay between automatic runs of ICE regathering. The regathering will occur on all networks and re-use the existing ICE ufrag/password. New connections are established once the candidates come back and WebRTC will automatically switch to the new connection that corresponds to the currently selected connection. Bug: webrtc:7969 Change-Id: I6bbf5439a48e285f704aed9f408631cba038c82b Reviewed-on: https://chromium-review.googlesource.com/562505 Reviewed-by: Peter Thatcher <pthatcher@webrtc.org> Cr-Commit-Position: refs/heads/master@{#18978}
This commit is contained in:
parent
f1f9889c44
commit
aa41f0cfa6
@ -453,6 +453,13 @@ class PeerConnectionInterface : public rtc::RefCountInterface {
|
||||
// (STUN pings), in milliseconds.
|
||||
rtc::Optional<int> ice_check_min_interval;
|
||||
|
||||
|
||||
// ICE Periodic Regathering
|
||||
// If set, WebRTC will periodically create and propose candidates without
|
||||
// starting a new ICE generation. The regathering happens continuously with
|
||||
// interval specified in milliseconds by the uniform distribution [a, b].
|
||||
rtc::Optional<rtc::IntervalRange> ice_regather_interval_range;
|
||||
|
||||
//
|
||||
// Don't forget to update operator== if adding something.
|
||||
//
|
||||
|
||||
@ -184,6 +184,10 @@ struct IceConfig {
|
||||
// active network having no connection on it.
|
||||
rtc::Optional<int> regather_on_failed_networks_interval;
|
||||
|
||||
// Interval to perform ICE regathering on all networks
|
||||
// The delay in milliseconds is sampled from the uniform distribution [a, b]
|
||||
rtc::Optional<rtc::IntervalRange> regather_all_networks_interval_range;
|
||||
|
||||
// The time period in which we will not switch the selected connection
|
||||
// when a new connection becomes receiving but the selected connection is not
|
||||
// in case that the selected connection may become receiving soon.
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <random>
|
||||
#include <set>
|
||||
|
||||
#include "webrtc/api/umametrics.h"
|
||||
@ -32,7 +33,8 @@ namespace {
|
||||
enum {
|
||||
MSG_SORT_AND_UPDATE_STATE = 1,
|
||||
MSG_CHECK_AND_PING,
|
||||
MSG_REGATHER_ON_FAILED_NETWORKS
|
||||
MSG_REGATHER_ON_FAILED_NETWORKS,
|
||||
MSG_REGATHER_ON_ALL_NETWORKS
|
||||
};
|
||||
|
||||
// The minimum improvement in RTT that justifies a switch.
|
||||
@ -111,6 +113,7 @@ P2PTransportChannel::P2PTransportChannel(const std::string& transport_name,
|
||||
ice_role_(ICEROLE_UNKNOWN),
|
||||
tiebreaker_(0),
|
||||
gathering_state_(kIceGatheringNew),
|
||||
rand_(std::random_device()()),
|
||||
check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5),
|
||||
config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */,
|
||||
DEFAULT_BACKUP_CONNECTION_PING_INTERVAL,
|
||||
@ -428,6 +431,14 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
|
||||
LOG(LS_INFO) << "Set regather_on_failed_networks_interval to "
|
||||
<< *config_.regather_on_failed_networks_interval;
|
||||
}
|
||||
|
||||
if (config.regather_all_networks_interval_range) {
|
||||
config_.regather_all_networks_interval_range =
|
||||
config.regather_all_networks_interval_range;
|
||||
LOG(LS_INFO) << "Set regather_all_networks_interval_range to "
|
||||
<< config.regather_all_networks_interval_range->ToString();
|
||||
}
|
||||
|
||||
if (config.receiving_switching_delay) {
|
||||
config_.receiving_switching_delay = config.receiving_switching_delay;
|
||||
LOG(LS_INFO) << "Set receiving_switching_delay to"
|
||||
@ -1077,6 +1088,11 @@ void P2PTransportChannel::MaybeStartPinging() {
|
||||
thread()->PostDelayed(RTC_FROM_HERE,
|
||||
*config_.regather_on_failed_networks_interval, this,
|
||||
MSG_REGATHER_ON_FAILED_NETWORKS);
|
||||
if (config_.regather_all_networks_interval_range) {
|
||||
thread()->PostDelayed(RTC_FROM_HERE,
|
||||
SampleRegatherAllNetworksInterval(), this,
|
||||
MSG_REGATHER_ON_ALL_NETWORKS);
|
||||
}
|
||||
started_pinging_ = true;
|
||||
}
|
||||
}
|
||||
@ -1182,8 +1198,39 @@ int P2PTransportChannel::CompareConnectionCandidates(
|
||||
|
||||
// If we're still tied at this point, prefer a younger generation.
|
||||
// (Younger generation means a larger generation number).
|
||||
return (a->remote_candidate().generation() + a->port()->generation()) -
|
||||
(b->remote_candidate().generation() + b->port()->generation());
|
||||
int cmp = (a->remote_candidate().generation() + a->port()->generation()) -
|
||||
(b->remote_candidate().generation() + b->port()->generation());
|
||||
if (cmp != 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
// A periodic regather (triggered by the regather_all_networks_interval_range)
|
||||
// will produce candidates that appear the same but would use a new port. We
|
||||
// want to use the new candidates and purge the old candidates as they come
|
||||
// in, so use the fact that the old ports get pruned immediately to rank the
|
||||
// candidates with an active port/remote candidate higher.
|
||||
bool a_pruned = IsPortPruned(a->port()) ||
|
||||
IsRemoteCandidatePruned(a->remote_candidate());
|
||||
bool b_pruned = IsPortPruned(b->port()) ||
|
||||
IsRemoteCandidatePruned(b->remote_candidate());
|
||||
if (!a_pruned && b_pruned) {
|
||||
return a_is_better;
|
||||
}
|
||||
if (a_pruned && !b_pruned) {
|
||||
return b_is_better;
|
||||
}
|
||||
|
||||
// Otherwise, must be equal
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool P2PTransportChannel::IsPortPruned(const Port* port) const {
|
||||
return std::find(ports_.begin(), ports_.end(), port) == ports_.end();
|
||||
}
|
||||
|
||||
bool P2PTransportChannel::IsRemoteCandidatePruned(const Candidate& cand) const {
|
||||
return std::find(remote_candidates_.begin(), remote_candidates_.end(), cand)
|
||||
== remote_candidates_.end();
|
||||
}
|
||||
|
||||
int P2PTransportChannel::CompareConnections(
|
||||
@ -1528,6 +1575,9 @@ void P2PTransportChannel::OnMessage(rtc::Message *pmsg) {
|
||||
case MSG_REGATHER_ON_FAILED_NETWORKS:
|
||||
OnRegatherOnFailedNetworks();
|
||||
break;
|
||||
case MSG_REGATHER_ON_ALL_NETWORKS:
|
||||
OnRegatherOnAllNetworks();
|
||||
break;
|
||||
default:
|
||||
RTC_NOTREACHED();
|
||||
break;
|
||||
@ -1913,6 +1963,16 @@ void P2PTransportChannel::OnRegatherOnFailedNetworks() {
|
||||
MSG_REGATHER_ON_FAILED_NETWORKS);
|
||||
}
|
||||
|
||||
void P2PTransportChannel::OnRegatherOnAllNetworks() {
|
||||
if (!allocator_sessions_.empty() && allocator_session()->IsCleared()) {
|
||||
allocator_session()->RegatherOnAllNetworks();
|
||||
}
|
||||
|
||||
thread()->PostDelayed(RTC_FROM_HERE,
|
||||
SampleRegatherAllNetworksInterval(), this,
|
||||
MSG_REGATHER_ON_ALL_NETWORKS);
|
||||
}
|
||||
|
||||
void P2PTransportChannel::PruneAllPorts() {
|
||||
pruned_ports_.insert(pruned_ports_.end(), ports_.begin(), ports_.end());
|
||||
ports_.clear();
|
||||
@ -2066,4 +2126,10 @@ void P2PTransportChannel::set_receiving(bool receiving) {
|
||||
SignalReceivingState(this);
|
||||
}
|
||||
|
||||
int P2PTransportChannel::SampleRegatherAllNetworksInterval() {
|
||||
auto interval = config_.regather_all_networks_interval_range;
|
||||
RTC_DCHECK(interval);
|
||||
return rand_.Rand(interval->min(), interval->max());
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include "webrtc/p2p/base/portinterface.h"
|
||||
#include "webrtc/rtc_base/asyncpacketsocket.h"
|
||||
#include "webrtc/rtc_base/constructormagic.h"
|
||||
#include "webrtc/rtc_base/random.h"
|
||||
#include "webrtc/rtc_base/sigslot.h"
|
||||
|
||||
namespace cricket {
|
||||
@ -280,6 +281,7 @@ class P2PTransportChannel : public IceTransportInternal,
|
||||
void OnMessage(rtc::Message* pmsg) override;
|
||||
void OnCheckAndPing();
|
||||
void OnRegatherOnFailedNetworks();
|
||||
void OnRegatherOnAllNetworks();
|
||||
|
||||
uint32_t GetNominationAttr(Connection* conn) const;
|
||||
bool GetUseCandidateAttr(Connection* conn, NominationMode mode) const;
|
||||
@ -328,6 +330,16 @@ class P2PTransportChannel : public IceTransportInternal,
|
||||
: static_cast<uint32_t>(remote_ice_parameters_.size() - 1);
|
||||
}
|
||||
|
||||
// Samples a delay from the uniform distribution defined by the
|
||||
// regather_on_all_networks_interval ICE configuration pair.
|
||||
int SampleRegatherAllNetworksInterval();
|
||||
|
||||
// Indicates if the given local port has been pruned.
|
||||
bool IsPortPruned(const Port* port) const;
|
||||
|
||||
// Indicates if the given remote candidate has been pruned.
|
||||
bool IsRemoteCandidatePruned(const Candidate& cand) const;
|
||||
|
||||
// Sets the writable state, signaling if necessary.
|
||||
void set_writable(bool writable);
|
||||
// Sets the receiving state, signaling if necessary.
|
||||
@ -372,6 +384,9 @@ class P2PTransportChannel : public IceTransportInternal,
|
||||
uint64_t tiebreaker_;
|
||||
IceGatheringState gathering_state_;
|
||||
|
||||
// Used to generate random intervals for regather_all_networks_interval_range.
|
||||
webrtc::Random rand_;
|
||||
|
||||
int check_receiving_interval_;
|
||||
int64_t last_ping_sent_ms_ = 0;
|
||||
int weak_ping_interval_ = WEAK_PING_INTERVAL;
|
||||
|
||||
@ -1362,6 +1362,106 @@ TEST_F(P2PTransportChannelTest,
|
||||
DestroyChannels();
|
||||
}
|
||||
|
||||
// Tests that ICE regathering occurs regularly when
|
||||
// regather_all_networks_interval_range configuration value is set.
|
||||
TEST_F(P2PTransportChannelTest, TestIceRegatherOnAllNetworksContinual) {
|
||||
rtc::ScopedFakeClock clock;
|
||||
ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
|
||||
|
||||
// ep1 gathers continually but ep2 does not.
|
||||
const int kRegatherInterval = 2000;
|
||||
IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
|
||||
config1.regather_all_networks_interval_range.emplace(
|
||||
kRegatherInterval, kRegatherInterval);
|
||||
IceConfig config2;
|
||||
config2.regather_all_networks_interval_range.emplace(
|
||||
kRegatherInterval, kRegatherInterval);
|
||||
CreateChannels(config1, config2);
|
||||
|
||||
EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
|
||||
ep2_ch1()->receiving() &&
|
||||
ep2_ch1()->writable(),
|
||||
kDefaultTimeout, clock);
|
||||
|
||||
fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
|
||||
// Timeout value such that all connections are deleted.
|
||||
const int kNetworkGatherDuration = 11000;
|
||||
SIMULATED_WAIT(false, kNetworkGatherDuration, clock);
|
||||
// Expect regathering to happen 5 times in 11s with 2s interval.
|
||||
EXPECT_LE(5, GetMetricsObserver(0)->GetEnumCounter(
|
||||
webrtc::kEnumCounterIceRegathering,
|
||||
static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
|
||||
// Expect no regathering if continual gathering not configured.
|
||||
EXPECT_EQ(0, GetMetricsObserver(1)->GetEnumCounter(
|
||||
webrtc::kEnumCounterIceRegathering,
|
||||
static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
|
||||
|
||||
DestroyChannels();
|
||||
}
|
||||
|
||||
// Test that ICE periodic regathering can change the selected connection on the
|
||||
// specified interval and that the peers can communicate over the new
|
||||
// connection. The test is parameterized to test that it works when regathering
|
||||
// is done by the ICE controlling peer and when done by the controlled peer.
|
||||
class P2PTransportRegatherAllNetworksTest : public P2PTransportChannelTest {
|
||||
protected:
|
||||
void TestWithRoles(IceRole p1_role, IceRole p2_role) {
|
||||
rtc::ScopedFakeClock clock;
|
||||
ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
|
||||
kDefaultPortAllocatorFlags);
|
||||
set_force_relay(true);
|
||||
|
||||
const int kRegatherInterval = 2000;
|
||||
const int kNumRegathers = 2;
|
||||
|
||||
// Set up peer 1 to auto regather every 2s.
|
||||
IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
|
||||
config1.regather_all_networks_interval_range.emplace(
|
||||
kRegatherInterval, kRegatherInterval);
|
||||
IceConfig config2 = CreateIceConfig(1000, GATHER_CONTINUALLY);
|
||||
|
||||
// Set peer roles.
|
||||
SetIceRole(0, p1_role);
|
||||
SetIceRole(1, p2_role);
|
||||
|
||||
CreateChannels(config1, config2);
|
||||
|
||||
// Wait for initial connection to be made.
|
||||
EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() &&
|
||||
ep1_ch1()->writable() &&
|
||||
ep2_ch1()->receiving() &&
|
||||
ep2_ch1()->writable(),
|
||||
kMediumTimeout, clock);
|
||||
|
||||
const Connection* initial_selected = ep1_ch1()->selected_connection();
|
||||
|
||||
// Wait long enough for 2 regathering cycles to happen plus some extra so
|
||||
// the new connection has time to settle.
|
||||
const int kWaitRegather =
|
||||
kRegatherInterval * kNumRegathers + kRegatherInterval / 2;
|
||||
SIMULATED_WAIT(false, kWaitRegather, clock);
|
||||
EXPECT_EQ(kNumRegathers, GetMetricsObserver(0)->GetEnumCounter(
|
||||
webrtc::kEnumCounterIceRegathering,
|
||||
static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
|
||||
|
||||
const Connection* new_selected = ep1_ch1()->selected_connection();
|
||||
|
||||
// Want the new selected connection to be different.
|
||||
ASSERT_NE(initial_selected, new_selected);
|
||||
|
||||
// Make sure we can communicate over the new connection too.
|
||||
TestSendRecv(clock);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(P2PTransportRegatherAllNetworksTest, TestControlling) {
|
||||
TestWithRoles(ICEROLE_CONTROLLING, ICEROLE_CONTROLLED);
|
||||
}
|
||||
|
||||
TEST_F(P2PTransportRegatherAllNetworksTest, TestControlled) {
|
||||
TestWithRoles(ICEROLE_CONTROLLED, ICEROLE_CONTROLLING);
|
||||
}
|
||||
|
||||
// Test that we properly create a connection on a STUN ping from unknown address
|
||||
// when the signaling is slow.
|
||||
TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) {
|
||||
|
||||
@ -89,7 +89,12 @@ enum {
|
||||
};
|
||||
|
||||
// Defines various reasons that have caused ICE regathering.
|
||||
enum class IceRegatheringReason { NETWORK_CHANGE, NETWORK_FAILURE, MAX_VALUE };
|
||||
enum class IceRegatheringReason {
|
||||
NETWORK_CHANGE, // Network interfaces on the device changed
|
||||
NETWORK_FAILURE, // Regather only on networks that have failed
|
||||
OCCASIONAL_REFRESH, // Periodic regather on all networks
|
||||
MAX_VALUE
|
||||
};
|
||||
|
||||
const uint32_t kDefaultPortAllocatorFlags = 0;
|
||||
|
||||
@ -238,7 +243,6 @@ class PortAllocatorSession : public sigslot::has_slots<> {
|
||||
// implementation should start re-gathering on all networks of that interface.
|
||||
virtual void RegatherOnFailedNetworks() {}
|
||||
// Re-gathers candidates on all networks.
|
||||
// TODO(honghaiz): Implement this in BasicPortAllocator.
|
||||
virtual void RegatherOnAllNetworks() {}
|
||||
|
||||
// Another way of getting the information provided by the signals below.
|
||||
|
||||
@ -339,19 +339,43 @@ void BasicPortAllocatorSession::RegatherOnFailedNetworks() {
|
||||
sequence->set_network_failed();
|
||||
}
|
||||
}
|
||||
|
||||
bool disable_equivalent_phases = true;
|
||||
Regather(failed_networks, disable_equivalent_phases,
|
||||
IceRegatheringReason::NETWORK_FAILURE);
|
||||
}
|
||||
|
||||
void BasicPortAllocatorSession::RegatherOnAllNetworks() {
|
||||
std::vector<rtc::Network*> networks = GetNetworks();
|
||||
if (networks.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(LS_INFO) << "Regather candidates on all networks";
|
||||
|
||||
// We expect to generate candidates that are equivalent to what we have now.
|
||||
// Force DoAllocate to generate them instead of skipping.
|
||||
bool disable_equivalent_phases = false;
|
||||
Regather(networks, disable_equivalent_phases,
|
||||
IceRegatheringReason::OCCASIONAL_REFRESH);
|
||||
}
|
||||
|
||||
void BasicPortAllocatorSession::Regather(
|
||||
const std::vector<rtc::Network*>& networks,
|
||||
bool disable_equivalent_phases,
|
||||
IceRegatheringReason reason) {
|
||||
// Remove ports from being used locally and send signaling to remove
|
||||
// the candidates on the remote side.
|
||||
std::vector<PortData*> ports_to_prune = GetUnprunedPorts(failed_networks);
|
||||
std::vector<PortData*> ports_to_prune = GetUnprunedPorts(networks);
|
||||
if (!ports_to_prune.empty()) {
|
||||
LOG(LS_INFO) << "Prune " << ports_to_prune.size()
|
||||
<< " ports because their networks failed";
|
||||
LOG(LS_INFO) << "Prune " << ports_to_prune.size() << " ports";
|
||||
PrunePortsAndRemoveCandidates(ports_to_prune);
|
||||
}
|
||||
|
||||
if (allocation_started_ && network_manager_started_ && !IsStopped()) {
|
||||
SignalIceRegathering(this, IceRegatheringReason::NETWORK_FAILURE);
|
||||
SignalIceRegathering(this, reason);
|
||||
|
||||
DoAllocate();
|
||||
DoAllocate(disable_equivalent_phases);
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,8 +554,10 @@ void BasicPortAllocatorSession::AllocatePorts() {
|
||||
}
|
||||
|
||||
void BasicPortAllocatorSession::OnAllocate() {
|
||||
if (network_manager_started_ && !IsStopped())
|
||||
DoAllocate();
|
||||
if (network_manager_started_ && !IsStopped()) {
|
||||
bool disable_equivalent_phases = true;
|
||||
DoAllocate(disable_equivalent_phases);
|
||||
}
|
||||
|
||||
allocation_started_ = true;
|
||||
}
|
||||
@ -586,7 +612,7 @@ std::vector<rtc::Network*> BasicPortAllocatorSession::GetNetworks() {
|
||||
|
||||
// For each network, see if we have a sequence that covers it already. If not,
|
||||
// create a new sequence to create the appropriate ports.
|
||||
void BasicPortAllocatorSession::DoAllocate() {
|
||||
void BasicPortAllocatorSession::DoAllocate(bool disable_equivalent) {
|
||||
bool done_signal_needed = false;
|
||||
std::vector<rtc::Network*> networks = GetNetworks();
|
||||
if (networks.empty()) {
|
||||
@ -622,13 +648,15 @@ void BasicPortAllocatorSession::DoAllocate() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Disable phases that would only create ports equivalent to
|
||||
// ones that we have already made.
|
||||
DisableEquivalentPhases(networks[i], config, &sequence_flags);
|
||||
if (disable_equivalent) {
|
||||
// Disable phases that would only create ports equivalent to
|
||||
// ones that we have already made.
|
||||
DisableEquivalentPhases(networks[i], config, &sequence_flags);
|
||||
|
||||
if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) {
|
||||
// New AllocationSequence would have nothing to do, so don't make it.
|
||||
continue;
|
||||
if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) {
|
||||
// New AllocationSequence would have nothing to do, so don't make it.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
AllocationSequence* sequence =
|
||||
@ -671,7 +699,8 @@ void BasicPortAllocatorSession::OnNetworksChanged() {
|
||||
// If the network manager has started, it must be regathering.
|
||||
SignalIceRegathering(this, IceRegatheringReason::NETWORK_CHANGE);
|
||||
}
|
||||
DoAllocate();
|
||||
bool disable_equivalent_phases = true;
|
||||
DoAllocate(disable_equivalent_phases);
|
||||
}
|
||||
|
||||
if (!network_manager_started_) {
|
||||
|
||||
@ -112,6 +112,7 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
|
||||
std::vector<Candidate> ReadyCandidates() const override;
|
||||
bool CandidatesAllocationDone() const override;
|
||||
void RegatherOnFailedNetworks() override;
|
||||
void RegatherOnAllNetworks() override;
|
||||
void PruneAllPorts() override;
|
||||
|
||||
protected:
|
||||
@ -185,7 +186,7 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
|
||||
void OnConfigStop();
|
||||
void AllocatePorts();
|
||||
void OnAllocate();
|
||||
void DoAllocate();
|
||||
void DoAllocate(bool disable_equivalent_phases);
|
||||
void OnNetworksChanged();
|
||||
void OnAllocationSequenceObjectsCreated();
|
||||
void DisableEquivalentPhases(rtc::Network* network,
|
||||
@ -203,6 +204,9 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
|
||||
PortData* FindPort(Port* port);
|
||||
std::vector<rtc::Network*> GetNetworks();
|
||||
std::vector<rtc::Network*> GetFailedNetworks();
|
||||
void Regather(const std::vector<rtc::Network*>& networks,
|
||||
bool disable_equivalent_phases,
|
||||
IceRegatheringReason reason);
|
||||
|
||||
bool CheckCandidateFilter(const Candidate& c) const;
|
||||
bool CandidatePairable(const Candidate& c, const Port* port) const;
|
||||
|
||||
@ -223,11 +223,20 @@ namespace webrtc {
|
||||
bool PeerConnectionInterface::RTCConfiguration::operator==(
|
||||
const PeerConnectionInterface::RTCConfiguration& o) const {
|
||||
// This static_assert prevents us from accidentally breaking operator==.
|
||||
// Note: Order matters! Fields must be ordered the same as RTCConfiguration.
|
||||
struct stuff_being_tested_for_equality {
|
||||
IceTransportsType type;
|
||||
IceServers servers;
|
||||
IceTransportsType type;
|
||||
BundlePolicy bundle_policy;
|
||||
RtcpMuxPolicy rtcp_mux_policy;
|
||||
std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
|
||||
int ice_candidate_pool_size;
|
||||
bool disable_ipv6;
|
||||
bool disable_ipv6_on_wifi;
|
||||
bool enable_rtp_data_channel;
|
||||
rtc::Optional<int> screencast_min_bitrate;
|
||||
rtc::Optional<bool> combined_audio_video_bwe;
|
||||
rtc::Optional<bool> enable_dtls_srtp;
|
||||
TcpCandidatePolicy tcp_candidate_policy;
|
||||
CandidateNetworkPolicy candidate_network_policy;
|
||||
int audio_jitter_buffer_max_packets;
|
||||
@ -235,22 +244,15 @@ bool PeerConnectionInterface::RTCConfiguration::operator==(
|
||||
int ice_connection_receiving_timeout;
|
||||
int ice_backup_candidate_pair_ping_interval;
|
||||
ContinualGatheringPolicy continual_gathering_policy;
|
||||
std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
|
||||
bool prioritize_most_likely_ice_candidate_pairs;
|
||||
struct cricket::MediaConfig media_config;
|
||||
bool disable_ipv6;
|
||||
bool disable_ipv6_on_wifi;
|
||||
bool enable_rtp_data_channel;
|
||||
bool enable_quic;
|
||||
rtc::Optional<int> screencast_min_bitrate;
|
||||
rtc::Optional<bool> combined_audio_video_bwe;
|
||||
rtc::Optional<bool> enable_dtls_srtp;
|
||||
int ice_candidate_pool_size;
|
||||
bool prune_turn_ports;
|
||||
bool presume_writable_when_fully_relayed;
|
||||
bool enable_ice_renomination;
|
||||
bool redetermine_role_on_ice_restart;
|
||||
rtc::Optional<int> ice_check_min_interval;
|
||||
rtc::Optional<rtc::IntervalRange> ice_regather_interval_range;
|
||||
};
|
||||
static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
|
||||
"Did you add something to RTCConfiguration and forget to "
|
||||
@ -284,7 +286,8 @@ bool PeerConnectionInterface::RTCConfiguration::operator==(
|
||||
o.presume_writable_when_fully_relayed &&
|
||||
enable_ice_renomination == o.enable_ice_renomination &&
|
||||
redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart &&
|
||||
ice_check_min_interval == o.ice_check_min_interval;
|
||||
ice_check_min_interval == o.ice_check_min_interval &&
|
||||
ice_regather_interval_range == o.ice_regather_interval_range;
|
||||
}
|
||||
|
||||
bool PeerConnectionInterface::RTCConfiguration::operator!=(
|
||||
|
||||
@ -1222,6 +1222,8 @@ cricket::IceConfig WebRtcSession::ParseIceConfig(
|
||||
ice_config.presume_writable_when_fully_relayed =
|
||||
config.presume_writable_when_fully_relayed;
|
||||
ice_config.ice_check_min_interval = config.ice_check_min_interval;
|
||||
ice_config.regather_all_networks_interval_range =
|
||||
config.ice_regather_interval_range;
|
||||
return ice_config;
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,9 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/rtc_base/checks.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
@ -124,6 +127,32 @@ int64_t TmToSeconds(const std::tm& tm);
|
||||
// measuring time intervals and timeouts.
|
||||
int64_t TimeUTCMicros();
|
||||
|
||||
// Interval of time from the range [min, max] inclusive.
|
||||
class IntervalRange {
|
||||
public:
|
||||
IntervalRange() : min_(0), max_(0) {}
|
||||
IntervalRange(int min, int max) : min_(min), max_(max) {
|
||||
RTC_DCHECK_LE(min, max);
|
||||
}
|
||||
|
||||
int min() const { return min_; }
|
||||
int max() const { return max_; }
|
||||
|
||||
std::string ToString() const {
|
||||
std::stringstream ss;
|
||||
ss << "[" << min_ << "," << max_ << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool operator==(const IntervalRange& o) const {
|
||||
return min_ == o.min_ && max_ == o.max_;
|
||||
}
|
||||
|
||||
private:
|
||||
int min_;
|
||||
int max_;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_RTC_BASE_TIMEUTILS_H_
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user