OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 const std::string& ice_pwd) { | 347 const std::string& ice_pwd) { |
348 ASSERT(worker_thread_ == rtc::Thread::Current()); | 348 ASSERT(worker_thread_ == rtc::Thread::Current()); |
349 IceParameters* current_ice = remote_ice(); | 349 IceParameters* current_ice = remote_ice(); |
350 IceParameters new_ice(ice_ufrag, ice_pwd); | 350 IceParameters new_ice(ice_ufrag, ice_pwd); |
351 if (!current_ice || *current_ice != new_ice) { | 351 if (!current_ice || *current_ice != new_ice) { |
352 // Keep the ICE credentials so that newer connections | 352 // Keep the ICE credentials so that newer connections |
353 // are prioritized over the older ones. | 353 // are prioritized over the older ones. |
354 remote_ice_parameters_.push_back(new_ice); | 354 remote_ice_parameters_.push_back(new_ice); |
355 } | 355 } |
356 | 356 |
| 357 // Update the pwd of remote candidate if needed. |
| 358 for (RemoteCandidate& candidate : remote_candidates_) { |
| 359 if (candidate.username() == ice_ufrag && candidate.password().empty()) { |
| 360 candidate.set_password(ice_pwd); |
| 361 } |
| 362 } |
357 // We need to update the credentials for any peer reflexive candidates. | 363 // We need to update the credentials for any peer reflexive candidates. |
358 std::vector<Connection*>::iterator it = connections_.begin(); | 364 for (Connection* conn : connections_) { |
359 for (; it != connections_.end(); ++it) { | 365 conn->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd); |
360 (*it)->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd); | |
361 } | 366 } |
362 } | 367 } |
363 | 368 |
364 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { | 369 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { |
365 remote_ice_mode_ = mode; | 370 remote_ice_mode_ = mode; |
366 } | 371 } |
367 | 372 |
368 void P2PTransportChannel::SetIceConfig(const IceConfig& config) { | 373 void P2PTransportChannel::SetIceConfig(const IceConfig& config) { |
369 gather_continually_ = config.gather_continually; | 374 gather_continually_ = config.gather_continually; |
370 LOG(LS_INFO) << "Set gather_continually to " << gather_continually_; | 375 LOG(LS_INFO) << "Set gather_continually to " << gather_continually_; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 (it->address() == address && | 523 (it->address() == address && |
519 it->protocol() == ProtoToString(proto))) { | 524 it->protocol() == ProtoToString(proto))) { |
520 candidate = &(*it); | 525 candidate = &(*it); |
521 break; | 526 break; |
522 } | 527 } |
523 // We don't want to break here because we may find a match of the address | 528 // We don't want to break here because we may find a match of the address |
524 // later. | 529 // later. |
525 } | 530 } |
526 } | 531 } |
527 | 532 |
| 533 uint32_t remote_generation = 0; |
528 // The STUN binding request may arrive after setRemoteDescription and before | 534 // The STUN binding request may arrive after setRemoteDescription and before |
529 // adding remote candidate, so we need to set the password to the shared | 535 // adding remote candidate, so we need to set the password to the shared |
530 // password if the user name matches. | 536 // password if the user name matches. |
531 if (remote_password.empty()) { | 537 if (remote_password.empty()) { |
532 IceParameters* current_ice = remote_ice(); | 538 const IceParameters* ice_param = |
533 if (current_ice && remote_username == current_ice->ufrag) { | 539 FindRemoteIceFromUfrag(remote_username, &remote_generation); |
534 remote_password = current_ice->pwd; | 540 // Note: if not found, the remote_generation will still be 0. |
| 541 if (ice_param != nullptr) { |
| 542 remote_password = ice_param->pwd; |
535 } | 543 } |
536 } | 544 } |
537 | 545 |
538 Candidate remote_candidate; | 546 Candidate remote_candidate; |
539 bool remote_candidate_is_new = (candidate == nullptr); | 547 bool remote_candidate_is_new = (candidate == nullptr); |
540 if (!remote_candidate_is_new) { | 548 if (!remote_candidate_is_new) { |
541 remote_candidate = *candidate; | 549 remote_candidate = *candidate; |
542 if (ufrag_per_port) { | 550 if (ufrag_per_port) { |
543 remote_candidate.set_address(address); | 551 remote_candidate.set_address(address); |
544 } | 552 } |
(...skipping 12 matching lines...) Expand all Loading... |
557 port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_BAD_REQUEST, | 565 port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_BAD_REQUEST, |
558 STUN_ERROR_REASON_BAD_REQUEST); | 566 STUN_ERROR_REASON_BAD_REQUEST); |
559 return; | 567 return; |
560 } | 568 } |
561 remote_candidate_priority = priority_attr->value(); | 569 remote_candidate_priority = priority_attr->value(); |
562 | 570 |
563 // RFC 5245 | 571 // RFC 5245 |
564 // If the source transport address of the request does not match any | 572 // If the source transport address of the request does not match any |
565 // existing remote candidates, it represents a new peer reflexive remote | 573 // existing remote candidates, it represents a new peer reflexive remote |
566 // candidate. | 574 // candidate. |
567 remote_candidate = | 575 remote_candidate = Candidate(component(), ProtoToString(proto), address, 0, |
568 Candidate(component(), ProtoToString(proto), address, 0, | 576 remote_username, remote_password, |
569 remote_username, remote_password, PRFLX_PORT_TYPE, 0U, ""); | 577 PRFLX_PORT_TYPE, remote_generation, ""); |
570 | 578 |
571 // From RFC 5245, section-7.2.1.3: | 579 // From RFC 5245, section-7.2.1.3: |
572 // The foundation of the candidate is set to an arbitrary value, different | 580 // The foundation of the candidate is set to an arbitrary value, different |
573 // from the foundation for all other remote candidates. | 581 // from the foundation for all other remote candidates. |
574 remote_candidate.set_foundation( | 582 remote_candidate.set_foundation( |
575 rtc::ToString<uint32_t>(rtc::ComputeCrc32(remote_candidate.id()))); | 583 rtc::ToString<uint32_t>(rtc::ComputeCrc32(remote_candidate.id()))); |
576 | 584 |
577 remote_candidate.set_priority(remote_candidate_priority); | 585 remote_candidate.set_priority(remote_candidate_priority); |
578 } | 586 } |
579 | 587 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 // after sending the response since it could (in principle) delete the | 627 // after sending the response since it could (in principle) delete the |
620 // connection in question. | 628 // connection in question. |
621 SortConnections(); | 629 SortConnections(); |
622 } | 630 } |
623 | 631 |
624 void P2PTransportChannel::OnRoleConflict(PortInterface* port) { | 632 void P2PTransportChannel::OnRoleConflict(PortInterface* port) { |
625 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called | 633 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called |
626 // from Transport. | 634 // from Transport. |
627 } | 635 } |
628 | 636 |
| 637 const IceParameters* P2PTransportChannel::FindRemoteIceFromUfrag( |
| 638 const std::string& ufrag, |
| 639 uint32_t* generation) { |
| 640 const auto& params = remote_ice_parameters_; |
| 641 auto it = std::find_if( |
| 642 params.rbegin(), params.rend(), |
| 643 [ufrag](const IceParameters& param) { return param.ufrag == ufrag; }); |
| 644 if (it == params.rend()) { |
| 645 // Not found. |
| 646 return nullptr; |
| 647 } |
| 648 *generation = params.rend() - it - 1; |
| 649 return &(*it); |
| 650 } |
| 651 |
629 void P2PTransportChannel::OnNominated(Connection* conn) { | 652 void P2PTransportChannel::OnNominated(Connection* conn) { |
630 ASSERT(worker_thread_ == rtc::Thread::Current()); | 653 ASSERT(worker_thread_ == rtc::Thread::Current()); |
631 ASSERT(ice_role_ == ICEROLE_CONTROLLED); | 654 ASSERT(ice_role_ == ICEROLE_CONTROLLED); |
632 | 655 |
633 if (conn->write_state() == Connection::STATE_WRITABLE) { | 656 if (conn->write_state() == Connection::STATE_WRITABLE) { |
634 if (best_connection_ != conn) { | 657 if (best_connection_ != conn) { |
635 pending_best_connection_ = NULL; | 658 pending_best_connection_ = NULL; |
636 LOG(LS_INFO) << "Switching best connection on controlled side: " | 659 LOG(LS_INFO) << "Switching best connection on controlled side: " |
637 << conn->ToString(); | 660 << conn->ToString(); |
638 SwitchBestConnectionTo(conn); | 661 SwitchBestConnectionTo(conn); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 | 804 |
782 bool P2PTransportChannel::FindConnection( | 805 bool P2PTransportChannel::FindConnection( |
783 cricket::Connection* connection) const { | 806 cricket::Connection* connection) const { |
784 std::vector<Connection*>::const_iterator citer = | 807 std::vector<Connection*>::const_iterator citer = |
785 std::find(connections_.begin(), connections_.end(), connection); | 808 std::find(connections_.begin(), connections_.end(), connection); |
786 return citer != connections_.end(); | 809 return citer != connections_.end(); |
787 } | 810 } |
788 | 811 |
789 uint32_t P2PTransportChannel::GetRemoteCandidateGeneration( | 812 uint32_t P2PTransportChannel::GetRemoteCandidateGeneration( |
790 const Candidate& candidate) { | 813 const Candidate& candidate) { |
791 // We need to keep track of the remote ice restart so newer | 814 // If the candidate has a ufrag, use it to find the generation. |
792 // connections are prioritized over the older. | |
793 const auto& params = remote_ice_parameters_; | |
794 if (!candidate.username().empty()) { | 815 if (!candidate.username().empty()) { |
795 // If remote side sets the ufrag, we use that to determine the candidate | 816 uint32_t generation = 0; |
796 // generation. | 817 if (!FindRemoteIceFromUfrag(candidate.username(), &generation)) { |
797 // Search backward as it is more likely to find it near the end. | 818 // If the ufrag is not found, assume the next/future generation. |
798 auto it = std::find_if(params.rbegin(), params.rend(), | 819 generation = static_cast<uint32_t>(remote_ice_parameters_.size()); |
799 [candidate](const IceParameters& param) { | |
800 return param.ufrag == candidate.username(); | |
801 }); | |
802 if (it == params.rend()) { | |
803 // If not found, assume it is the next (future) generation. | |
804 return static_cast<uint32_t>(remote_ice_parameters_.size()); | |
805 } | 820 } |
806 return params.rend() - it - 1; | 821 return generation; |
807 } | 822 } |
808 // If candidate generation is set, use that. | 823 // If candidate generation is set, use that. |
809 if (candidate.generation() > 0) { | 824 if (candidate.generation() > 0) { |
810 return candidate.generation(); | 825 return candidate.generation(); |
811 } | 826 } |
812 // Otherwise, assume the generation from remote ice parameters. | 827 // Otherwise, assume the generation from remote ice parameters. |
813 return remote_ice_generation(); | 828 return remote_ice_generation(); |
814 } | 829 } |
815 | 830 |
816 // Check if remote candidate is already cached. | 831 // Check if remote candidate is already cached. |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 SignalSentPacket(this, sent_packet); | 1431 SignalSentPacket(this, sent_packet); |
1417 } | 1432 } |
1418 | 1433 |
1419 void P2PTransportChannel::OnReadyToSend(Connection* connection) { | 1434 void P2PTransportChannel::OnReadyToSend(Connection* connection) { |
1420 if (connection == best_connection_ && writable()) { | 1435 if (connection == best_connection_ && writable()) { |
1421 SignalReadyToSend(this); | 1436 SignalReadyToSend(this); |
1422 } | 1437 } |
1423 } | 1438 } |
1424 | 1439 |
1425 } // namespace cricket | 1440 } // namespace cricket |
OLD | NEW |