| 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) {
|
|
|