| Index: webrtc/p2p/base/p2ptransportchannel.cc
|
| diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc
|
| index 5101bf341117c2cebafc14f5734c6f612fd857e8..c58a235f2dbc80483bc1915eaf089c573e25dc93 100644
|
| --- a/webrtc/p2p/base/p2ptransportchannel.cc
|
| +++ b/webrtc/p2p/base/p2ptransportchannel.cc
|
| @@ -354,10 +354,15 @@ void P2PTransportChannel::SetRemoteIceCredentials(const std::string& ice_ufrag,
|
| remote_ice_parameters_.push_back(new_ice);
|
| }
|
|
|
| + // Update the pwd of remote candidate if needed.
|
| + for (RemoteCandidate& candidate : remote_candidates_) {
|
| + if (candidate.username() == ice_ufrag && candidate.password().empty()) {
|
| + candidate.set_password(ice_pwd);
|
| + }
|
| + }
|
| // We need to update the credentials for any peer reflexive candidates.
|
| - std::vector<Connection*>::iterator it = connections_.begin();
|
| - for (; it != connections_.end(); ++it) {
|
| - (*it)->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd);
|
| + for (Connection* conn : connections_) {
|
| + conn->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd);
|
| }
|
| }
|
|
|
| @@ -525,13 +530,16 @@ void P2PTransportChannel::OnUnknownAddress(
|
| }
|
| }
|
|
|
| + uint32_t remote_generation = 0;
|
| // 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()) {
|
| - IceParameters* current_ice = remote_ice();
|
| - if (current_ice && remote_username == current_ice->ufrag) {
|
| - remote_password = current_ice->pwd;
|
| + 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;
|
| }
|
| }
|
|
|
| @@ -564,9 +572,9 @@ void P2PTransportChannel::OnUnknownAddress(
|
| // If the source transport address of the request does not match any
|
| // existing remote candidates, it represents a new peer reflexive remote
|
| // candidate.
|
| - remote_candidate =
|
| - Candidate(component(), ProtoToString(proto), address, 0,
|
| - remote_username, remote_password, PRFLX_PORT_TYPE, 0U, "");
|
| + remote_candidate = Candidate(component(), ProtoToString(proto), address, 0,
|
| + remote_username, remote_password,
|
| + PRFLX_PORT_TYPE, remote_generation, "");
|
|
|
| // From RFC 5245, section-7.2.1.3:
|
| // The foundation of the candidate is set to an arbitrary value, different
|
| @@ -626,6 +634,21 @@ void P2PTransportChannel::OnRoleConflict(PortInterface* port) {
|
| // from Transport.
|
| }
|
|
|
| +const IceParameters* P2PTransportChannel::FindRemoteIceFromUfrag(
|
| + const std::string& ufrag,
|
| + uint32_t* generation) {
|
| + const auto& params = remote_ice_parameters_;
|
| + auto it = std::find_if(
|
| + params.rbegin(), params.rend(),
|
| + [ufrag](const IceParameters& param) { return param.ufrag == ufrag; });
|
| + if (it == params.rend()) {
|
| + // Not found.
|
| + return nullptr;
|
| + }
|
| + *generation = params.rend() - it - 1;
|
| + return &(*it);
|
| +}
|
| +
|
| void P2PTransportChannel::OnNominated(Connection* conn) {
|
| ASSERT(worker_thread_ == rtc::Thread::Current());
|
| ASSERT(ice_role_ == ICEROLE_CONTROLLED);
|
| @@ -788,22 +811,14 @@ bool P2PTransportChannel::FindConnection(
|
|
|
| uint32_t P2PTransportChannel::GetRemoteCandidateGeneration(
|
| const Candidate& candidate) {
|
| - // We need to keep track of the remote ice restart so newer
|
| - // connections are prioritized over the older.
|
| - const auto& params = remote_ice_parameters_;
|
| + // If the candidate has a ufrag, use it to find the generation.
|
| if (!candidate.username().empty()) {
|
| - // If remote side sets the ufrag, we use that to determine the candidate
|
| - // generation.
|
| - // Search backward as it is more likely to find it near the end.
|
| - auto it = std::find_if(params.rbegin(), params.rend(),
|
| - [candidate](const IceParameters& param) {
|
| - return param.ufrag == candidate.username();
|
| - });
|
| - if (it == params.rend()) {
|
| - // If not found, assume it is the next (future) generation.
|
| - return static_cast<uint32_t>(remote_ice_parameters_.size());
|
| + uint32_t generation = 0;
|
| + if (!FindRemoteIceFromUfrag(candidate.username(), &generation)) {
|
| + // If the ufrag is not found, assume the next/future generation.
|
| + generation = static_cast<uint32_t>(remote_ice_parameters_.size());
|
| }
|
| - return params.rend() - it - 1;
|
| + return generation;
|
| }
|
| // If candidate generation is set, use that.
|
| if (candidate.generation() > 0) {
|
|
|