Make CONNECTION_WRITE_TIMEOUT configurable for ice connection

Bug: None
Change-Id: I0fd0616132705c6d15a77fc442be47080f1b81b1
Reviewed-on: https://webrtc-review.googlesource.com/c/112721
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25975}
diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h
index 4be3d2f..c2fb6a3 100644
--- a/api/peerconnectioninterface.h
+++ b/api/peerconnectioninterface.h
@@ -544,6 +544,11 @@
     // overrides the default value in the ICE implementation if set.
     absl::optional<int> ice_unwritable_min_checks;
 
+    // The min time period for which a candidate pair must wait for response to
+    // connectivity checks it becomes inactive. This parameter overrides the
+    // default value in the ICE implementation if set.
+    absl::optional<int> ice_inactive_timeout;
+
     // The interval in milliseconds at which STUN candidates will resend STUN
     // binding requests to keep NAT bindings open.
     absl::optional<int> stun_candidate_keepalive_interval;
diff --git a/p2p/base/icetransportinternal.cc b/p2p/base/icetransportinternal.cc
index 261e0f0..62bfb56 100644
--- a/p2p/base/icetransportinternal.cc
+++ b/p2p/base/icetransportinternal.cc
@@ -71,6 +71,9 @@
 int IceConfig::ice_unwritable_min_checks_or_default() const {
   return ice_unwritable_min_checks.value_or(CONNECTION_WRITE_CONNECT_FAILURES);
 }
+int IceConfig::ice_inactive_timeout_or_default() const {
+  return ice_inactive_timeout.value_or(CONNECTION_WRITE_TIMEOUT);
+}
 int IceConfig::stun_keepalive_interval_or_default() const {
   return stun_keepalive_interval.value_or(STUN_KEEPALIVE_INTERVAL);
 }
diff --git a/p2p/base/icetransportinternal.h b/p2p/base/icetransportinternal.h
index 49cc1cc..acc7169 100644
--- a/p2p/base/icetransportinternal.h
+++ b/p2p/base/icetransportinternal.h
@@ -136,6 +136,13 @@
   // overrides the default value given by |CONNECTION_WRITE_CONNECT_FAILURES| in
   // port.h if set, when determining the writability of a candidate pair.
   absl::optional<int> ice_unwritable_min_checks;
+
+  // The min time period for which a candidate pair must wait for response to
+  // connectivity checks it becomes inactive. This parameter overrides the
+  // default value given by |CONNECTION_WRITE_TIMEOUT| in port.h if set, when
+  // determining the writability of a candidate pair.
+  absl::optional<int> ice_inactive_timeout;
+
   // The interval in milliseconds at which STUN candidates will resend STUN
   // binding requests to keep NAT bindings open.
   absl::optional<int> stun_keepalive_interval;
@@ -166,6 +173,7 @@
   int ice_check_min_interval_or_default() const;
   int ice_unwritable_timeout_or_default() const;
   int ice_unwritable_min_checks_or_default() const;
+  int ice_inactive_timeout_or_default() const;
   int stun_keepalive_interval_or_default() const;
 };
 
diff --git a/p2p/base/p2pconstants.h b/p2p/base/p2pconstants.h
index a8462ec..a27e90b 100644
--- a/p2p/base/p2pconstants.h
+++ b/p2p/base/p2pconstants.h
@@ -87,6 +87,8 @@
 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.ice_inactive_timeout;
+extern const int CONNECTION_WRITE_TIMEOUT;
 // Default value of IceConfig.stun_keepalive_interval;
 extern const int STUN_KEEPALIVE_INTERVAL;
 
@@ -98,8 +100,6 @@
 // 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
diff --git a/p2p/base/p2ptransportchannel.cc b/p2p/base/p2ptransportchannel.cc
index 0d21613..6506b53 100644
--- a/p2p/base/p2ptransportchannel.cc
+++ b/p2p/base/p2ptransportchannel.cc
@@ -195,6 +195,7 @@
   connection->set_receiving_timeout(config_.receiving_timeout);
   connection->set_unwritable_timeout(config_.ice_unwritable_timeout);
   connection->set_unwritable_min_checks(config_.ice_unwritable_min_checks);
+  connection->set_inactive_timeout(config_.ice_inactive_timeout);
   connection->SignalReadPacket.connect(
       this, &P2PTransportChannel::OnReadPacket);
   connection->SignalReadyToSend.connect(
@@ -607,6 +608,15 @@
                      << config_.ice_unwritable_min_checks_or_default();
   }
 
+  if (config_.ice_inactive_timeout != config.ice_inactive_timeout) {
+    config_.ice_inactive_timeout = config.ice_inactive_timeout;
+    for (Connection* conn : connections_) {
+      conn->set_inactive_timeout(config_.ice_inactive_timeout);
+    }
+    RTC_LOG(LS_INFO) << "Set inactive timeout to "
+                     << config_.ice_inactive_timeout_or_default();
+  }
+
   if (config_.network_preference != config.network_preference) {
     config_.network_preference = config.network_preference;
     RequestSortAndStateUpdate("network preference changed");
@@ -682,7 +692,8 @@
                     "strongly connected");
   }
 
