diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc index f506126cef..78cb7045f8 100644 --- a/webrtc/p2p/base/p2ptransportchannel.cc +++ b/webrtc/p2p/base/p2ptransportchannel.cc @@ -577,56 +577,31 @@ void P2PTransportChannel::OnUnknownAddress( // is currently available for. See if we already have a candidate with the // address. If it isn't we need to create new candidate for it. - // Determine if the remote candidates use shared ufrag. - bool ufrag_per_port = false; - std::vector::iterator it; - if (remote_candidates_.size() > 0) { - it = remote_candidates_.begin(); - std::string username = it->username(); - for (; it != remote_candidates_.end(); ++it) { - if (it->username() != username) { - ufrag_per_port = true; - break; - } - } - } - - const Candidate* candidate = NULL; - std::string remote_password; - for (it = remote_candidates_.begin(); it != remote_candidates_.end(); ++it) { - if (it->username() == remote_username) { - remote_password = it->password(); - if (ufrag_per_port || - (it->address() == address && - it->protocol() == ProtoToString(proto))) { - candidate = &(*it); - break; - } - // We don't want to break here because we may find a match of the address - // later. + const Candidate* candidate = nullptr; + for (const Candidate& c : remote_candidates_) { + if (c.username() == remote_username && c.address() == address && + c.protocol() == ProtoToString(proto)) { + candidate = &c; + break; } } uint32_t remote_generation = 0; + std::string remote_password; // The STUN binding request may arrive after setRemoteDescription and before // adding remote candidate, so we need to set the password to the shared - // password if the user name matches. - if (remote_password.empty()) { - const IceParameters* ice_param = - FindRemoteIceFromUfrag(remote_username, &remote_generation); - // Note: if not found, the remote_generation will still be 0. - if (ice_param != nullptr) { - remote_password = ice_param->pwd; - } + // password and set the generation if the user name matches. + const IceParameters* ice_param = + FindRemoteIceFromUfrag(remote_username, &remote_generation); + // Note: if not found, the remote_generation will still be 0. + if (ice_param != nullptr) { + remote_password = ice_param->pwd; } Candidate remote_candidate; bool remote_candidate_is_new = (candidate == nullptr); if (!remote_candidate_is_new) { remote_candidate = *candidate; - if (ufrag_per_port) { - remote_candidate.set_address(address); - } } else { // Create a new candidate with this address. // The priority of the candidate is set to the PRIORITY attribute diff --git a/webrtc/p2p/base/p2ptransportchannel_unittest.cc b/webrtc/p2p/base/p2ptransportchannel_unittest.cc index 6c26704388..e5e63a3fa0 100644 --- a/webrtc/p2p/base/p2ptransportchannel_unittest.cc +++ b/webrtc/p2p/base/p2ptransportchannel_unittest.cc @@ -1071,6 +1071,16 @@ TEST_F(P2PTransportChannelTest, HandleUfragPwdChange) { DestroyChannels(); } +// Same as above test, but with a symmetric NAT. +// We should end up with relay<->prflx candidate pairs, with generation "1". +TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeSymmetricNat) { + ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags, + kDefaultPortAllocatorFlags); + CreateChannels(1); + TestHandleIceUfragPasswordChanged(); + DestroyChannels(); +} + // Test the operation of GetStats. TEST_F(P2PTransportChannelTest, GetStats) { ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags, @@ -1333,6 +1343,11 @@ TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) { SetAllowTcpListen(0, true); // actpass. SetAllowTcpListen(1, false); // active. + // We want SetRemoteIceCredentials to be called as it normally would. + // Otherwise we won't know what credentials to use for the expected + // prflx TCP candidates. + set_remote_ice_credential_source(FROM_SETICECREDENTIALS); + // Pause candidate so we could verify the candidate properties. PauseCandidates(0); PauseCandidates(1); @@ -1627,6 +1642,7 @@ class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase { static_cast(nat_type - NAT_FULL_CONE)); ConfigureEndpoint(outer_nat, 0, config1); ConfigureEndpoint(outer_nat, 1, config2); + set_remote_ice_credential_source(FROM_SETICECREDENTIALS); } void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat, int endpoint, Config config) { diff --git a/webrtc/p2p/base/port.cc b/webrtc/p2p/base/port.cc index c0e8d9770d..6e26371dae 100644 --- a/webrtc/p2p/base/port.cc +++ b/webrtc/p2p/base/port.cc @@ -1485,6 +1485,7 @@ void Connection::MaybeAddPrflxCandidate(ConnectionRequest* request, new_local_candidate.set_network_name(local_candidate().network_name()); new_local_candidate.set_network_type(local_candidate().network_type()); new_local_candidate.set_related_address(local_candidate().address()); + new_local_candidate.set_generation(local_candidate().generation()); new_local_candidate.set_foundation(ComputeFoundation( PRFLX_PORT_TYPE, local_candidate().protocol(), local_candidate().relay_protocol(), local_candidate().address()));