Index: webrtc/p2p/base/port.cc |
diff --git a/webrtc/p2p/base/port.cc b/webrtc/p2p/base/port.cc |
index da66928db284ae8810acac8299ec89dbe2d53ea1..d6bc27ba023bdf156dd8dd0aeca87f07a355a880 100644 |
--- a/webrtc/p2p/base/port.cc |
+++ b/webrtc/p2p/base/port.cc |
@@ -782,8 +782,8 @@ Connection::Connection(Port* port, |
: port_(port), |
local_candidate_index_(index), |
remote_candidate_(remote_candidate), |
- read_state_(STATE_READ_INIT), |
write_state_(STATE_WRITE_INIT), |
+ receiving_(false), |
connected_(true), |
pruned_(false), |
use_candidate_attr_(false), |
@@ -800,7 +800,8 @@ Connection::Connection(Port* port, |
sent_packets_discarded_(0), |
sent_packets_total_(0), |
reported_(false), |
- state_(STATE_WAITING) { |
+ state_(STATE_WAITING), |
+ receiving_timeout_(WEAK_CONNECTION_RECEIVE_TIMEOUT) { |
// All of our connections start in WAITING state. |
// TODO(mallinath) - Start connections from STATE_FROZEN. |
// Wire up to send stun packets |
@@ -841,16 +842,6 @@ uint64 Connection::priority() const { |
return priority; |
} |
-void Connection::set_read_state(ReadState value) { |
- ReadState old_value = read_state_; |
- read_state_ = value; |
- if (value != old_value) { |
- LOG_J(LS_VERBOSE, this) << "set_read_state"; |
- SignalStateChange(this); |
- CheckTimeout(); |
- } |
-} |
- |
void Connection::set_write_state(WriteState value) { |
WriteState old_value = write_state_; |
write_state_ = value; |
@@ -862,6 +853,15 @@ void Connection::set_write_state(WriteState value) { |
} |
} |
+void Connection::set_receiving(bool value) { |
+ if (value != receiving_) { |
+ LOG_J(LS_VERBOSE, this) << "set_receiving to " << value; |
+ receiving_ = value; |
+ SignalStateChange(this); |
+ CheckTimeout(); |
+ } |
+} |
+ |
void Connection::set_state(State state) { |
State old_state = state_; |
state_ = state; |
@@ -902,27 +902,17 @@ void Connection::OnReadPacket( |
const rtc::SocketAddress& addr(remote_candidate_.address()); |
if (!port_->GetStunMessage(data, size, addr, msg.accept(), &remote_ufrag)) { |
// The packet did not parse as a valid STUN message |
- |
- // If this connection is readable, then pass along the packet. |
- if (read_state_ == STATE_READABLE) { |
- // readable means data from this address is acceptable |
- // Send it on! |
- last_data_received_ = rtc::Time(); |
- recv_rate_tracker_.AddSamples(size); |
- SignalReadPacket(this, data, size, packet_time); |
- |
- // If timed out sending writability checks, start up again |
- if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) { |
- LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. " |
- << "Resetting state to STATE_WRITE_INIT."; |
- set_write_state(STATE_WRITE_INIT); |
- } |
- } else { |
- // Not readable means the remote address hasn't sent a valid |
- // binding request yet. |
- |
- LOG_J(LS_WARNING, this) |
- << "Received non-STUN packet from an unreadable connection."; |
+ // This is a data packet, pass it along. |
+ set_receiving(true); |
+ last_data_received_ = rtc::Time(); |
+ recv_rate_tracker_.AddSamples(size); |
+ SignalReadPacket(this, data, size, packet_time); |
+ |
+ // If timed out sending writability checks, start up again |
+ if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) { |
+ LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. " |
+ << "Resetting state to STATE_WRITE_INIT."; |
+ set_write_state(STATE_WRITE_INIT); |
} |
} else if (!msg) { |
// The packet was STUN, but failed a check and was handled internally. |
@@ -992,12 +982,7 @@ void Connection::OnReadPacket( |
// Otherwise we can mark connection to read timeout. No response will be |
// sent in this scenario. |
case STUN_BINDING_INDICATION: |
- if (read_state_ == STATE_READABLE) { |
- ReceivedPing(); |
- } else { |
- LOG_J(LS_WARNING, this) << "Received STUN binding indication " |
- << "from an unreadable connection."; |
- } |
+ ReceivedPing(); |
break; |
default: |
@@ -1024,8 +1009,7 @@ void Connection::Prune() { |
void Connection::Destroy() { |
LOG_J(LS_VERBOSE, this) << "Connection destroyed"; |
- set_read_state(STATE_READ_TIMEOUT); |
- set_write_state(STATE_WRITE_TIMEOUT); |
+ port_->thread()->Post(this, MSG_DELETE); |
} |
void Connection::PrintPingsSinceLastResponse(std::string* s, size_t max) { |
@@ -1089,7 +1073,6 @@ void Connection::UpdateState(uint32 now) { |
<< " rtt=" << rtt; |
set_write_state(STATE_WRITE_UNRELIABLE); |
} |
- |
if ((write_state_ == STATE_WRITE_UNRELIABLE || |
write_state_ == STATE_WRITE_INIT) && |
TooLongWithoutResponse(pings_since_last_response_, |
@@ -1101,6 +1084,11 @@ void Connection::UpdateState(uint32 now) { |
<< ", rtt=" << rtt; |
set_write_state(STATE_WRITE_TIMEOUT); |
} |
+ |
+ // Check the receiving state. |
+ uint32 last_recv_time = last_received(); |
+ bool receiving = now <= last_recv_time + receiving_timeout_; |
+ set_receiving(receiving); |
} |
void Connection::Ping(uint32 now) { |
@@ -1114,8 +1102,8 @@ void Connection::Ping(uint32 now) { |
} |
void Connection::ReceivedPing() { |
+ set_receiving(true); |
last_ping_received_ = rtc::Time(); |
- set_read_state(STATE_READABLE); |
} |
void Connection::ReceivedPingResponse() { |
@@ -1124,6 +1112,7 @@ void Connection::ReceivedPingResponse() { |
// So if we're not already, become writable. We may be bringing a pruned |
// connection back to life, but if we don't really want it, we can always |
// prune it again. |
+ set_receiving(true); |
set_write_state(STATE_WRITABLE); |
set_state(STATE_SUCCEEDED); |
pings_since_last_response_.clear(); |
@@ -1141,10 +1130,9 @@ std::string Connection::ToString() const { |
'-', // not connected (false) |
'C', // connected (true) |
}; |
- const char READ_STATE_ABBREV[3] = { |
- '-', // STATE_READ_INIT |
- 'R', // STATE_READABLE |
- 'x', // STATE_READ_TIMEOUT |
+ const char RECEIVE_STATE_ABBREV[2] = { |
+ '-', // not receiving (false) |
+ 'R', // receiving (true) |
}; |
const char WRITE_STATE_ABBREV[4] = { |
'W', // STATE_WRITABLE |
@@ -1172,7 +1160,7 @@ std::string Connection::ToString() const { |
<< ":" << remote.type() << ":" |
<< remote.protocol() << ":" << remote.address().ToSensitiveString() << "|" |
<< CONNECT_STATE_ABBREV[connected()] |
- << READ_STATE_ABBREV[read_state()] |
+ << RECEIVE_STATE_ABBREV[receiving()] |
<< WRITE_STATE_ABBREV[write_state()] |
<< ICESTATE[state()] << "|" |
<< priority() << "|"; |
@@ -1197,11 +1185,6 @@ void Connection::OnConnectionRequestResponse(ConnectionRequest* request, |
uint32 rtt = request->Elapsed(); |
ReceivedPingResponse(); |
- if (remote_ice_mode_ == ICEMODE_LITE) { |
- // A ice-lite end point never initiates ping requests. This will allow |
- // us to move to STATE_READABLE without an incoming ping request. |
- set_read_state(STATE_READABLE); |
- } |
if (LOG_CHECK_LEVEL_V(sev)) { |
bool use_candidate = ( |
@@ -1269,14 +1252,8 @@ void Connection::OnConnectionRequestSent(ConnectionRequest* request) { |
} |
void Connection::CheckTimeout() { |
- // If both read and write have timed out or read has never initialized, then |
- // this connection can contribute no more to p2p socket unless at some later |
- // date readability were to come back. However, we gave readability a long |
- // time to timeout, so at this point, it seems fair to get rid of this |
- // connection. |
- if ((read_state_ == STATE_READ_TIMEOUT || |
- read_state_ == STATE_READ_INIT) && |
- write_state_ == STATE_WRITE_TIMEOUT) { |
+ // If write has timed out and it is not receiving, remove the connection. |
+ if (!receiving_ && write_state_ == STATE_WRITE_TIMEOUT) { |
port_->thread()->Post(this, MSG_DELETE); |
} |
} |