-  if (config.ice_unwritable_timeout_or_default() > CONNECTION_WRITE_TIMEOUT) {
+  if (config.ice_unwritable_timeout_or_default() >
+      config.ice_inactive_timeout_or_default()) {
     return RTCError(RTCErrorType::INVALID_PARAMETER,
                     "The timeout period for the writability state to become "
                     "UNRELIABLE is longer than that to become TIMEOUT.");
diff --git a/p2p/base/port.cc b/p2p/base/port.cc
index 4d93b4f..835e12c 100644
--- a/p2p/base/port.cc
+++ b/p2p/base/port.cc
@@ -1231,6 +1231,10 @@
   return unwritable_min_checks_.value_or(CONNECTION_WRITE_CONNECT_FAILURES);
 }
 
+int Connection::inactive_timeout() const {
+  return inactive_timeout_.value_or(CONNECTION_WRITE_TIMEOUT);
+}
+
 int Connection::receiving_timeout() const {
   return receiving_timeout_.value_or(WEAK_CONNECTION_RECEIVE_TIMEOUT);
 }
@@ -1483,8 +1487,8 @@
   }
   if ((write_state_ == STATE_WRITE_UNRELIABLE ||
        write_state_ == STATE_WRITE_INIT) &&
-      TooLongWithoutResponse(pings_since_last_response_,
-                             CONNECTION_WRITE_TIMEOUT, now)) {
+      TooLongWithoutResponse(pings_since_last_response_, inactive_timeout(),
+                             now)) {
     RTC_LOG(LS_INFO) << ToString() << ": Timed out after "
                      << now - pings_since_last_response_[0].sent_time
                      << " ms without a response, rtt=" << rtt;
diff --git a/p2p/base/port.h b/p2p/base/port.h
index ca4fedb..320ed62 100644
--- a/p2p/base/port.h
+++ b/p2p/base/port.h
@@ -585,6 +585,10 @@
   void set_unwritable_min_checks(const absl::optional<int>& value) {
     unwritable_min_checks_ = value;
   }
+  int inactive_timeout() const;
+  void set_inactive_timeout(const absl::optional<int>& value) {
+    inactive_timeout_ = value;
+  }
 
   // Gets the |ConnectionInfo| stats, where |best_connection| has not been
   // populated (default value false).
@@ -835,6 +839,7 @@
 
   absl::optional<int> unwritable_timeout_;
   absl::optional<int> unwritable_min_checks_;
+  absl::optional<int> inactive_timeout_;
 
   bool reported_;
   IceCandidatePairState state_;
diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc
index d7247c4..4bdaead 100644
--- a/pc/peerconnection.cc
+++ b/pc/peerconnection.cc
@@ -702,6 +702,7 @@
     absl::optional<int> ice_check_min_interval;
     absl::optional<int> ice_unwritable_timeout;
     absl::optional<int> ice_unwritable_min_checks;
+    absl::optional<int> ice_inactive_timeout;
     absl::optional<int> stun_candidate_keepalive_interval;
     absl::optional<rtc::IntervalRange> ice_regather_interval_range;
     webrtc::TurnCustomizer* turn_customizer;
@@ -755,6 +756,7 @@
          ice_check_min_interval == o.ice_check_min_interval &&
          ice_unwritable_timeout == o.ice_unwritable_timeout &&
          ice_unwritable_min_checks == o.ice_unwritable_min_checks &&
+         ice_inactive_timeout == o.ice_inactive_timeout &&
          stun_candidate_keepalive_interval ==
              o.stun_candidate_keepalive_interval &&
          ice_regather_interval_range == o.ice_regather_interval_range &&
@@ -3013,6 +3015,7 @@
   modified_config.ice_unwritable_timeout = configuration.ice_unwritable_timeout;
   modified_config.ice_unwritable_min_checks =
       configuration.ice_unwritable_min_checks;
+  modified_config.ice_inactive_timeout = configuration.ice_inactive_timeout;
   modified_config.stun_candidate_keepalive_interval =
       configuration.stun_candidate_keepalive_interval;
   modified_config.turn_customizer = configuration.turn_customizer;
@@ -5242,6 +5245,7 @@
   ice_config.ice_check_min_interval = config.ice_check_min_interval;
   ice_config.ice_unwritable_timeout = config.ice_unwritable_timeout;
   ice_config.ice_unwritable_min_checks = config.ice_unwritable_min_checks;
+  ice_config.ice_inactive_timeout = config.ice_inactive_timeout;
   ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval;
   ice_config.regather_all_networks_interval_range =
       config.ice_regather_interval_range;