diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h index 1dfe2bdc80..7364aa0ced 100644 --- a/api/peerconnectioninterface.h +++ b/api/peerconnectioninterface.h @@ -489,8 +489,30 @@ class PeerConnectionInterface : public rtc::RefCountInterface { // re-determining was removed in ICEbis (ICE v2). bool redetermine_role_on_ice_restart = true; - // If set, the min interval (max rate) at which we will send ICE checks - // (STUN pings), in milliseconds. + // The following fields define intervals in milliseconds at which ICE + // connectivity checks are sent. + // + // We consider ICE is "strongly connected" for an agent when there is at + // least one candidate pair that currently succeeds in connectivity check + // from its direction i.e. sending a STUN ping and receives a STUN ping + // response, AND all candidate pairs have sent a minimum number of pings for + // connectivity (this number is implementation-specific). Otherwise, ICE is + // considered in "weak connectivity". + // + // Note that the above notion of strong and weak connectivity is not defined + // in RFC 5245, and they apply to our current ICE implementation only. + // + // 1) ice_check_interval_strong_connectivity defines the interval applied to + // ALL candidate pairs when ICE is strongly connected, and it overrides the + // default value of this interval in the ICE implementation; + // 2) ice_check_interval_weak_connectivity defines the counterpart for ALL + // pairs when ICE is weakly connected, and it overrides the default value of + // this interval in the ICE implementation; + // 3) ice_check_min_interval defines the minimal interval (equivalently the + // maximum rate) that overrides the above two intervals when either of them + // is less. + rtc::Optional ice_check_interval_strong_connectivity; + rtc::Optional ice_check_interval_weak_connectivity; rtc::Optional ice_check_min_interval; // The interval in milliseconds at which STUN candidates will resend STUN diff --git a/p2p/base/icetransportinternal.h b/p2p/base/icetransportinternal.h index 192a9d06e0..a111f44eac 100644 --- a/p2p/base/icetransportinternal.h +++ b/p2p/base/icetransportinternal.h @@ -110,9 +110,23 @@ struct IceConfig { // Default nomination mode if the remote does not support renomination. NominationMode default_nomination_mode = NominationMode::SEMI_AGGRESSIVE; + // The interval in milliseconds at which ICE checks (STUN pings) will be sent + // for a candidate pair when it is both writable and receiving (strong + // connectivity). This parameter overrides the default value given by + // |STRONG_PING_INTERVAL| in p2ptransport.h if set. + rtc::Optional ice_check_interval_strong_connectivity; + // The interval in milliseconds at which ICE checks (STUN pings) will be sent + // for a candidate pair when it is either not writable or not receiving (weak + // connectivity). This parameter overrides the default value given by + // |WEAK_PING_INTERVAL| in p2ptransport.h if set. + rtc::Optional ice_check_interval_weak_connectivity; // ICE checks (STUN pings) will not be sent at higher rate (lower interval) // than this, no matter what other settings there are. // Measure in milliseconds. + // + // Note that this parameter overrides both the above check intervals for + // candidate pairs with strong or weak connectivity, if either of the above + // interval is shorter than the min interval. rtc::Optional ice_check_min_interval; // The interval in milliseconds at which STUN candidates will resend STUN // binding requests to keep NAT bindings open. diff --git a/p2p/base/p2ptransportchannel.cc b/p2p/base/p2ptransportchannel.cc index b728334780..5384801674 100644 --- a/p2p/base/p2ptransportchannel.cc +++ b/p2p/base/p2ptransportchannel.cc @@ -105,9 +105,15 @@ 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. @@ -438,6 +444,11 @@ void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { remote_ice_mode_ = mode; } +// TODO(qingsi): We apply the convention that setting a rtc::Optional parameter +// to null restores its default value in the implementation. However, some +// rtc::Optional parameters are only processed below if non-null, e.g., +// regather_on_failed_networks_interval, and thus there is no way to restore the +// defaults. Fix this issue later for consistency. void P2PTransportChannel::SetIceConfig(const IceConfig& config) { if (config_.continual_gathering_policy != config.continual_gathering_policy) { if (!allocator_sessions_.empty()) { @@ -504,7 +515,8 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { 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; + << config_.regather_on_failed_networks_interval.value_or( + -1); } if (config.regather_all_networks_interval_range) { @@ -513,13 +525,15 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { config_.regather_all_networks_interval_range = config.regather_all_networks_interval_range; RTC_LOG(LS_INFO) << "Set regather_all_networks_interval_range to " - << config.regather_all_networks_interval_range->ToString(); + << config.regather_all_networks_interval_range + .value_or(rtc::IntervalRange(-1, 0)) + .ToString(); } if (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; + << config_.receiving_switching_delay.value_or(-1); } if (config_.default_nomination_mode != config.default_nomination_mode) { @@ -528,10 +542,28 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { << static_cast(config_.default_nomination_mode); } + if (config_.ice_check_interval_strong_connectivity != + 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); + } + + 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); + } + 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; + << config_.ice_check_min_interval.value_or(-1); } if (config_.network_preference != config.network_preference) { @@ -540,7 +572,8 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { RTC_LOG(LS_INFO) << "Set network preference to " << (config_.network_preference.has_value() ? config_.network_preference.value() - : 0); + : -1); // network_preference cannot be bound to + // int with value_or. } // TODO(qingsi): Resolve the naming conflict of stun_keepalive_delay in @@ -550,9 +583,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.has_value() - ? config_.stun_keepalive_interval.value() - : -1); + << config.stun_keepalive_interval.value_or(-1); } } diff --git a/p2p/base/p2ptransportchannel.h b/p2p/base/p2ptransportchannel.h index e4db38cb42..a9825cf856 100644 --- a/p2p/base/p2ptransportchannel.h +++ b/p2p/base/p2ptransportchannel.h @@ -20,6 +20,7 @@ #ifndef P2P_BASE_P2PTRANSPORTCHANNEL_H_ #define P2P_BASE_P2PTRANSPORTCHANNEL_H_ +#include #include #include #include @@ -180,19 +181,15 @@ class P2PTransportChannel : public IceTransportInternal, bool weak() const; int weak_ping_interval() const { - if (config_.ice_check_min_interval && - weak_ping_interval_ < *config_.ice_check_min_interval) { - return *config_.ice_check_min_interval; - } - return weak_ping_interval_; + return std::max(config_.ice_check_interval_weak_connectivity.value_or( + weak_ping_interval_), + config_.ice_check_min_interval.value_or(-1)); } int strong_ping_interval() const { - if (config_.ice_check_min_interval && - STRONG_PING_INTERVAL < *config_.ice_check_min_interval) { - return *config_.ice_check_min_interval; - } - return STRONG_PING_INTERVAL; + return std::max(config_.ice_check_interval_strong_connectivity.value_or( + STRONG_PING_INTERVAL), + config_.ice_check_min_interval.value_or(-1)); } // Returns true if it's possible to send packets on |connection|. diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc index 3df7ebf8aa..e37d9d88d8 100644 --- a/pc/peerconnection.cc +++ b/pc/peerconnection.cc @@ -663,6 +663,8 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( bool presume_writable_when_fully_relayed; bool enable_ice_renomination; bool redetermine_role_on_ice_restart; + rtc::Optional ice_check_interval_strong_connectivity; + rtc::Optional ice_check_interval_weak_connectivity; rtc::Optional ice_check_min_interval; rtc::Optional stun_candidate_keepalive_interval; rtc::Optional ice_regather_interval_range; @@ -703,6 +705,10 @@ 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_interval_strong_connectivity == + o.ice_check_interval_strong_connectivity && + ice_check_interval_weak_connectivity == + o.ice_check_interval_weak_connectivity && ice_check_min_interval == o.ice_check_min_interval && stun_candidate_keepalive_interval == o.stun_candidate_keepalive_interval && @@ -2700,6 +2706,10 @@ bool PeerConnection::SetConfiguration(const RTCConfiguration& configuration, configuration.ice_candidate_pool_size; modified_config.prune_turn_ports = configuration.prune_turn_ports; modified_config.ice_check_min_interval = configuration.ice_check_min_interval; + modified_config.ice_check_interval_strong_connectivity = + configuration.ice_check_interval_strong_connectivity; + modified_config.ice_check_interval_weak_connectivity = + configuration.ice_check_interval_weak_connectivity; modified_config.stun_candidate_keepalive_interval = configuration.stun_candidate_keepalive_interval; modified_config.turn_customizer = configuration.turn_customizer; @@ -4860,6 +4870,10 @@ cricket::IceConfig PeerConnection::ParseIceConfig( ice_config.continual_gathering_policy = gathering_policy; ice_config.presume_writable_when_fully_relayed = config.presume_writable_when_fully_relayed; + ice_config.ice_check_interval_strong_connectivity = + config.ice_check_interval_strong_connectivity; + ice_config.ice_check_interval_weak_connectivity = + config.ice_check_interval_weak_connectivity; ice_config.ice_check_min_interval = config.ice_check_min_interval; ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval; ice_config.regather_all_networks_interval_range = diff --git a/sdk/android/api/org/webrtc/PeerConnection.java b/sdk/android/api/org/webrtc/PeerConnection.java index 603b36e371..65aa734983 100644 --- a/sdk/android/api/org/webrtc/PeerConnection.java +++ b/sdk/android/api/org/webrtc/PeerConnection.java @@ -386,6 +386,28 @@ public class PeerConnection { public int iceCandidatePoolSize; public boolean pruneTurnPorts; public boolean presumeWritableWhenFullyRelayed; + // The following fields define intervals in milliseconds at which ICE + // connectivity checks are sent. + // + // We consider ICE is "strongly connected" for an agent when there is at + // least one candidate pair that currently succeeds in connectivity check + // from its direction i.e. sending a ping and receives a ping response, AND + // all candidate pairs have sent a minimum number of pings for connectivity + // (this number is implementation-specific). Otherwise, ICE is considered in + // "weak connectivity". + // + // Note that the above notion of strong and weak connectivity is not defined + // in RFC 5245, and they apply to our current ICE implementation only. + // + // 1) iceCheckIntervalStrongConnectivityMs defines the interval applied to + // ALL candidate pairs when ICE is strongly connected, + // 2) iceCheckIntervalWeakConnectivityMs defines the counterpart for ALL + // pairs when ICE is weakly connected, and + // 3) iceCheckMinInterval defines the minimal interval (equivalently the + // maximum rate) that overrides the above two intervals when either of them + // is less. + public Integer iceCheckIntervalStrongConnectivityMs; + public Integer iceCheckIntervalWeakConnectivityMs; public Integer iceCheckMinInterval; // The interval in milliseconds at which STUN candidates will resend STUN binding requests // to keep NAT bindings open. @@ -437,6 +459,8 @@ public class PeerConnection { iceCandidatePoolSize = 0; pruneTurnPorts = false; presumeWritableWhenFullyRelayed = false; + iceCheckIntervalStrongConnectivityMs = null; + iceCheckIntervalWeakConnectivityMs = null; iceCheckMinInterval = null; stunCandidateKeepaliveIntervalMs = null; disableIPv6OnWifi = false; @@ -529,6 +553,16 @@ public class PeerConnection { return presumeWritableWhenFullyRelayed; } + @CalledByNative("RTCConfiguration") + Integer getIceCheckIntervalStrongConnectivity() { + return iceCheckIntervalStrongConnectivityMs; + } + + @CalledByNative("RTCConfiguration") + Integer getIceCheckIntervalWeakConnectivity() { + return iceCheckIntervalWeakConnectivityMs; + } + @CalledByNative("RTCConfiguration") Integer getIceCheckMinInterval() { return iceCheckMinInterval; diff --git a/sdk/android/src/jni/pc/peerconnection.cc b/sdk/android/src/jni/pc/peerconnection.cc index 048d22490c..c18af7f17f 100644 --- a/sdk/android/src/jni/pc/peerconnection.cc +++ b/sdk/android/src/jni/pc/peerconnection.cc @@ -173,6 +173,16 @@ void JavaToNativeRTCConfiguration( rtc_config->presume_writable_when_fully_relayed = Java_RTCConfiguration_getPresumeWritableWhenFullyRelayed(jni, j_rtc_config); + ScopedJavaLocalRef j_ice_check_interval_strong_connectivity = + Java_RTCConfiguration_getIceCheckIntervalStrongConnectivity(jni, + j_rtc_config); + rtc_config->ice_check_interval_strong_connectivity = + JavaToNativeOptionalInt(jni, j_ice_check_interval_strong_connectivity); + ScopedJavaLocalRef j_ice_check_interval_weak_connectivity = + Java_RTCConfiguration_getIceCheckIntervalWeakConnectivity(jni, + j_rtc_config); + rtc_config->ice_check_interval_weak_connectivity = + JavaToNativeOptionalInt(jni, j_ice_check_interval_weak_connectivity); ScopedJavaLocalRef j_ice_check_min_interval = Java_RTCConfiguration_getIceCheckMinInterval(jni, j_rtc_config); rtc_config->ice_check_min_interval =