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