Chromium Code Reviews| Index: webrtc/p2p/base/p2ptransportchannel.cc |
| diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc |
| index ab7c32277f9f920c667b25c8f977998b5665b83d..1e2089db430814aaac0266d29a8858074cee07c8 100644 |
| --- a/webrtc/p2p/base/p2ptransportchannel.cc |
| +++ b/webrtc/p2p/base/p2ptransportchannel.cc |
| @@ -187,6 +187,7 @@ namespace cricket { |
| // well on a 28.8K modem, which is the slowest connection on which the voice |
| // quality is reasonable at all. |
| static const uint32_t PING_PACKET_SIZE = 60 * 8; |
| +// TODO(honghaiz): Change the word DELAY to INTERVAL whenever appropriate. |
| // STRONG_PING_DELAY (480ms) is applied when the best connection is both |
| // writable and receiving. |
| static const uint32_t STRONG_PING_DELAY = 1000 * PING_PACKET_SIZE / 1000; |
| @@ -201,7 +202,6 @@ static const uint32_t MAX_CURRENT_STRONG_DELAY = 900; |
| static const int MIN_CHECK_RECEIVING_DELAY = 50; // ms |
| - |
| P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, |
| int component, |
| P2PTransport* transport, |
| @@ -221,7 +221,8 @@ P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, |
| remote_candidate_generation_(0), |
| gathering_state_(kIceGatheringNew), |
| check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5), |
| - receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50) { |
| + receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50), |
| + backup_connection_ping_interval_(0) { |
| uint32_t weak_ping_delay = ::strtoul( |
| webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), |
| nullptr, 10); |
| @@ -296,9 +297,13 @@ void P2PTransportChannel::SetIceTiebreaker(uint64_t tiebreaker) { |
| tiebreaker_ = tiebreaker; |
| } |
| +TransportChannelState P2PTransportChannel::GetState() const { |
|
pthatcher1
2015/11/21 00:18:26
You can just call this method state(). And call G
honghaiz3
2015/12/01 18:05:36
Changed GetStateInternal to ComputeState().
GetSt
|
| + return state_; |
| +} |
| + |
| // A channel is considered ICE completed once there is at most one active |
| // connection per network and at least one active connection. |
| -TransportChannelState P2PTransportChannel::GetState() const { |
| +TransportChannelState P2PTransportChannel::GetStateInternal() const { |
| if (!had_connection_) { |
| return TransportChannelState::STATE_INIT; |
| } |
| @@ -372,18 +377,26 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { |
| gather_continually_ = config.gather_continually; |
| LOG(LS_INFO) << "Set gather_continually to " << gather_continually_; |
| - if (config.receiving_timeout_ms < 0) { |
| - return; |
| + if (config.backup_connection_ping_interval >= 0 && |
| + backup_connection_ping_interval_ != |
| + config.backup_connection_ping_interval) { |
| + backup_connection_ping_interval_ = config.backup_connection_ping_interval; |
| + LOG(LS_INFO) << "Set backup connection ping interval to " |
| + << backup_connection_ping_interval_ << " milliseconds."; |
| } |
| - receiving_timeout_ = config.receiving_timeout_ms; |
| - check_receiving_delay_ = |
| - std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10); |
| - for (Connection* connection : connections_) { |
| - connection->set_receiving_timeout(receiving_timeout_); |
| + if (config.receiving_timeout_ms >= 0 && |
| + receiving_timeout_ != config.receiving_timeout_ms) { |
|
pthatcher1
2015/11/21 00:18:26
If nothing else has _ms on the end, can you make a
honghaiz3
2015/12/01 18:05:36
Done. TODO added in transport.cc
|
| + receiving_timeout_ = config.receiving_timeout_ms; |
| + check_receiving_delay_ = |
| + std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10); |
| + |
| + for (Connection* connection : connections_) { |
| + connection->set_receiving_timeout(receiving_timeout_); |
| + } |
| + LOG(LS_INFO) << "Set ICE receiving timeout to " << receiving_timeout_ |
| + << " milliseconds"; |
| } |
| - LOG(LS_INFO) << "Set ICE receiving timeout to " << receiving_timeout_ |
| - << " milliseconds"; |
| } |
| // Go into the state of processing candidates, and running in general |
| @@ -1051,6 +1064,8 @@ void P2PTransportChannel::SwitchBestConnectionTo(Connection* conn) { |
| } |
| void P2PTransportChannel::UpdateChannelState() { |
| + state_ = GetStateInternal(); |
| + |
| bool writable = best_connection_ && best_connection_->writable(); |
| set_writable(writable); |
| @@ -1150,10 +1165,17 @@ void P2PTransportChannel::OnCheckAndPing() { |
| thread()->PostDelayed(check_delay, this, MSG_CHECK_AND_PING); |
| } |
| +// A connection is considered a backup connection if the channel state |
| +// is complete, the connection is not the best connection and it is active. |
| +bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { |
| + return state_ == STATE_COMPLETED && conn != best_connection_ && |
| + conn->active(); |
| +} |
| + |
| // Is the connection in a state for us to even consider pinging the other side? |
| // We consider a connection pingable even if it's not connected because that's |
| // how a TCP connection is kicked into reconnecting on the active side. |
| -bool P2PTransportChannel::IsPingable(Connection* conn) { |
| +bool P2PTransportChannel::IsPingable(Connection* conn, uint32_t now) { |
| const Candidate& remote = conn->remote_candidate(); |
| // We should never get this far with an empty remote ufrag. |
| ASSERT(!remote.username().empty()); |
| @@ -1169,9 +1191,18 @@ bool P2PTransportChannel::IsPingable(Connection* conn) { |
| return false; |
| } |
| - // If the channel is weak, ping all candidates. Otherwise, we only |
| - // want to ping connections that have not timed out on writing. |
| - return weak() || conn->write_state() != Connection::STATE_WRITE_TIMEOUT; |
| + // If the channel is weakly connected, ping all connections. |
| + if (weak()) { |
| + return true; |
| + } |
| + |
| + // Always ping active connections regardless whether the channel is completed |
| + // or not, but backup connections are pinged at a slower rate. |
| + if (IsBackupConnection(conn)) { |
| + return (now >= conn->last_ping_response_received() + |
| + backup_connection_ping_interval_); |
| + } |
| + return conn->active(); |
| } |
| // Returns the next pingable connection to ping. This will be the oldest |
| @@ -1195,7 +1226,7 @@ Connection* P2PTransportChannel::FindNextPingableConnection() { |
| Connection* oldest_needing_triggered_check = nullptr; |
| Connection* oldest = nullptr; |
| for (Connection* conn : connections_) { |
| - if (!IsPingable(conn)) { |
| + if (!IsPingable(conn, now)) { |
| continue; |
| } |
| bool needs_triggered_check = |
| @@ -1307,6 +1338,9 @@ void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) { |
| RequestSort(); |
| } |
| + UpdateChannelState(); |
| + // SignalConnectionRemoved should be called after the channel state is |
| + // updated because the receiver of the event may access the channel state. |
| SignalConnectionRemoved(this); |
| } |