diff --git a/p2p/base/fakeicetransport.h b/p2p/base/fakeicetransport.h index 1a569c6f62..aa6afb8e3f 100644 --- a/p2p/base/fakeicetransport.h +++ b/p2p/base/fakeicetransport.h @@ -85,7 +85,9 @@ class FakeIceTransport : public IceTransportInternal { } // Convenience functions for accessing ICE config and other things. - int receiving_timeout() const { return ice_config_.receiving_timeout; } + int receiving_timeout() const { + return ice_config_.receiving_timeout_or_default(); + } bool gather_continually() const { return ice_config_.gather_continually(); } const Candidates& remote_candidates() const { return remote_candidates_; } diff --git a/p2p/base/icetransportinternal.cc b/p2p/base/icetransportinternal.cc index 1edbf63a72..261e0f0e60 100644 --- a/p2p/base/icetransportinternal.cc +++ b/p2p/base/icetransportinternal.cc @@ -10,6 +10,8 @@ #include "p2p/base/icetransportinternal.h" +#include "p2p/base/p2pconstants.h" + namespace cricket { IceConfig::IceConfig() = default; @@ -21,8 +23,7 @@ IceConfig::IceConfig(int receiving_timeout_ms, int stable_writable_connection_ping_interval_ms, bool presume_writable_when_fully_relayed, int regather_on_failed_networks_interval_ms, - int receiving_switching_delay_ms, - rtc::Optional network_preference) + int receiving_switching_delay_ms) : receiving_timeout(receiving_timeout_ms), backup_connection_ping_interval(backup_connection_ping_interval), continual_gathering_policy(gathering_policy), @@ -33,11 +34,47 @@ IceConfig::IceConfig(int receiving_timeout_ms, presume_writable_when_fully_relayed(presume_writable_when_fully_relayed), regather_on_failed_networks_interval( regather_on_failed_networks_interval_ms), - receiving_switching_delay(receiving_switching_delay_ms), - network_preference(network_preference) {} + receiving_switching_delay(receiving_switching_delay_ms) {} IceConfig::~IceConfig() = default; +int IceConfig::receiving_timeout_or_default() const { + return receiving_timeout.value_or(RECEIVING_TIMEOUT); +} +int IceConfig::backup_connection_ping_interval_or_default() const { + return backup_connection_ping_interval.value_or( + BACKUP_CONNECTION_PING_INTERVAL); +} +int IceConfig::stable_writable_connection_ping_interval_or_default() const { + return stable_writable_connection_ping_interval.value_or( + STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL); +} +int IceConfig::regather_on_failed_networks_interval_or_default() const { + return regather_on_failed_networks_interval.value_or( + REGATHER_ON_FAILED_NETWORKS_INTERVAL); +} +int IceConfig::receiving_switching_delay_or_default() const { + return receiving_switching_delay.value_or(RECEIVING_SWITCHING_DELAY); +} +int IceConfig::ice_check_interval_strong_connectivity_or_default() const { + return ice_check_interval_strong_connectivity.value_or(STRONG_PING_INTERVAL); +} +int IceConfig::ice_check_interval_weak_connectivity_or_default() const { + return ice_check_interval_weak_connectivity.value_or(WEAK_PING_INTERVAL); +} +int IceConfig::ice_check_min_interval_or_default() const { + return ice_check_min_interval.value_or(-1); +} +int IceConfig::ice_unwritable_timeout_or_default() const { + return ice_unwritable_timeout.value_or(CONNECTION_WRITE_CONNECT_TIMEOUT); +} +int IceConfig::ice_unwritable_min_checks_or_default() const { + return ice_unwritable_min_checks.value_or(CONNECTION_WRITE_CONNECT_FAILURES); +} +int IceConfig::stun_keepalive_interval_or_default() const { + return stun_keepalive_interval.value_or(STUN_KEEPALIVE_INTERVAL); +} + IceTransportInternal::IceTransportInternal() = default; IceTransportInternal::~IceTransportInternal() = default; diff --git a/p2p/base/icetransportinternal.h b/p2p/base/icetransportinternal.h index f5cafd09c7..4b6db6149a 100644 --- a/p2p/base/icetransportinternal.h +++ b/p2p/base/icetransportinternal.h @@ -70,10 +70,10 @@ enum class NominationMode { // -1. struct IceConfig { // The ICE connection receiving timeout value in milliseconds. - int receiving_timeout = -1; + rtc::Optional receiving_timeout; // Time interval in milliseconds to ping a backup connection when the ICE // channel is strongly connected. - int backup_connection_ping_interval = -1; + rtc::Optional backup_connection_ping_interval; ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE; @@ -87,7 +87,7 @@ struct IceConfig { bool prioritize_most_likely_candidate_pairs = false; // Writable connections are pinged at a slower rate once stablized. - int stable_writable_connection_ping_interval = -1; + rtc::Optional stable_writable_connection_ping_interval; // If set to true, this means the ICE transport should presume TURN-to-TURN // candidate pairs will succeed, even before a binding response is received. @@ -153,9 +153,23 @@ struct IceConfig { int stable_writable_connection_ping_interval_ms, bool presume_writable_when_fully_relayed, int regather_on_failed_networks_interval_ms, - int receiving_switching_delay_ms, - rtc::Optional network_preference); + int receiving_switching_delay_ms); ~IceConfig(); + + // Helper getters for parameters with implementation-specific default value. + // By convention, parameters with default value are represented by + // rtc::Optional and setting a parameter to null restores its default value. + int receiving_timeout_or_default() const; + int backup_connection_ping_interval_or_default() const; + int stable_writable_connection_ping_interval_or_default() const; + int regather_on_failed_networks_interval_or_default() const; + int receiving_switching_delay_or_default() const; + int ice_check_interval_strong_connectivity_or_default() const; + int ice_check_interval_weak_connectivity_or_default() const; + int ice_check_min_interval_or_default() const; + int ice_unwritable_timeout_or_default() const; + int ice_unwritable_min_checks_or_default() const; + int stun_keepalive_interval_or_default() const; }; // TODO(zhihuang): Replace this with diff --git a/p2p/base/p2pconstants.cc b/p2p/base/p2pconstants.cc index dc6db636e5..7dad2d0348 100644 --- a/p2p/base/p2pconstants.cc +++ b/p2p/base/p2pconstants.cc @@ -43,4 +43,33 @@ const char CONNECTIONROLE_PASSIVE_STR[] = "passive"; const char CONNECTIONROLE_ACTPASS_STR[] = "actpass"; const char CONNECTIONROLE_HOLDCONN_STR[] = "holdconn"; +const int MIN_CHECK_RECEIVING_INTERVAL = 50; +const int RECEIVING_TIMEOUT = MIN_CHECK_RECEIVING_INTERVAL * 50; +const int RECEIVING_SWITCHING_DELAY = 1000; +const int BACKUP_CONNECTION_PING_INTERVAL = 25 * 1000; +const int REGATHER_ON_FAILED_NETWORKS_INTERVAL = 5 * 60 * 1000; + +// When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) +// for pinging. When the socket is writable, we will use only 1 Kbps because we +// don't want to degrade the quality on a modem. These numbers should work well +// on a 28.8K modem, which is the slowest connection on which the voice quality +// is reasonable at all. +const int STUN_PING_PACKET_SIZE = 60 * 8; +const int STRONG_PING_INTERVAL = 1000 * STUN_PING_PACKET_SIZE / 1000; // 480ms. +const int WEAK_PING_INTERVAL = 1000 * STUN_PING_PACKET_SIZE / 10000; // 48ms. +const int WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL = 900; +const int STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL = 2500; +const int CONNECTION_WRITE_CONNECT_TIMEOUT = 5 * 1000; // 5 seconds +const uint32_t CONNECTION_WRITE_CONNECT_FAILURES = 5; // 5 pings + +const int STUN_KEEPALIVE_INTERVAL = 10 * 1000; // 10 seconds + +const int MIN_CONNECTION_LIFETIME = 10 * 1000; // 10 seconds. +const int DEAD_CONNECTION_RECEIVE_TIMEOUT = 30 * 1000; // 30 seconds. +const int WEAK_CONNECTION_RECEIVE_TIMEOUT = 2500; // 2.5 seconds +const int CONNECTION_WRITE_TIMEOUT = 15 * 1000; // 15 seconds +// There is no harm to keep this value high other than a small amount +// of increased memory, but in some networks (2G), we observe up to 60s RTTs. +const int CONNECTION_RESPONSE_TIMEOUT = 60 * 1000; // 60 seconds + } // namespace cricket diff --git a/p2p/base/p2pconstants.h b/p2p/base/p2pconstants.h index 584eac2fd3..b2e92eff13 100644 --- a/p2p/base/p2pconstants.h +++ b/p2p/base/p2pconstants.h @@ -45,6 +45,64 @@ extern const char CONNECTIONROLE_PASSIVE_STR[]; extern const char CONNECTIONROLE_ACTPASS_STR[]; extern const char CONNECTIONROLE_HOLDCONN_STR[]; +// Constants for time intervals are in milliseconds unless otherwise stated. +// +// Most of the following constants are the default values of IceConfig +// paramters. See IceConfig for detailed definition. +// +// Default value of IceConfig.receiving_timeout. +extern const int RECEIVING_TIMEOUT; +// Default value IceConfig.ice_check_min_interval. +extern const int MIN_CHECK_RECEIVING_INTERVAL; +// The next two ping intervals are at the ICE transport level. +// +// STRONG_PING_INTERVAL is applied when the selected connection is both +// writable and receiving. +// +// Default value of IceConfig.ice_check_interval_strong_connectivity. +extern const int STRONG_PING_INTERVAL; +// WEAK_PING_INTERVAL is applied when the selected connection is either +// not writable or not receiving. +// +// Defaul value of IceConfig.ice_check_interval_weak_connectivity. +extern const int WEAK_PING_INTERVAL; +// The next two ping intervals are at the candidate pair level. +// +// Writable candidate pairs are pinged at a slower rate once they are stabilized +// and the channel is strongly connected. +extern const int STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL; +// Writable candidate pairs are pinged at a faster rate while the connections +// are stabilizing or the channel is weak. +extern const int WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL; +// Default value of IceConfig.backup_connection_ping_interval +extern const int BACKUP_CONNECTION_PING_INTERVAL; +// Defualt value of IceConfig.receiving_switching_delay. +extern const int RECEIVING_SWITCHING_DELAY; +// Default value of IceConfig.regather_on_failed_networks_interval. +extern const int REGATHER_ON_FAILED_NETWORKS_INTERVAL; +// Default vaule of IceConfig.ice_unwritable_timeout. +extern const int CONNECTION_WRITE_CONNECT_TIMEOUT; +// Default vaule of IceConfig.ice_unwritable_min_checks. +extern const uint32_t CONNECTION_WRITE_CONNECT_FAILURES; +// Default value of IceConfig.stun_keepalive_interval; +extern const int STUN_KEEPALIVE_INTERVAL; + +// The following constants are used at the candidate pair level to determine the +// state of a candidate pair. +// +// The timeout duration when a connection does not receive anything. +extern const int WEAK_CONNECTION_RECEIVE_TIMEOUT; +// A connection will be declared dead if it has not received anything for this +// long. +extern const int DEAD_CONNECTION_RECEIVE_TIMEOUT; +// The length of time we wait before timing out writability on a connection. +extern const int CONNECTION_WRITE_TIMEOUT; +// This is the length of time that we wait for a ping response to come back. +extern const int CONNECTION_RESPONSE_TIMEOUT; +// The minimum time we will wait before destroying a connection after creating +// it. +extern const int MIN_CONNECTION_LIFETIME; + } // namespace cricket #endif // P2P_BASE_P2PCONSTANTS_H_ diff --git a/p2p/base/p2ptransportchannel.cc b/p2p/base/p2ptransportchannel.cc index ab519f5b07..5ef81f63e0 100644 --- a/p2p/base/p2ptransportchannel.cc +++ b/p2p/base/p2ptransportchannel.cc @@ -95,45 +95,6 @@ int CompareCandidatePairsByNetworkPreference( namespace cricket { -// When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) -// for pinging. When the socket is writable, we will use only 1 Kbps because -// we don't want to degrade the quality on a modem. These numbers should work -// well on a 28.8K modem, which is the slowest connection on which the voice -// quality is reasonable at all. -static const int PING_PACKET_SIZE = 60 * 8; - -// The next two ping intervals are at the channel level. -// STRONG_PING_INTERVAL (480ms) is applied when the selected connection is both -// writable and receiving. -// -// This constant is the default value of ice_check_interval_strong_connectivity -// in IceConfig if not set. -const int STRONG_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 1000; -// WEAK_PING_INTERVAL (48ms) is applied when the selected connection is either -// not writable or not receiving. -// -// This constant is the default value of ice_check_interval_weak_connectivity in -// IceConfig if not set. -const int WEAK_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 10000; - -// The next two ping intervals are at the connection level. -// Writable connections are pinged at a faster rate while the connections are -// stabilizing or the channel is weak. -const int WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL = 900; // ms -// Writable connections are pinged at a slower rate once they are stabilized and -// the channel is strongly connected. -const int STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL = 2500; // ms - -static const int MIN_CHECK_RECEIVING_INTERVAL = 50; // ms - -static const int RECEIVING_SWITCHING_DELAY = 1000; // ms - -// We periodically check if any existing networks do not have any connection -// and regather on those networks. -static const int DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL = 5 * 60 * 1000; - -static constexpr int DEFAULT_BACKUP_CONNECTION_PING_INTERVAL = 25 * 1000; - bool IceCredentialsChanged(const std::string& old_ufrag, const std::string& old_pwd, const std::string& new_ufrag, @@ -161,16 +122,14 @@ P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, tiebreaker_(0), gathering_state_(kIceGatheringNew), rand_(rtc::SystemTimeNanos()), - check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5), - config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */, - DEFAULT_BACKUP_CONNECTION_PING_INTERVAL, + config_(RECEIVING_TIMEOUT, + BACKUP_CONNECTION_PING_INTERVAL, GATHER_ONCE /* continual_gathering_policy */, false /* prioritize_most_likely_candidate_pairs */, STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL, true /* presume_writable_when_fully_relayed */, - DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL, - RECEIVING_SWITCHING_DELAY, - rtc::nullopt) { + REGATHER_ON_FAILED_NETWORKS_INTERVAL, + RECEIVING_SWITCHING_DELAY) { uint32_t weak_ping_interval = ::strtoul( webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), nullptr, 10); @@ -270,7 +229,7 @@ bool P2PTransportChannel::ShouldSwitchSelectedConnection( } rtc::Optional receiving_unchanged_threshold( - rtc::TimeMillis() - config_.receiving_switching_delay.value_or(0)); + rtc::TimeMillis() - config_.receiving_switching_delay_or_default()); int cmp = CompareConnections(selected_connection_, new_connection, receiving_unchanged_threshold, missed_receiving_unchanged_threshold); @@ -294,13 +253,14 @@ bool P2PTransportChannel::MaybeSwitchSelectedConnection( return true; } if (missed_receiving_unchanged_threshold && - config_.receiving_switching_delay) { + config_.receiving_switching_delay_or_default()) { // If we do not switch to the connection because it missed the receiving // threshold, the new connection is in a better receiving state than the // currently selected connection. So we need to re-check whether it needs // to be switched at a later time. - thread()->PostDelayed(RTC_FROM_HERE, *config_.receiving_switching_delay, - this, MSG_SORT_AND_UPDATE_STATE); + thread()->PostDelayed(RTC_FROM_HERE, + config_.receiving_switching_delay_or_default(), this, + MSG_SORT_AND_UPDATE_STATE); } return false; } @@ -463,27 +423,22 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { } } - if (config.backup_connection_ping_interval >= 0 && - config_.backup_connection_ping_interval != - config.backup_connection_ping_interval) { + if (config_.backup_connection_ping_interval != + config.backup_connection_ping_interval) { config_.backup_connection_ping_interval = config.backup_connection_ping_interval; RTC_LOG(LS_INFO) << "Set backup connection ping interval to " - << config_.backup_connection_ping_interval + << config_.backup_connection_ping_interval_or_default() << " milliseconds."; } - - if (config.receiving_timeout >= 0 && - config_.receiving_timeout != config.receiving_timeout) { + if (config_.receiving_timeout != config.receiving_timeout) { config_.receiving_timeout = config.receiving_timeout; - check_receiving_interval_ = - std::max(MIN_CHECK_RECEIVING_INTERVAL, config_.receiving_timeout / 10); - for (Connection* connection : connections_) { connection->set_receiving_timeout(config_.receiving_timeout); } RTC_LOG(LS_INFO) << "Set ICE receiving timeout to " - << config_.receiving_timeout << " milliseconds"; + << config_.receiving_timeout_or_default() + << " milliseconds"; } config_.prioritize_most_likely_candidate_pairs = @@ -491,17 +446,17 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { RTC_LOG(LS_INFO) << "Set ping most likely connection to " << config_.prioritize_most_likely_candidate_pairs; - if (config.stable_writable_connection_ping_interval >= 0 && - config_.stable_writable_connection_ping_interval != - config.stable_writable_connection_ping_interval) { + if (config_.stable_writable_connection_ping_interval != + config.stable_writable_connection_ping_interval) { config_.stable_writable_connection_ping_interval = config.stable_writable_connection_ping_interval; - RTC_LOG(LS_INFO) << "Set stable_writable_connection_ping_interval to " - << config_.stable_writable_connection_ping_interval; + RTC_LOG(LS_INFO) + << "Set stable_writable_connection_ping_interval to " + << config_.stable_writable_connection_ping_interval_or_default(); } - if (config.presume_writable_when_fully_relayed != - config_.presume_writable_when_fully_relayed) { + if (config_.presume_writable_when_fully_relayed != + config.presume_writable_when_fully_relayed) { if (!connections_.empty()) { RTC_LOG(LS_ERROR) << "Trying to change 'presume writable' " << "while connections already exist!"; @@ -513,15 +468,17 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { } } - if (config.regather_on_failed_networks_interval) { + if (config_.regather_on_failed_networks_interval != + config.regather_on_failed_networks_interval) { config_.regather_on_failed_networks_interval = config.regather_on_failed_networks_interval; - RTC_LOG(LS_INFO) << "Set regather_on_failed_networks_interval to " - << config_.regather_on_failed_networks_interval.value_or( - -1); + RTC_LOG(LS_INFO) + << "Set regather_on_failed_networks_interval to " + << config_.regather_on_failed_networks_interval_or_default(); } - if (config.regather_all_networks_interval_range) { + if (config_.regather_all_networks_interval_range != + config.regather_all_networks_interval_range) { // Config validation is assumed to have already happened at the API layer. RTC_DCHECK(config.continual_gathering_policy != GATHER_ONCE); config_.regather_all_networks_interval_range = @@ -532,10 +489,10 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { .ToString(); } - if (config.receiving_switching_delay) { + if (config_.receiving_switching_delay != config.receiving_switching_delay) { config_.receiving_switching_delay = config.receiving_switching_delay; RTC_LOG(LS_INFO) << "Set receiving_switching_delay to" - << config_.receiving_switching_delay.value_or(-1); + << config_.receiving_switching_delay_or_default(); } if (config_.default_nomination_mode != config.default_nomination_mode) { @@ -548,24 +505,24 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { config.ice_check_interval_strong_connectivity) { config_.ice_check_interval_strong_connectivity = config.ice_check_interval_strong_connectivity; - RTC_LOG(LS_INFO) << "Set strong ping interval to " - << config_.ice_check_interval_strong_connectivity.value_or( - -1); + RTC_LOG(LS_INFO) + << "Set strong ping interval to " + << config_.ice_check_interval_strong_connectivity_or_default(); } if (config_.ice_check_interval_weak_connectivity != config.ice_check_interval_weak_connectivity) { config_.ice_check_interval_weak_connectivity = config.ice_check_interval_weak_connectivity; - RTC_LOG(LS_INFO) << "Set weak ping interval to " - << config_.ice_check_interval_weak_connectivity.value_or( - -1); + RTC_LOG(LS_INFO) + << "Set weak ping interval to " + << config_.ice_check_interval_weak_connectivity_or_default(); } if (config_.ice_check_min_interval != config.ice_check_min_interval) { config_.ice_check_min_interval = config.ice_check_min_interval; RTC_LOG(LS_INFO) << "Set min ping interval to " - << config_.ice_check_min_interval.value_or(-1); + << config_.ice_check_min_interval_or_default(); } if (config_.ice_unwritable_timeout != config.ice_unwritable_timeout) { @@ -574,7 +531,7 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { conn->set_unwritable_timeout(config_.ice_unwritable_timeout); } RTC_LOG(LS_INFO) << "Set unwritable timeout to " - << config_.ice_unwritable_timeout.value_or(-1); + << config_.ice_unwritable_timeout_or_default(); } if (config_.ice_unwritable_min_checks != config.ice_unwritable_min_checks) { @@ -583,7 +540,7 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { conn->set_unwritable_min_checks(config_.ice_unwritable_min_checks); } RTC_LOG(LS_INFO) << "Set unwritable min checks to " - << config_.ice_unwritable_min_checks.value_or(-1); + << config_.ice_unwritable_min_checks_or_default(); } if (config_.network_preference != config.network_preference) { @@ -603,7 +560,7 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { allocator_session()->SetStunKeepaliveIntervalForReadyPorts( config_.stun_keepalive_interval); RTC_LOG(LS_INFO) << "Set STUN keepalive interval to " - << config.stun_keepalive_interval.value_or(-1); + << config.stun_keepalive_interval_or_default(); } } @@ -611,6 +568,11 @@ const IceConfig& P2PTransportChannel::config() const { return config_; } +int P2PTransportChannel::check_receiving_interval() const { + return std::max(MIN_CHECK_RECEIVING_INTERVAL, + config_.receiving_timeout_or_default() / 10); +} + void P2PTransportChannel::SetMetricsObserver( webrtc::MetricsObserverInterface* observer) { metrics_observer_ = observer; @@ -1253,9 +1215,10 @@ void P2PTransportChannel::MaybeStartPinging() { LOG_J(LS_INFO, this) << "Have a pingable connection for the first time; " << "starting to ping."; thread()->Post(RTC_FROM_HERE, this, MSG_CHECK_AND_PING); - thread()->PostDelayed(RTC_FROM_HERE, - *config_.regather_on_failed_networks_interval, this, - MSG_REGATHER_ON_FAILED_NETWORKS); + thread()->PostDelayed( + RTC_FROM_HERE, + config_.regather_on_failed_networks_interval_or_default(), this, + MSG_REGATHER_ON_FAILED_NETWORKS); if (config_.regather_all_networks_interval_range) { thread()->PostDelayed(RTC_FROM_HERE, SampleRegatherAllNetworksInterval(), this, @@ -1806,7 +1769,7 @@ void P2PTransportChannel::OnCheckAndPing() { MarkConnectionPinged(conn); } } - int delay = std::min(ping_interval, check_receiving_interval_); + int delay = std::min(ping_interval, check_receiving_interval()); thread()->PostDelayed(RTC_FROM_HERE, delay, this, MSG_CHECK_AND_PING); } @@ -1852,7 +1815,7 @@ bool P2PTransportChannel::IsPingable(const Connection* conn, if (IsBackupConnection(conn)) { return conn->rtt_samples() == 0 || (now >= conn->last_ping_response_received() + - config_.backup_connection_ping_interval); + config_.backup_connection_ping_interval_or_default()); } // Don't ping inactive non-backup connections. if (!conn->active()) { @@ -1885,7 +1848,8 @@ int P2PTransportChannel::CalculateActiveWritablePingInterval( return weak_ping_interval(); } - int stable_interval = config_.stable_writable_connection_ping_interval; + int stable_interval = + config_.stable_writable_connection_ping_interval_or_default(); int weak_or_stablizing_interval = std::min( stable_interval, WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL); // If the channel is weak or the connection is not stable yet, use the @@ -2162,9 +2126,9 @@ void P2PTransportChannel::OnRegatherOnFailedNetworks() { allocator_session()->RegatherOnFailedNetworks(); } - thread()->PostDelayed(RTC_FROM_HERE, - *config_.regather_on_failed_networks_interval, this, - MSG_REGATHER_ON_FAILED_NETWORKS); + thread()->PostDelayed( + RTC_FROM_HERE, config_.regather_on_failed_networks_interval_or_default(), + this, MSG_REGATHER_ON_FAILED_NETWORKS); } void P2PTransportChannel::OnRegatherOnAllNetworks() { diff --git a/p2p/base/p2ptransportchannel.h b/p2p/base/p2ptransportchannel.h index a9825cf856..d811b631bd 100644 --- a/p2p/base/p2ptransportchannel.h +++ b/p2p/base/p2ptransportchannel.h @@ -32,6 +32,7 @@ #include "logging/rtc_event_log/icelogger.h" #include "p2p/base/candidatepairinterface.h" #include "p2p/base/icetransportinternal.h" +#include "p2p/base/p2pconstants.h" #include "p2p/base/portallocator.h" #include "p2p/base/portinterface.h" #include "rtc_base/asyncpacketsocket.h" @@ -49,10 +50,6 @@ namespace cricket { // connected/connecting/disconnected when ICE restart happens. enum class IceRestartState { CONNECTING, CONNECTED, DISCONNECTED, MAX_VALUE }; -extern const int WEAK_PING_INTERVAL; -extern const int STRONG_PING_INTERVAL; -extern const int WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL; -extern const int STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL; static const int MIN_PINGS_AT_WEAK_PING_INTERVAL = 3; bool IceCredentialsChanged(const std::string& old_ufrag, @@ -138,9 +135,7 @@ class P2PTransportChannel : public IceTransportInternal, IceMode remote_ice_mode() const { return remote_ice_mode_; } void PruneAllPorts(); - int receiving_timeout() const { return config_.receiving_timeout; } - int check_receiving_interval() const { return check_receiving_interval_; } - + int check_receiving_interval() const; rtc::Optional network_route() const override; // Helper method used only in unittest. @@ -181,15 +176,13 @@ class P2PTransportChannel : public IceTransportInternal, bool weak() const; int weak_ping_interval() const { - return std::max(config_.ice_check_interval_weak_connectivity.value_or( - weak_ping_interval_), - config_.ice_check_min_interval.value_or(-1)); + return std::max(config_.ice_check_interval_weak_connectivity_or_default(), + config_.ice_check_min_interval_or_default()); } int strong_ping_interval() const { - return std::max(config_.ice_check_interval_strong_connectivity.value_or( - STRONG_PING_INTERVAL), - config_.ice_check_min_interval.value_or(-1)); + return std::max(config_.ice_check_interval_strong_connectivity_or_default(), + config_.ice_check_min_interval_or_default()); } // Returns true if it's possible to send packets on |connection|. @@ -405,7 +398,6 @@ class P2PTransportChannel : public IceTransportInternal, // 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; IceTransportState state_ = IceTransportState::STATE_INIT; diff --git a/p2p/base/p2ptransportchannel_unittest.cc b/p2p/base/p2ptransportchannel_unittest.cc index 71c648afa9..58ee95d360 100644 --- a/p2p/base/p2ptransportchannel_unittest.cc +++ b/p2p/base/p2ptransportchannel_unittest.cc @@ -113,7 +113,7 @@ enum { MSG_ADD_CANDIDATES, MSG_REMOVE_CANDIDATES }; cricket::IceConfig CreateIceConfig( int receiving_timeout, cricket::ContinualGatheringPolicy continual_gathering_policy, - int backup_ping_interval = -1) { + rtc::Optional backup_ping_interval = rtc::nullopt) { cricket::IceConfig config; config.receiving_timeout = receiving_timeout; config.continual_gathering_policy = continual_gathering_policy; @@ -3567,10 +3567,10 @@ TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) { PrepareChannel(&ch); // Default receiving timeout and checking receiving interval should not be too // small. - EXPECT_LE(1000, ch.receiving_timeout()); + EXPECT_LE(1000, ch.config().receiving_timeout_or_default()); EXPECT_LE(200, ch.check_receiving_interval()); ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE)); - EXPECT_EQ(500, ch.receiving_timeout()); + EXPECT_EQ(500, ch.config().receiving_timeout_or_default()); EXPECT_EQ(50, ch.check_receiving_interval()); ch.MaybeStartGathering(); ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1)); diff --git a/p2p/base/port.cc b/p2p/base/port.cc index dfc3f12949..5c4d4871f1 100644 --- a/p2p/base/port.cc +++ b/p2p/base/port.cc @@ -1036,7 +1036,6 @@ Connection::Connection(Port* port, packet_loss_estimator_(kConsiderPacketLostAfter, kForgetPacketAfter), reported_(false), state_(IceCandidatePairState::WAITING), - receiving_timeout_(WEAK_CONNECTION_RECEIVE_TIMEOUT), time_created_ms_(rtc::TimeMillis()) { // All of our connections start in WAITING state. // TODO(mallinath) - Start connections from STATE_FROZEN. @@ -1095,7 +1094,7 @@ void Connection::set_write_state(WriteState value) { void Connection::UpdateReceiving(int64_t now) { bool receiving = - last_received() > 0 && now <= last_received() + receiving_timeout_; + last_received() > 0 && now <= last_received() + receiving_timeout(); if (receiving_ == receiving) { return; } @@ -1134,6 +1133,10 @@ int Connection::unwritable_min_checks() const { return unwritable_min_checks_.value_or(CONNECTION_WRITE_CONNECT_FAILURES); } +int Connection::receiving_timeout() const { + return receiving_timeout_.value_or(WEAK_CONNECTION_RECEIVE_TIMEOUT); +} + void Connection::OnSendStunPacket(const void* data, size_t size, StunRequest* req) { rtc::PacketOptions options(port_->DefaultDscpValue()); diff --git a/p2p/base/port.h b/p2p/base/port.h index d9f7bf9e8f..5655b968cc 100644 --- a/p2p/base/port.h +++ b/p2p/base/port.h @@ -23,6 +23,7 @@ #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h" #include "logging/rtc_event_log/icelogger.h" #include "p2p/base/candidatepairinterface.h" +#include "p2p/base/p2pconstants.h" #include "p2p/base/packetlossestimator.h" #include "p2p/base/packetsocketfactory.h" #include "p2p/base/portinterface.h" @@ -54,32 +55,6 @@ extern const char TCPTYPE_ACTIVE_STR[]; extern const char TCPTYPE_PASSIVE_STR[]; extern const char TCPTYPE_SIMOPEN_STR[]; -// The minimum time we will wait before destroying a connection after creating -// it. -static const int MIN_CONNECTION_LIFETIME = 10 * 1000; // 10 seconds. - -// A connection will be declared dead if it has not received anything for this -// long. -static const int DEAD_CONNECTION_RECEIVE_TIMEOUT = 30 * 1000; // 30 seconds. - -// The timeout duration when a connection does not receive anything. -static const int WEAK_CONNECTION_RECEIVE_TIMEOUT = 2500; // 2.5 seconds - -// The length of time we wait before timing out writability on a connection. -static const int CONNECTION_WRITE_TIMEOUT = 15 * 1000; // 15 seconds - -// The length of time we wait before we become unwritable. -static const int CONNECTION_WRITE_CONNECT_TIMEOUT = 5 * 1000; // 5 seconds - -// This is the length of time that we wait for a ping response to come back. -// There is no harm to keep this value high other than a small amount -// of increased memory. But in some networks (2G), -// we observe up to 60s RTTs. -static const int CONNECTION_RESPONSE_TIMEOUT = 60 * 1000; // 60 seconds - -// The number of pings that must fail to respond before we become unwritable. -static const uint32_t CONNECTION_WRITE_CONNECT_FAILURES = 5; - enum RelayType { RELAY_GTURN, // Legacy google relay service. RELAY_TURN // Standard (TURN) relay service. @@ -650,7 +625,8 @@ class Connection : public CandidatePairInterface, remote_ice_mode_ = mode; } - void set_receiving_timeout(int receiving_timeout_ms) { + int receiving_timeout() const; + void set_receiving_timeout(rtc::Optional receiving_timeout_ms) { receiving_timeout_ = receiving_timeout_ms; } @@ -835,7 +811,7 @@ class Connection : public CandidatePairInterface, bool reported_; IceCandidatePairState state_; // Time duration to switch from receiving to not receiving. - int receiving_timeout_; + rtc::Optional receiving_timeout_; int64_t time_created_ms_; int num_pings_sent_ = 0; diff --git a/p2p/base/port_unittest.cc b/p2p/base/port_unittest.cc index bbf2fef69a..7623c993ca 100644 --- a/p2p/base/port_unittest.cc +++ b/p2p/base/port_unittest.cc @@ -12,6 +12,7 @@ #include #include "p2p/base/basicpacketsocketfactory.h" +#include "p2p/base/p2pconstants.h" #include "p2p/base/relayport.h" #include "p2p/base/stunport.h" #include "p2p/base/tcpport.h" diff --git a/p2p/base/stunport.cc b/p2p/base/stunport.cc index 81702a80aa..8deea1c92d 100644 --- a/p2p/base/stunport.cc +++ b/p2p/base/stunport.cc @@ -14,6 +14,7 @@ #include #include "p2p/base/common.h" +#include "p2p/base/p2pconstants.h" #include "p2p/base/portallocator.h" #include "p2p/base/stun.h" #include "rtc_base/checks.h" @@ -25,7 +26,6 @@ namespace cricket { // TODO(?): Move these to a common place (used in relayport too) -const int KEEPALIVE_DELAY = 10 * 1000; // 10 seconds - sort timeouts const int RETRY_TIMEOUT = 50 * 1000; // 50 seconds // Handles a binding request sent to the STUN server. @@ -166,17 +166,12 @@ UDPPort::UDPPort(rtc::Thread* thread, const std::string& password, const std::string& origin, bool emit_local_for_anyaddress) - : Port(thread, - LOCAL_PORT_TYPE, - factory, - network, - username, - password), + : Port(thread, LOCAL_PORT_TYPE, factory, network, username, password), requests_(thread), socket_(socket), error_(0), ready_(false), - stun_keepalive_delay_(KEEPALIVE_DELAY), + stun_keepalive_delay_(STUN_KEEPALIVE_INTERVAL), emit_local_for_anyaddress_(emit_local_for_anyaddress) { requests_.set_origin(origin); } @@ -202,7 +197,7 @@ UDPPort::UDPPort(rtc::Thread* thread, socket_(NULL), error_(0), ready_(false), - stun_keepalive_delay_(KEEPALIVE_DELAY), + stun_keepalive_delay_(STUN_KEEPALIVE_INTERVAL), emit_local_for_anyaddress_(emit_local_for_anyaddress) { requests_.set_origin(origin); } @@ -322,7 +317,7 @@ void UDPPort::GetStunStats(rtc::Optional* stats) { } void UDPPort::set_stun_keepalive_delay(const rtc::Optional& delay) { - stun_keepalive_delay_ = delay.value_or(KEEPALIVE_DELAY); + stun_keepalive_delay_ = delay.value_or(STUN_KEEPALIVE_INTERVAL); } void UDPPort::OnLocalAddressReady(rtc::AsyncPacketSocket* socket, diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc index 64b4b6eeb2..d8ec0c949a 100644 --- a/pc/peerconnection.cc +++ b/pc/peerconnection.cc @@ -600,6 +600,15 @@ std::string GetSetDescriptionErrorMessage(cricket::ContentSource source, return oss.str(); } +rtc::Optional RTCConfigurationToIceConfigOptionalInt( + int rtc_configuration_parameter) { + if (rtc_configuration_parameter == + webrtc::PeerConnectionInterface::RTCConfiguration::kUndefined) { + return rtc::nullopt; + } + return rtc_configuration_parameter; +} + } // namespace // Upon completion, posts a task to execute the callback of the @@ -4889,11 +4898,13 @@ cricket::IceConfig PeerConnection::ParseIceConfig( } cricket::IceConfig ice_config; - ice_config.receiving_timeout = config.ice_connection_receiving_timeout; + ice_config.receiving_timeout = RTCConfigurationToIceConfigOptionalInt( + config.ice_connection_receiving_timeout); ice_config.prioritize_most_likely_candidate_pairs = config.prioritize_most_likely_ice_candidate_pairs; ice_config.backup_connection_ping_interval = - config.ice_backup_candidate_pair_ping_interval; + RTCConfigurationToIceConfigOptionalInt( + config.ice_backup_candidate_pair_ping_interval); ice_config.continual_gathering_policy = gathering_policy; ice_config.presume_writable_when_fully_relayed = config.presume_writable_when_fully_relayed; diff --git a/rtc_base/timeutils.h b/rtc_base/timeutils.h index f602d483d5..5eb73c70ac 100644 --- a/rtc_base/timeutils.h +++ b/rtc_base/timeutils.h @@ -148,6 +148,8 @@ class IntervalRange { return min_ == o.min_ && max_ == o.max_; } + bool operator!=(const IntervalRange& o) const { return !operator==(o); } + private: int min_; int max_;