Index: webrtc/p2p/base/port.cc |
diff --git a/webrtc/p2p/base/port.cc b/webrtc/p2p/base/port.cc |
index 0add358ec91392917091e957dfc39d28224be5af..2ce6723842f0952d64c14e18d811da87ab28bb9b 100644 |
--- a/webrtc/p2p/base/port.cc |
+++ b/webrtc/p2p/base/port.cc |
@@ -825,11 +825,11 @@ class ConnectionRequest : public StunRequest { |
Connection::Connection(Port* port, |
size_t index, |
- const Candidate& remote_candidate) |
+ const Candidate& remote_candidate, |
+ const IceConfig& config) |
: port_(port), |
local_candidate_index_(index), |
remote_candidate_(remote_candidate), |
- write_state_(STATE_WRITE_INIT), |
receiving_(false), |
connected_(true), |
pruned_(false), |
@@ -847,9 +847,12 @@ Connection::Connection(Port* port, |
reported_(false), |
state_(STATE_WAITING), |
receiving_timeout_(WEAK_CONNECTION_RECEIVE_TIMEOUT), |
- time_created_ms_(rtc::TimeMillis()) { |
+ time_created_ms_(rtc::TimeMillis()), |
+ presume_writable_when_fully_relayed_( |
+ config.presume_writable_when_fully_relayed) { |
// All of our connections start in WAITING state. |
// TODO(mallinath) - Start connections from STATE_FROZEN. |
+ write_state_ = InitialWriteState(); |
// Wire up to send stun packets |
requests_.SignalSendPacket.connect(this, &Connection::OnSendStunPacket); |
LOG_J(LS_INFO, this) << "Connection created"; |
@@ -958,9 +961,9 @@ void Connection::OnReadPacket( |
// If timed out sending writability checks, start up again |
if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) { |
+ set_write_state(InitialWriteState()); |
LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. " |
- << "Resetting state to STATE_WRITE_INIT."; |
- set_write_state(STATE_WRITE_INIT); |
+ << "Reset state to " << write_state_ << "."; |
} |
} else if (!msg) { |
// The packet was STUN, but failed a check and was handled internally. |
@@ -1037,7 +1040,7 @@ void Connection::HandleBindingRequest(IceMessage* msg) { |
// If it timed out on writing check, start up again |
if (!pruned_ && write_state_ == STATE_WRITE_TIMEOUT) { |
- set_write_state(STATE_WRITE_INIT); |
+ set_write_state(InitialWriteState()); |
} |
if (port_->GetIceRole() == ICEROLE_CONTROLLED) { |
@@ -1066,7 +1069,7 @@ void Connection::HandleBindingRequest(IceMessage* msg) { |
} |
void Connection::OnReadyToSend() { |
- if (write_state_ == STATE_WRITABLE) { |
+ if (presumed_writable()) { |
SignalReadyToSend(this); |
} |
} |
@@ -1131,14 +1134,11 @@ void Connection::UpdateState(int64_t now) { |
// Before timing out writability, we give a fixed amount of time. This is to |
// allow for changes in network conditions. |
- if ((write_state_ == STATE_WRITABLE) && |
+ if (presumed_writable() && |
TooManyFailures(pings_since_last_response_, |
- CONNECTION_WRITE_CONNECT_FAILURES, |
- rtt, |
- now) && |
+ CONNECTION_WRITE_CONNECT_FAILURES, rtt, now) && |
TooLongWithoutResponse(pings_since_last_response_, |
- CONNECTION_WRITE_CONNECT_TIMEOUT, |
- now)) { |
+ CONNECTION_WRITE_CONNECT_TIMEOUT, now)) { |
uint32_t max_pings = CONNECTION_WRITE_CONNECT_FAILURES; |
LOG_J(LS_INFO, this) << "Unwritable after " << max_pings |
<< " ping failures and " |
@@ -1246,11 +1246,12 @@ std::string Connection::ToString() const { |
'-', // not receiving (false) |
'R', // receiving (true) |
}; |
- const char WRITE_STATE_ABBREV[4] = { |
- 'W', // STATE_WRITABLE |
- 'w', // STATE_WRITE_UNRELIABLE |
- '-', // STATE_WRITE_INIT |
- 'x', // STATE_WRITE_TIMEOUT |
+ const char WRITE_STATE_ABBREV[5] = { |
+ 'W', // STATE_WRITABLE |
+ 'P', // STATE_PRESUMED_WRITABLE |
+ 'w', // STATE_WRITE_UNRELIABLE |
+ '-', // STATE_WRITE_INIT |
+ 'x', // STATE_WRITE_TIMEOUT |
}; |
const std::string ICESTATE[4] = { |
"W", // STATE_WAITING |
@@ -1367,6 +1368,16 @@ void Connection::OnConnectionRequestSent(ConnectionRequest* request) { |
} |
} |
+Connection::WriteState Connection::InitialWriteState() const { |
+ if (presume_writable_when_fully_relayed_ && |
+ local_candidate().type() == RELAY_PORT_TYPE && |
+ (remote_candidate().type() == RELAY_PORT_TYPE || |
+ remote_candidate().type() == PRFLX_PORT_TYPE)) { |
+ return STATE_PRESUMED_WRITABLE; |
+ } |
+ return STATE_WRITE_INIT; |
+} |
+ |
void Connection::HandleRoleConflictFromPeer() { |
port_->SignalRoleConflict(port_); |
} |
@@ -1399,6 +1410,11 @@ void Connection::MaybeUpdatePeerReflexiveCandidate( |
remote_candidate_.password() == new_candidate.password() && |
remote_candidate_.generation() == new_candidate.generation()) { |
remote_candidate_ = new_candidate; |
+ // If it turns out that the peer reflexive candidate was a TURN candidate, |
+ // we may need to change the state to STATE_PRESUMED_WRITABLE. |
+ if (write_state() == STATE_WRITE_INIT) { |
+ set_write_state(InitialWriteState()); |
+ } |
} |
} |
@@ -1492,8 +1508,9 @@ void Connection::MaybeAddPrflxCandidate(ConnectionRequest* request, |
ProxyConnection::ProxyConnection(Port* port, |
size_t index, |
- const Candidate& remote_candidate) |
- : Connection(port, index, remote_candidate) {} |
+ const Candidate& remote_candidate, |
+ const IceConfig& config) |
+ : Connection(port, index, remote_candidate, config) {} |
int ProxyConnection::Send(const void* data, size_t size, |
const rtc::PacketOptions& options) { |