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 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |