Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(601)

Side by Side Diff: webrtc/p2p/base/p2ptransportchannel.cc

Issue 1270613006: First step of passive aggressive nomination. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | webrtc/p2p/base/port.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 558
559 if (port->IceProtocol() == ICEPROTO_RFC5245) { 559 if (port->IceProtocol() == ICEPROTO_RFC5245) {
560 // RFC5245, the agent constructs a pair whose local candidate is equal to 560 // RFC5245, the agent constructs a pair whose local candidate is equal to
561 // the transport address on which the STUN request was received, and a 561 // the transport address on which the STUN request was received, and a
562 // remote candidate equal to the source transport address where the 562 // remote candidate equal to the source transport address where the
563 // request came from. 563 // request came from.
564 564
565 // There shouldn't be an existing connection with this remote address. 565 // There shouldn't be an existing connection with this remote address.
566 // When ports are muxed, this channel might get multiple unknown address 566 // When ports are muxed, this channel might get multiple unknown address
567 // signals. In that case if the connection is already exists, we should 567 // signals. In that case if the connection is already exists, we should
568 // simply ignore the signal othewise send server error. 568 // simply ignore the signal otherwise send server error.
569 if (port->GetConnection(remote_candidate.address())) { 569 if (port->GetConnection(remote_candidate.address())) {
570 if (port_muxed) { 570 if (port_muxed) {
571 LOG(LS_INFO) << "Connection already exists for peer reflexive " 571 LOG(LS_INFO) << "Connection already exists for peer reflexive "
572 << "candidate: " << remote_candidate.ToString(); 572 << "candidate: " << remote_candidate.ToString();
573 return; 573 return;
574 } else { 574 } else {
575 ASSERT(false); 575 ASSERT(false);
576 port->SendBindingErrorResponse(stun_msg, address, 576 port->SendBindingErrorResponse(stun_msg, address,
577 STUN_ERROR_SERVER_ERROR, 577 STUN_ERROR_SERVER_ERROR,
578 STUN_ERROR_REASON_SERVER_ERROR); 578 STUN_ERROR_REASON_SERVER_ERROR);
579 return; 579 return;
580 } 580 }
581 } 581 }
582 582
583 Connection* connection = port->CreateConnection( 583 Connection* connection = port->CreateConnection(
584 remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT); 584 remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT);
585 if (!connection) { 585 if (!connection) {
586 ASSERT(false); 586 ASSERT(false);
587 port->SendBindingErrorResponse(stun_msg, address, 587 port->SendBindingErrorResponse(stun_msg, address,
588 STUN_ERROR_SERVER_ERROR, 588 STUN_ERROR_SERVER_ERROR,
589 STUN_ERROR_REASON_SERVER_ERROR); 589 STUN_ERROR_REASON_SERVER_ERROR);
590 return; 590 return;
591 } 591 }
592 bool received_use_candidate =
593 stun_msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != nullptr;
594 if (received_use_candidate && ice_role_ == ICEROLE_CONTROLLED &&
595 protocol_type_ == ICEPROTO_RFC5245) {
596 connection->set_received_use_candidate(true);
pthatcher1 2015/08/06 01:41:42 I think we should call this set_nominated.
honghaiz3 2015/08/06 18:22:57 Done.
597 // Since the connection is not writable yet, it will only set the
598 // pending_best_connection_ there and will not incur double sorting.
599 OnUseCandidate(connection);
pthatcher1 2015/08/06 01:41:42 We can call OnUseCandidate *before* calling AddCon
honghaiz3 2015/08/06 18:22:57 I move this after AddConnection. Plus, hid the cal
600 }
592 601
593 LOG(LS_INFO) << "Adding connection from " 602 LOG(LS_INFO) << "Adding connection from "
594 << (remote_candidate_is_new ? "peer reflexive" : "resurrected") 603 << (remote_candidate_is_new ? "peer reflexive" : "resurrected")
595 << " candidate: " << remote_candidate.ToString(); 604 << " candidate: " << remote_candidate.ToString();
596 AddConnection(connection); 605 AddConnection(connection);
597 connection->ReceivedPing(); 606 connection->ReceivedPing();
598 607
599 // Send the pinger a successful stun response. 608 // Send the pinger a successful stun response.
600 port->SendBindingResponse(stun_msg, address); 609 port->SendBindingResponse(stun_msg, address);
601 610
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 std::stable_sort(connections_.begin(), connections_.end(), cmp); 1022 std::stable_sort(connections_.begin(), connections_.end(), cmp);
1014 LOG(LS_VERBOSE) << "Sorting available connections:"; 1023 LOG(LS_VERBOSE) << "Sorting available connections:";
1015 for (uint32 i = 0; i < connections_.size(); ++i) { 1024 for (uint32 i = 0; i < connections_.size(); ++i) {
1016 LOG(LS_VERBOSE) << connections_[i]->ToString(); 1025 LOG(LS_VERBOSE) << connections_[i]->ToString();
1017 } 1026 }
1018 1027
1019 Connection* top_connection = NULL; 1028 Connection* top_connection = NULL;
1020 if (connections_.size() > 0) 1029 if (connections_.size() > 0)
1021 top_connection = connections_[0]; 1030 top_connection = connections_[0];
1022 1031
1023 // We don't want to pick the best connections if channel is using RFC5245
1024 // and it's mode is CONTROLLED, as connections will be selected by the
1025 // CONTROLLING agent.
1026
1027 // If necessary, switch to the new choice. 1032 // If necessary, switch to the new choice.
1028 if (protocol_type_ != ICEPROTO_RFC5245 || ice_role_ == ICEROLE_CONTROLLING) { 1033 // As we are moving toward passive-aggressive nomination, a channel may be
1034 // selected as the best connection even if it is using RFC5245 and its mode
1035 // is CONTROLLED. Note that top_connection don't have to be writable to be
1036 // switched to although it will have higher priority if it is writable.
1037 if (protocol_type_ != ICEPROTO_RFC5245 || ice_role_ == ICEROLE_CONTROLLING ||
1038 (ice_role_ == ICEROLE_CONTROLLED &&
1039 !(best_connection_ && best_connection_->received_use_candidate()))) {
pthatcher1 2015/08/06 01:41:42 I think a best_nominated_connection() == (best_con
honghaiz3 2015/08/06 18:22:57 Done.
1029 if (ShouldSwitch(best_connection_, top_connection)) { 1040 if (ShouldSwitch(best_connection_, top_connection)) {
pthatcher1 2015/08/06 01:41:42 I think we should move all of this logic together
honghaiz3 2015/08/06 18:22:57 ShouldSwitch is defined as a helper function outsi
1030 LOG(LS_INFO) << "Switching best connection on controlling side: " 1041 LOG(LS_INFO) << "Switching best connection: "
1031 << top_connection->ToString(); 1042 << top_connection->ToString();
1032 SwitchBestConnectionTo(top_connection); 1043 SwitchBestConnectionTo(top_connection);
1033 } 1044 }
1034 } 1045 }
1035 1046
1036 // We can prune any connection for which there is a connected, writable 1047 // We can prune any connection for which there is a connected, writable
1037 // connection on the same network with better or equal priority. We leave 1048 // connection on the same network with better or equal priority. We leave
1038 // those with better priority just in case they become writable later (at 1049 // those with better priority just in case they become writable later (at
1039 // which point, we would prune out the current best connection). We leave 1050 // which point, we would prune out the current best connection). We leave
1040 // connections on other networks because they may not be using the same 1051 // connections on other networks because they may not be using the same
1041 // resources and they may represent very distinct paths over which we can 1052 // resources and they may represent very distinct paths over which we can
1042 // switch. If the |primier| connection is not connected, we may be 1053 // switch. If the |primier| connection is not connected, we may be
1043 // reconnecting a TCP connection and temporarily do not prune connections in 1054 // reconnecting a TCP connection and temporarily do not prune connections in
1044 // this network. See the big comment in CompareConnections. 1055 // this network. See the big comment in CompareConnections.
1045 std::set<rtc::Network*>::iterator network; 1056 // NOTE: If the ICE role is controlled and it has not received requests with
1046 for (network = networks.begin(); network != networks.end(); ++network) { 1057 // use_candidate yet, do not prune the connections because it may delete the
1047 Connection* primier = GetBestConnectionOnNetwork(*network); 1058 // connection that will be selected by the controlling side.
1048 if (!primier || (primier->write_state() != Connection::STATE_WRITABLE) || 1059 if (ice_role_ != ICEROLE_CONTROLLED ||
1049 !primier->connected()) 1060 (best_connection_ && best_connection_->received_use_candidate())) {
pthatcher1 2015/08/06 01:41:42 I think we want to make this if (best_connection
honghaiz3 2015/08/06 18:22:57 Done. I think calling it PruneConnections is proba
1050 continue; 1061 std::set<rtc::Network*>::iterator network;
1062 for (network = networks.begin(); network != networks.end(); ++network) {
1063 Connection* primier = GetBestConnectionOnNetwork(*network);
1064 if (!(primier && primier->writable() && primier->connected()))
1065 continue;
1051 1066
1052 for (uint32 i = 0; i < connections_.size(); ++i) { 1067 for (uint32 i = 0; i < connections_.size(); ++i) {
1053 if ((connections_[i] != primier) && 1068 if ((connections_[i] != primier) &&
1054 (connections_[i]->port()->Network() == *network) && 1069 (connections_[i]->port()->Network() == *network) &&
1055 (CompareConnectionCandidates(primier, connections_[i]) >= 0)) { 1070 (CompareConnectionCandidates(primier, connections_[i]) >= 0)) {
1056 connections_[i]->Prune(); 1071 connections_[i]->Prune();
1072 }
1057 } 1073 }
1058 } 1074 }
1059 } 1075 }
1060 1076
1061 // Check if all connections are timedout. 1077 // Check if all connections are timedout.
1062 bool all_connections_timedout = true; 1078 bool all_connections_timedout = true;
1063 for (uint32 i = 0; i < connections_.size(); ++i) { 1079 for (uint32 i = 0; i < connections_.size(); ++i) {
1064 if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) { 1080 if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) {
1065 all_connections_timedout = false; 1081 all_connections_timedout = false;
1066 break; 1082 break;
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 Connection *connection, const char *data, size_t len, 1426 Connection *connection, const char *data, size_t len,
1411 const rtc::PacketTime& packet_time) { 1427 const rtc::PacketTime& packet_time) {
1412 ASSERT(worker_thread_ == rtc::Thread::Current()); 1428 ASSERT(worker_thread_ == rtc::Thread::Current());
1413 1429
1414 // Do not deliver, if packet doesn't belong to the correct transport channel. 1430 // Do not deliver, if packet doesn't belong to the correct transport channel.
1415 if (!FindConnection(connection)) 1431 if (!FindConnection(connection))
1416 return; 1432 return;
1417 1433
1418 // Let the client know of an incoming packet 1434 // Let the client know of an incoming packet
1419 SignalReadPacket(this, data, len, packet_time, 0); 1435 SignalReadPacket(this, data, len, packet_time, 0);
1436
1437 // May need to switch the sending connection based on the receiving media path
1438 // if this is controlled side.
1439 if (best_connection_ != connection && ice_role_ == ICEROLE_CONTROLLED &&
1440 !(best_connection_ && best_connection_->received_use_candidate()) &&
1441 connection->writable()) {
pthatcher1 2015/08/06 01:41:42 I think if this would be easier to read: if (ice_
honghaiz3 2015/08/06 18:22:57 That is different from what I put. If the connect
1442 SwitchBestConnectionTo(connection);
1443 }
1420 } 1444 }
1421 1445
1422 void P2PTransportChannel::OnReadyToSend(Connection* connection) { 1446 void P2PTransportChannel::OnReadyToSend(Connection* connection) {
1423 if (connection == best_connection_ && writable()) { 1447 if (connection == best_connection_ && writable()) {
1424 SignalReadyToSend(this); 1448 SignalReadyToSend(this);
1425 } 1449 }
1426 } 1450 }
1427 1451
1428 } // namespace cricket 1452 } // namespace cricket
OLDNEW
« no previous file with comments | « no previous file | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | webrtc/p2p/base/port.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698