Use active ICE controller in P2PTransportChannel with an adapter (#6/n)
Controlled by a field trial, P2PTransportChannel can now use an active ICE controller instead of a legacy ICE controller. P2PTransportChannel unit tests need non-trivial changes to exercise the refactored code path, so the testing changes are added in a follow-up CL. Bug: webrtc:14367, webrtc:14131 Change-Id: I00d4930a5692c7d6d331ea9d6c2a2199304e363c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/274701 Commit-Queue: Sameer Vijaykar <samvi@google.com> Reviewed-by: Jonas Oreland <jonaso@webrtc.org> Reviewed-by: Per Kjellander <perkj@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38114}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
b555e83395
commit
1adcde9dfe
@ -89,7 +89,18 @@ struct IceTransportInit final {
|
|||||||
// transport, in contrast with a legacy ICE controller that only picks the
|
// transport, in contrast with a legacy ICE controller that only picks the
|
||||||
// best connection to use or ping, and lets the transport decide when and
|
// best connection to use or ping, and lets the transport decide when and
|
||||||
// whether to switch.
|
// whether to switch.
|
||||||
// TODO(bugs.webrtc.org/14367): currently unused, update doc when used.
|
//
|
||||||
|
// Which ICE controller is used is determined based on the field trial
|
||||||
|
// "WebRTC-UseActiveIceController" as follows:
|
||||||
|
//
|
||||||
|
// 1. If the field trial is not enabled
|
||||||
|
// a. The legacy ICE controller factory is used if one is supplied.
|
||||||
|
// b. If not, a default ICE controller (BasicIceController) is
|
||||||
|
// constructed and used.
|
||||||
|
//
|
||||||
|
// 2. If the field trial is enabled
|
||||||
|
// - then an active ICE controller factory must be supplied and is used.
|
||||||
|
// - the legacy ICE controller factory is not used in this case.
|
||||||
void set_active_ice_controller_factory(
|
void set_active_ice_controller_factory(
|
||||||
cricket::ActiveIceControllerFactoryInterface*
|
cricket::ActiveIceControllerFactoryInterface*
|
||||||
active_ice_controller_factory) {
|
active_ice_controller_factory) {
|
||||||
|
@ -199,7 +199,9 @@ if (rtc_include_tests) {
|
|||||||
sources = [
|
sources = [
|
||||||
"base/fake_dtls_transport.h",
|
"base/fake_dtls_transport.h",
|
||||||
"base/fake_packet_transport.h",
|
"base/fake_packet_transport.h",
|
||||||
|
"base/mock_active_ice_controller.h",
|
||||||
"base/mock_async_resolver.h",
|
"base/mock_async_resolver.h",
|
||||||
|
"base/mock_ice_controller.h",
|
||||||
"base/mock_ice_transport.h",
|
"base/mock_ice_transport.h",
|
||||||
"base/test_stun_server.cc",
|
"base/test_stun_server.cc",
|
||||||
"base/test_stun_server.h",
|
"base/test_stun_server.h",
|
||||||
|
89
p2p/base/mock_active_ice_controller.h
Normal file
89
p2p/base/mock_active_ice_controller.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 The WebRTC Project Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef P2P_BASE_MOCK_ACTIVE_ICE_CONTROLLER_H_
|
||||||
|
#define P2P_BASE_MOCK_ACTIVE_ICE_CONTROLLER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "p2p/base/active_ice_controller_factory_interface.h"
|
||||||
|
#include "p2p/base/active_ice_controller_interface.h"
|
||||||
|
#include "test/gmock.h"
|
||||||
|
|
||||||
|
namespace cricket {
|
||||||
|
|
||||||
|
class MockActiveIceController : public cricket::ActiveIceControllerInterface {
|
||||||
|
public:
|
||||||
|
explicit MockActiveIceController(
|
||||||
|
const cricket::ActiveIceControllerFactoryArgs& args) {}
|
||||||
|
~MockActiveIceController() override = default;
|
||||||
|
|
||||||
|
MOCK_METHOD(void, SetIceConfig, (const cricket::IceConfig&), (override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
OnConnectionAdded,
|
||||||
|
(const cricket::Connection*),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
OnConnectionSwitched,
|
||||||
|
(const cricket::Connection*),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
OnConnectionDestroyed,
|
||||||
|
(const cricket::Connection*),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
OnConnectionPinged,
|
||||||
|
(const cricket::Connection*),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
OnConnectionUpdated,
|
||||||
|
(const cricket::Connection*),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(bool,
|
||||||
|
GetUseCandidateAttribute,
|
||||||
|
(const cricket::Connection*,
|
||||||
|
cricket::NominationMode,
|
||||||
|
cricket::IceMode),
|
||||||
|
(const, override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
OnSortAndSwitchRequest,
|
||||||
|
(cricket::IceSwitchReason),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
OnImmediateSortAndSwitchRequest,
|
||||||
|
(cricket::IceSwitchReason),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(bool,
|
||||||
|
OnImmediateSwitchRequest,
|
||||||
|
(cricket::IceSwitchReason, const cricket::Connection*),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(const cricket::Connection*,
|
||||||
|
FindNextPingableConnection,
|
||||||
|
(),
|
||||||
|
(override));
|
||||||
|
};
|
||||||
|
|
||||||
|
class MockActiveIceControllerFactory
|
||||||
|
: public cricket::ActiveIceControllerFactoryInterface {
|
||||||
|
public:
|
||||||
|
~MockActiveIceControllerFactory() override = default;
|
||||||
|
|
||||||
|
std::unique_ptr<cricket::ActiveIceControllerInterface> Create(
|
||||||
|
const cricket::ActiveIceControllerFactoryArgs& args) {
|
||||||
|
RecordActiveIceControllerCreated();
|
||||||
|
return std::make_unique<MockActiveIceController>(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOCK_METHOD(void, RecordActiveIceControllerCreated, ());
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cricket
|
||||||
|
|
||||||
|
#endif // P2P_BASE_MOCK_ACTIVE_ICE_CONTROLLER_H_
|
90
p2p/base/mock_ice_controller.h
Normal file
90
p2p/base/mock_ice_controller.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 The WebRTC Project Authors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef P2P_BASE_MOCK_ICE_CONTROLLER_H_
|
||||||
|
#define P2P_BASE_MOCK_ICE_CONTROLLER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "p2p/base/ice_controller_factory_interface.h"
|
||||||
|
#include "p2p/base/ice_controller_interface.h"
|
||||||
|
#include "test/gmock.h"
|
||||||
|
|
||||||
|
namespace cricket {
|
||||||
|
|
||||||
|
class MockIceController : public cricket::IceControllerInterface {
|
||||||
|
public:
|
||||||
|
explicit MockIceController(const cricket::IceControllerFactoryArgs& args) {}
|
||||||
|
~MockIceController() override = default;
|
||||||
|
|
||||||
|
MOCK_METHOD(void, SetIceConfig, (const cricket::IceConfig&), (override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
SetSelectedConnection,
|
||||||
|
(const cricket::Connection*),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void, AddConnection, (const cricket::Connection*), (override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
OnConnectionDestroyed,
|
||||||
|
(const cricket::Connection*),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(rtc::ArrayView<const cricket::Connection*>,
|
||||||
|
connections,
|
||||||
|
(),
|
||||||
|
(const, override));
|
||||||
|
MOCK_METHOD(bool, HasPingableConnection, (), (const, override));
|
||||||
|
MOCK_METHOD(cricket::IceControllerInterface::PingResult,
|
||||||
|
SelectConnectionToPing,
|
||||||
|
(int64_t),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(bool,
|
||||||
|
GetUseCandidateAttr,
|
||||||
|
(const cricket::Connection*,
|
||||||
|
cricket::NominationMode,
|
||||||
|
cricket::IceMode),
|
||||||
|
(const, override));
|
||||||
|
MOCK_METHOD(const cricket::Connection*,
|
||||||
|
FindNextPingableConnection,
|
||||||
|
(),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
MarkConnectionPinged,
|
||||||
|
(const cricket::Connection*),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(cricket::IceControllerInterface::SwitchResult,
|
||||||
|
ShouldSwitchConnection,
|
||||||
|
(cricket::IceSwitchReason, const cricket::Connection*),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(cricket::IceControllerInterface::SwitchResult,
|
||||||
|
SortAndSwitchConnection,
|
||||||
|
(cricket::IceSwitchReason),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(std::vector<const cricket::Connection*>,
|
||||||
|
PruneConnections,
|
||||||
|
(),
|
||||||
|
(override));
|
||||||
|
};
|
||||||
|
|
||||||
|
class MockIceControllerFactory : public cricket::IceControllerFactoryInterface {
|
||||||
|
public:
|
||||||
|
~MockIceControllerFactory() override = default;
|
||||||
|
|
||||||
|
std::unique_ptr<cricket::IceControllerInterface> Create(
|
||||||
|
const cricket::IceControllerFactoryArgs& args) override {
|
||||||
|
RecordIceControllerCreated();
|
||||||
|
return std::make_unique<MockIceController>(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOCK_METHOD(void, RecordIceControllerCreated, ());
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cricket
|
||||||
|
|
||||||
|
#endif // P2P_BASE_MOCK_ICE_CONTROLLER_H_
|
@ -93,15 +93,23 @@ rtc::RouteEndpoint CreateRouteEndpointFromCandidate(
|
|||||||
uses_turn);
|
uses_turn);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
bool UseActiveIceControllerFieldTrialEnabled(
|
||||||
|
const webrtc::FieldTrialsView* field_trials) {
|
||||||
namespace cricket {
|
// Feature to refactor ICE controller and enable active ICE controllers.
|
||||||
|
// Field trial key reserved in bugs.webrtc.org/14367
|
||||||
|
return field_trials &&
|
||||||
|
field_trials->IsEnabled("WebRTC-UseActiveIceController");
|
||||||
|
}
|
||||||
|
|
||||||
using ::webrtc::RTCError;
|
using ::webrtc::RTCError;
|
||||||
using ::webrtc::RTCErrorType;
|
using ::webrtc::RTCErrorType;
|
||||||
using ::webrtc::SafeTask;
|
using ::webrtc::SafeTask;
|
||||||
using ::webrtc::TimeDelta;
|
using ::webrtc::TimeDelta;
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
|
namespace cricket {
|
||||||
|
|
||||||
bool IceCredentialsChanged(absl::string_view old_ufrag,
|
bool IceCredentialsChanged(absl::string_view old_ufrag,
|
||||||
absl::string_view old_pwd,
|
absl::string_view old_pwd,
|
||||||
absl::string_view new_ufrag,
|
absl::string_view new_ufrag,
|
||||||
@ -122,12 +130,14 @@ std::unique_ptr<P2PTransportChannel> P2PTransportChannel::Create(
|
|||||||
transport_name, component, init.port_allocator(), nullptr,
|
transport_name, component, init.port_allocator(), nullptr,
|
||||||
std::make_unique<webrtc::WrappingAsyncDnsResolverFactory>(
|
std::make_unique<webrtc::WrappingAsyncDnsResolverFactory>(
|
||||||
init.async_resolver_factory()),
|
init.async_resolver_factory()),
|
||||||
init.event_log(), init.ice_controller_factory(), init.field_trials()));
|
init.event_log(), init.ice_controller_factory(),
|
||||||
|
init.active_ice_controller_factory(), init.field_trials()));
|
||||||
} else {
|
} else {
|
||||||
return absl::WrapUnique(new P2PTransportChannel(
|
return absl::WrapUnique(new P2PTransportChannel(
|
||||||
transport_name, component, init.port_allocator(),
|
transport_name, component, init.port_allocator(),
|
||||||
init.async_dns_resolver_factory(), nullptr, init.event_log(),
|
init.async_dns_resolver_factory(), nullptr, init.event_log(),
|
||||||
init.ice_controller_factory(), init.field_trials()));
|
init.ice_controller_factory(), init.active_ice_controller_factory(),
|
||||||
|
init.field_trials()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +153,7 @@ P2PTransportChannel::P2PTransportChannel(
|
|||||||
/* owned_dns_resolver_factory= */ nullptr,
|
/* owned_dns_resolver_factory= */ nullptr,
|
||||||
/* event_log= */ nullptr,
|
/* event_log= */ nullptr,
|
||||||
/* ice_controller_factory= */ nullptr,
|
/* ice_controller_factory= */ nullptr,
|
||||||
|
/* active_ice_controller_factory= */ nullptr,
|
||||||
field_trials) {}
|
field_trials) {}
|
||||||
|
|
||||||
// Private constructor, called from Create()
|
// Private constructor, called from Create()
|
||||||
@ -155,6 +166,7 @@ P2PTransportChannel::P2PTransportChannel(
|
|||||||
owned_dns_resolver_factory,
|
owned_dns_resolver_factory,
|
||||||
webrtc::RtcEventLog* event_log,
|
webrtc::RtcEventLog* event_log,
|
||||||
IceControllerFactoryInterface* ice_controller_factory,
|
IceControllerFactoryInterface* ice_controller_factory,
|
||||||
|
ActiveIceControllerFactoryInterface* active_ice_controller_factory,
|
||||||
const webrtc::FieldTrialsView* field_trials)
|
const webrtc::FieldTrialsView* field_trials)
|
||||||
: transport_name_(transport_name),
|
: transport_name_(transport_name),
|
||||||
component_(component),
|
component_(component),
|
||||||
@ -210,11 +222,9 @@ P2PTransportChannel::P2PTransportChannel(
|
|||||||
&ice_field_trials_,
|
&ice_field_trials_,
|
||||||
field_trials ? field_trials->Lookup("WebRTC-IceControllerFieldTrials")
|
field_trials ? field_trials->Lookup("WebRTC-IceControllerFieldTrials")
|
||||||
: ""};
|
: ""};
|
||||||
if (ice_controller_factory != nullptr) {
|
ice_adapter_ = std::make_unique<IceControllerAdapter>(
|
||||||
ice_controller_ = ice_controller_factory->Create(args);
|
args, ice_controller_factory, active_ice_controller_factory, field_trials,
|
||||||
} else {
|
/* transport= */ this);
|
||||||
ice_controller_ = std::make_unique<BasicIceController>(args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
P2PTransportChannel::~P2PTransportChannel() {
|
P2PTransportChannel::~P2PTransportChannel() {
|
||||||
@ -282,18 +292,21 @@ void P2PTransportChannel::AddConnection(Connection* connection) {
|
|||||||
webrtc::IceCandidatePairConfigType::kAdded);
|
webrtc::IceCandidatePairConfigType::kAdded);
|
||||||
|
|
||||||
connections_.push_back(connection);
|
connections_.push_back(connection);
|
||||||
ice_controller_->AddConnection(connection);
|
ice_adapter_->OnConnectionAdded(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
bool P2PTransportChannel::MaybeSwitchSelectedConnection(
|
bool P2PTransportChannel::MaybeSwitchSelectedConnection(
|
||||||
Connection* new_connection,
|
const Connection* new_connection,
|
||||||
IceSwitchReason reason) {
|
IceSwitchReason reason) {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
|
|
||||||
return MaybeSwitchSelectedConnection(
|
return MaybeSwitchSelectedConnection(
|
||||||
reason, ice_controller_->ShouldSwitchConnection(reason, new_connection));
|
reason,
|
||||||
|
ice_adapter_->LegacyShouldSwitchConnection(reason, new_connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
bool P2PTransportChannel::MaybeSwitchSelectedConnection(
|
bool P2PTransportChannel::MaybeSwitchSelectedConnection(
|
||||||
IceSwitchReason reason,
|
IceSwitchReason reason,
|
||||||
IceControllerInterface::SwitchResult result) {
|
IceControllerInterface::SwitchResult result) {
|
||||||
@ -530,7 +543,7 @@ void P2PTransportChannel::SetRemoteIceParameters(
|
|||||||
ice_params, static_cast<int>(remote_ice_parameters_.size() - 1));
|
ice_params, static_cast<int>(remote_ice_parameters_.size() - 1));
|
||||||
}
|
}
|
||||||
// Updating the remote ICE candidate generation could change the sort order.
|
// Updating the remote ICE candidate generation could change the sort order.
|
||||||
RequestSortAndStateUpdate(
|
ice_adapter_->OnSortAndSwitchRequest(
|
||||||
IceSwitchReason::REMOTE_CANDIDATE_GENERATION_CHANGE);
|
IceSwitchReason::REMOTE_CANDIDATE_GENERATION_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,7 +698,8 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
|
|||||||
|
|
||||||
if (config_.network_preference != config.network_preference) {
|
if (config_.network_preference != config.network_preference) {
|
||||||
config_.network_preference = config.network_preference;
|
config_.network_preference = config.network_preference;
|
||||||
RequestSortAndStateUpdate(IceSwitchReason::NETWORK_PREFERENCE_CHANGE);
|
ice_adapter_->OnSortAndSwitchRequest(
|
||||||
|
IceSwitchReason::NETWORK_PREFERENCE_CHANGE);
|
||||||
RTC_LOG(LS_INFO) << "Set network preference to "
|
RTC_LOG(LS_INFO) << "Set network preference to "
|
||||||
<< (config_.network_preference.has_value()
|
<< (config_.network_preference.has_value()
|
||||||
? config_.network_preference.value()
|
? config_.network_preference.value()
|
||||||
@ -711,7 +725,7 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
|
|||||||
config_.vpn_preference = config.vpn_preference;
|
config_.vpn_preference = config.vpn_preference;
|
||||||
allocator_->SetVpnPreference(config_.vpn_preference);
|
allocator_->SetVpnPreference(config_.vpn_preference);
|
||||||
|
|
||||||
ice_controller_->SetIceConfig(config_);
|
ice_adapter_->SetIceConfig(config_);
|
||||||
|
|
||||||
RTC_DCHECK(ValidateIceConfig(config_).ok());
|
RTC_DCHECK(ValidateIceConfig(config_).ok());
|
||||||
}
|
}
|
||||||
@ -988,7 +1002,7 @@ void P2PTransportChannel::OnPortReady(PortAllocatorSession* session,
|
|||||||
CreateConnection(port, *iter, iter->origin_port());
|
CreateConnection(port, *iter, iter->origin_port());
|
||||||
}
|
}
|
||||||
|
|
||||||
SortConnectionsAndUpdateState(
|
ice_adapter_->OnImmediateSortAndSwitchRequest(
|
||||||
IceSwitchReason::NEW_CONNECTION_FROM_LOCAL_CANDIDATE);
|
IceSwitchReason::NEW_CONNECTION_FROM_LOCAL_CANDIDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,7 +1182,7 @@ void P2PTransportChannel::OnUnknownAddress(PortInterface* port,
|
|||||||
// Update the list of connections since we just added another. We do this
|
// Update the list of connections since we just added another. We do this
|
||||||
// after sending the response since it could (in principle) delete the
|
// after sending the response since it could (in principle) delete the
|
||||||
// connection in question.
|
// connection in question.
|
||||||
SortConnectionsAndUpdateState(
|
ice_adapter_->OnImmediateSortAndSwitchRequest(
|
||||||
IceSwitchReason::NEW_CONNECTION_FROM_UNKNOWN_REMOTE_ADDRESS);
|
IceSwitchReason::NEW_CONNECTION_FROM_UNKNOWN_REMOTE_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1219,11 +1233,12 @@ void P2PTransportChannel::OnNominated(Connection* conn) {
|
|||||||
|
|
||||||
// TODO(qingsi): RequestSortAndStateUpdate will eventually call
|
// TODO(qingsi): RequestSortAndStateUpdate will eventually call
|
||||||
// MaybeSwitchSelectedConnection again. Rewrite this logic.
|
// MaybeSwitchSelectedConnection again. Rewrite this logic.
|
||||||
if (MaybeSwitchSelectedConnection(
|
if (ice_adapter_->OnImmediateSwitchRequest(
|
||||||
conn, IceSwitchReason::NOMINATION_ON_CONTROLLED_SIDE)) {
|
IceSwitchReason::NOMINATION_ON_CONTROLLED_SIDE, conn)) {
|
||||||
// Now that we have selected a connection, it is time to prune other
|
// Now that we have selected a connection, it is time to prune other
|
||||||
// connections and update the read/write state of the channel.
|
// connections and update the read/write state of the channel.
|
||||||
RequestSortAndStateUpdate(IceSwitchReason::NOMINATION_ON_CONTROLLED_SIDE);
|
ice_adapter_->OnSortAndSwitchRequest(
|
||||||
|
IceSwitchReason::NOMINATION_ON_CONTROLLED_SIDE);
|
||||||
} else {
|
} else {
|
||||||
RTC_LOG(LS_INFO)
|
RTC_LOG(LS_INFO)
|
||||||
<< "Not switching the selected connection on controlled side yet: "
|
<< "Not switching the selected connection on controlled side yet: "
|
||||||
@ -1371,7 +1386,7 @@ void P2PTransportChannel::FinishAddingRemoteCandidate(
|
|||||||
CreateConnections(new_remote_candidate, NULL);
|
CreateConnections(new_remote_candidate, NULL);
|
||||||
|
|
||||||
// Resort the connections list, which may have new elements.
|
// Resort the connections list, which may have new elements.
|
||||||
SortConnectionsAndUpdateState(
|
ice_adapter_->OnImmediateSortAndSwitchRequest(
|
||||||
IceSwitchReason::NEW_CONNECTION_FROM_REMOTE_CANDIDATE);
|
IceSwitchReason::NEW_CONNECTION_FROM_REMOTE_CANDIDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1691,9 +1706,7 @@ rtc::DiffServCodePoint P2PTransportChannel::DefaultDscpValue() const {
|
|||||||
|
|
||||||
rtc::ArrayView<Connection*> P2PTransportChannel::connections() const {
|
rtc::ArrayView<Connection*> P2PTransportChannel::connections() const {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
rtc::ArrayView<const Connection*> res = ice_controller_->connections();
|
return ice_adapter_->LegacyConnections();
|
||||||
return rtc::ArrayView<Connection*>(const_cast<Connection**>(res.data()),
|
|
||||||
res.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void P2PTransportChannel::RemoveConnectionForTest(Connection* connection) {
|
void P2PTransportChannel::RemoveConnectionForTest(Connection* connection) {
|
||||||
@ -1724,6 +1737,7 @@ void P2PTransportChannel::UpdateConnectionStates() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prepare for best candidate sorting.
|
// Prepare for best candidate sorting.
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
void P2PTransportChannel::RequestSortAndStateUpdate(
|
void P2PTransportChannel::RequestSortAndStateUpdate(
|
||||||
IceSwitchReason reason_to_sort) {
|
IceSwitchReason reason_to_sort) {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
@ -1736,13 +1750,14 @@ void P2PTransportChannel::RequestSortAndStateUpdate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
void P2PTransportChannel::MaybeStartPinging() {
|
void P2PTransportChannel::MaybeStartPinging() {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
if (started_pinging_) {
|
if (started_pinging_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ice_controller_->HasPingableConnection()) {
|
if (ice_adapter_->LegacyHasPingableConnection()) {
|
||||||
RTC_LOG(LS_INFO) << ToString()
|
RTC_LOG(LS_INFO) << ToString()
|
||||||
<< ": Have a pingable connection for the first time; "
|
<< ": Have a pingable connection for the first time; "
|
||||||
"starting to ping.";
|
"starting to ping.";
|
||||||
@ -1782,6 +1797,7 @@ bool P2PTransportChannel::PresumedWritable(const Connection* conn) const {
|
|||||||
|
|
||||||
// Sort the available connections to find the best one. We also monitor
|
// Sort the available connections to find the best one. We also monitor
|
||||||
// the number of available connections and the current state.
|
// the number of available connections and the current state.
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
void P2PTransportChannel::SortConnectionsAndUpdateState(
|
void P2PTransportChannel::SortConnectionsAndUpdateState(
|
||||||
IceSwitchReason reason_to_sort) {
|
IceSwitchReason reason_to_sort) {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
@ -1797,7 +1813,8 @@ void P2PTransportChannel::SortConnectionsAndUpdateState(
|
|||||||
// have to be writable to become the selected connection although it will
|
// have to be writable to become the selected connection although it will
|
||||||
// have higher priority if it is writable.
|
// have higher priority if it is writable.
|
||||||
MaybeSwitchSelectedConnection(
|
MaybeSwitchSelectedConnection(
|
||||||
reason_to_sort, ice_controller_->SortAndSwitchConnection(reason_to_sort));
|
reason_to_sort,
|
||||||
|
ice_adapter_->LegacySortAndSwitchConnection(reason_to_sort));
|
||||||
|
|
||||||
// The controlled side can prune only if the selected connection has been
|
// The controlled side can prune only if the selected connection has been
|
||||||
// nominated because otherwise it may prune the connection that will be
|
// nominated because otherwise it may prune the connection that will be
|
||||||
@ -1865,7 +1882,7 @@ bool P2PTransportChannel::AllowedToPruneConnections() const {
|
|||||||
void P2PTransportChannel::PruneConnections() {
|
void P2PTransportChannel::PruneConnections() {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
std::vector<const Connection*> connections_to_prune =
|
std::vector<const Connection*> connections_to_prune =
|
||||||
ice_controller_->PruneConnections();
|
ice_adapter_->LegacyPruneConnections();
|
||||||
PruneConnections(connections_to_prune);
|
PruneConnections(connections_to_prune);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1976,7 +1993,7 @@ void P2PTransportChannel::SwitchSelectedConnectionInternal(
|
|||||||
|
|
||||||
++selected_candidate_pair_changes_;
|
++selected_candidate_pair_changes_;
|
||||||
|
|
||||||
ice_controller_->SetSelectedConnection(selected_connection_);
|
ice_adapter_->OnConnectionSwitched(selected_connection_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t P2PTransportChannel::ComputeEstimatedDisconnectedTimeMs(
|
int64_t P2PTransportChannel::ComputeEstimatedDisconnectedTimeMs(
|
||||||
@ -1990,11 +2007,11 @@ int64_t P2PTransportChannel::ComputeEstimatedDisconnectedTimeMs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Warning: UpdateTransportState should eventually be called whenever a
|
// Warning: UpdateTransportState should eventually be called whenever a
|
||||||
// connection is added, deleted, or the write state of any connection changes
|
// connection is added, deleted, or the write state of any connection changes so
|
||||||
// so that the transport controller will get the up-to-date channel state.
|
// that the transport controller will get the up-to-date channel state. However
|
||||||
// However it should not be called too often; in the case that multiple
|
// it should not be called too often; in the case that multiple connection
|
||||||
// connection states change, it should be called after all the connection
|
// states change, it should be called after all the connection states have
|
||||||
// states have changed. For example, we call this at the end of
|
// changed. For example, we call this at the end of
|
||||||
// SortConnectionsAndUpdateState.
|
// SortConnectionsAndUpdateState.
|
||||||
void P2PTransportChannel::UpdateTransportState() {
|
void P2PTransportChannel::UpdateTransportState() {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
@ -2091,7 +2108,7 @@ void P2PTransportChannel::OnSelectedConnectionDestroyed() {
|
|||||||
RTC_LOG(LS_INFO) << "Selected connection destroyed. Will choose a new one.";
|
RTC_LOG(LS_INFO) << "Selected connection destroyed. Will choose a new one.";
|
||||||
IceSwitchReason reason = IceSwitchReason::SELECTED_CONNECTION_DESTROYED;
|
IceSwitchReason reason = IceSwitchReason::SELECTED_CONNECTION_DESTROYED;
|
||||||
SwitchSelectedConnectionInternal(nullptr, reason);
|
SwitchSelectedConnectionInternal(nullptr, reason);
|
||||||
RequestSortAndStateUpdate(reason);
|
ice_adapter_->OnSortAndSwitchRequest(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all connections timed out, delete them all.
|
// If all connections timed out, delete them all.
|
||||||
@ -2125,13 +2142,14 @@ bool P2PTransportChannel::ReadyToSend(const Connection* connection) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle queued up check-and-ping request
|
// Handle queued up check-and-ping request
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
void P2PTransportChannel::CheckAndPing() {
|
void P2PTransportChannel::CheckAndPing() {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
// Make sure the states of the connections are up-to-date (since this
|
// Make sure the states of the connections are up-to-date (since this
|
||||||
// affects which ones are pingable).
|
// affects which ones are pingable).
|
||||||
UpdateConnectionStates();
|
UpdateConnectionStates();
|
||||||
|
|
||||||
auto result = ice_controller_->SelectConnectionToPing(last_ping_sent_ms_);
|
auto result = ice_adapter_->LegacySelectConnectionToPing(last_ping_sent_ms_);
|
||||||
TimeDelta delay = TimeDelta::Millis(result.recheck_delay_ms);
|
TimeDelta delay = TimeDelta::Millis(result.recheck_delay_ms);
|
||||||
|
|
||||||
if (result.connection.value_or(nullptr)) {
|
if (result.connection.value_or(nullptr)) {
|
||||||
@ -2145,7 +2163,7 @@ void P2PTransportChannel::CheckAndPing() {
|
|||||||
// This method is only for unit testing.
|
// This method is only for unit testing.
|
||||||
Connection* P2PTransportChannel::FindNextPingableConnection() {
|
Connection* P2PTransportChannel::FindNextPingableConnection() {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
auto* conn = ice_controller_->FindNextPingableConnection();
|
const Connection* conn = ice_adapter_->FindNextPingableConnection();
|
||||||
if (conn) {
|
if (conn) {
|
||||||
return FromIceController(conn);
|
return FromIceController(conn);
|
||||||
} else {
|
} else {
|
||||||
@ -2174,7 +2192,7 @@ void P2PTransportChannel::SendPingRequestInternal(Connection* connection) {
|
|||||||
// active.
|
// active.
|
||||||
void P2PTransportChannel::MarkConnectionPinged(Connection* conn) {
|
void P2PTransportChannel::MarkConnectionPinged(Connection* conn) {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
ice_controller_->MarkConnectionPinged(conn);
|
ice_adapter_->OnConnectionPinged(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apart from sending ping from `conn` this method also updates
|
// Apart from sending ping from `conn` this method also updates
|
||||||
@ -2208,7 +2226,7 @@ uint32_t P2PTransportChannel::GetNominationAttr(Connection* conn) const {
|
|||||||
// Nominate a connection based on the NominationMode.
|
// Nominate a connection based on the NominationMode.
|
||||||
bool P2PTransportChannel::GetUseCandidateAttr(Connection* conn) const {
|
bool P2PTransportChannel::GetUseCandidateAttr(Connection* conn) const {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
return ice_controller_->GetUseCandidateAttr(
|
return ice_adapter_->GetUseCandidateAttribute(
|
||||||
conn, config_.default_nomination_mode, remote_ice_mode_);
|
conn, config_.default_nomination_mode, remote_ice_mode_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2233,7 +2251,7 @@ void P2PTransportChannel::OnConnectionStateChange(Connection* connection) {
|
|||||||
}
|
}
|
||||||
// We have to unroll the stack before doing this because we may be changing
|
// We have to unroll the stack before doing this because we may be changing
|
||||||
// the state of connections while sorting.
|
// the state of connections while sorting.
|
||||||
RequestSortAndStateUpdate(
|
ice_adapter_->OnSortAndSwitchRequest(
|
||||||
IceSwitchReason::CONNECT_STATE_CHANGE); // "candidate pair state
|
IceSwitchReason::CONNECT_STATE_CHANGE); // "candidate pair state
|
||||||
// changed");
|
// changed");
|
||||||
}
|
}
|
||||||
@ -2261,9 +2279,9 @@ void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) {
|
|||||||
if (selected_connection_ == connection) {
|
if (selected_connection_ == connection) {
|
||||||
OnSelectedConnectionDestroyed();
|
OnSelectedConnectionDestroyed();
|
||||||
} else {
|
} else {
|
||||||
// If a non-selected connection was destroyed, we don't need to re-sort
|
// If a non-selected connection was destroyed, we don't need to re-sort but
|
||||||
// but we do need to update state, because we could be switching to
|
// we do need to update state, because we could be switching to "failed" or
|
||||||
// "failed" or "completed".
|
// "completed".
|
||||||
UpdateTransportState();
|
UpdateTransportState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2273,7 +2291,7 @@ void P2PTransportChannel::RemoveConnection(const Connection* connection) {
|
|||||||
auto it = absl::c_find(connections_, connection);
|
auto it = absl::c_find(connections_, connection);
|
||||||
RTC_DCHECK(it != connections_.end());
|
RTC_DCHECK(it != connections_.end());
|
||||||
connections_.erase(it);
|
connections_.erase(it);
|
||||||
ice_controller_->OnConnectionDestroyed(connection);
|
ice_adapter_->OnConnectionDestroyed(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When a port is destroyed, remove it from our list of ports to use for
|
// When a port is destroyed, remove it from our list of ports to use for
|
||||||
@ -2374,7 +2392,8 @@ void P2PTransportChannel::OnReadPacket(Connection* connection,
|
|||||||
// May need to switch the sending connection based on the receiving media
|
// May need to switch the sending connection based on the receiving media
|
||||||
// path if this is the controlled side.
|
// path if this is the controlled side.
|
||||||
if (ice_role_ == ICEROLE_CONTROLLED) {
|
if (ice_role_ == ICEROLE_CONTROLLED) {
|
||||||
MaybeSwitchSelectedConnection(connection, IceSwitchReason::DATA_RECEIVED);
|
ice_adapter_->OnImmediateSwitchRequest(IceSwitchReason::DATA_RECEIVED,
|
||||||
|
connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2445,4 +2464,167 @@ void P2PTransportChannel::LogCandidatePairConfig(
|
|||||||
conn->ToLogDescription());
|
conn->ToLogDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
P2PTransportChannel::IceControllerAdapter::IceControllerAdapter(
|
||||||
|
const IceControllerFactoryArgs& args,
|
||||||
|
IceControllerFactoryInterface* ice_controller_factory,
|
||||||
|
ActiveIceControllerFactoryInterface* active_ice_controller_factory,
|
||||||
|
const webrtc::FieldTrialsView* field_trials,
|
||||||
|
P2PTransportChannel* transport)
|
||||||
|
: transport_(transport) {
|
||||||
|
if (UseActiveIceControllerFieldTrialEnabled(field_trials)) {
|
||||||
|
RTC_DCHECK(active_ice_controller_factory);
|
||||||
|
ActiveIceControllerFactoryArgs active_args{args,
|
||||||
|
/* ice_agent= */ transport};
|
||||||
|
active_ice_controller_ = active_ice_controller_factory->Create(active_args);
|
||||||
|
} else {
|
||||||
|
if (ice_controller_factory != nullptr) {
|
||||||
|
legacy_ice_controller_ = ice_controller_factory->Create(args);
|
||||||
|
} else {
|
||||||
|
legacy_ice_controller_ = std::make_unique<BasicIceController>(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
P2PTransportChannel::IceControllerAdapter::~IceControllerAdapter() = default;
|
||||||
|
|
||||||
|
void P2PTransportChannel::IceControllerAdapter::SetIceConfig(
|
||||||
|
const IceConfig& config) {
|
||||||
|
active_ice_controller_ ? active_ice_controller_->SetIceConfig(config)
|
||||||
|
: legacy_ice_controller_->SetIceConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void P2PTransportChannel::IceControllerAdapter::OnConnectionAdded(
|
||||||
|
const Connection* connection) {
|
||||||
|
active_ice_controller_ ? active_ice_controller_->OnConnectionAdded(connection)
|
||||||
|
: legacy_ice_controller_->AddConnection(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void P2PTransportChannel::IceControllerAdapter::OnConnectionSwitched(
|
||||||
|
const Connection* connection) {
|
||||||
|
active_ice_controller_
|
||||||
|
? active_ice_controller_->OnConnectionSwitched(connection)
|
||||||
|
: legacy_ice_controller_->SetSelectedConnection(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void P2PTransportChannel::IceControllerAdapter::OnConnectionPinged(
|
||||||
|
const Connection* connection) {
|
||||||
|
active_ice_controller_
|
||||||
|
? active_ice_controller_->OnConnectionPinged(connection)
|
||||||
|
: legacy_ice_controller_->MarkConnectionPinged(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void P2PTransportChannel::IceControllerAdapter::OnConnectionDestroyed(
|
||||||
|
const Connection* connection) {
|
||||||
|
active_ice_controller_
|
||||||
|
? active_ice_controller_->OnConnectionDestroyed(connection)
|
||||||
|
: legacy_ice_controller_->OnConnectionDestroyed(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void P2PTransportChannel::IceControllerAdapter::OnConnectionUpdated(
|
||||||
|
const Connection* connection) {
|
||||||
|
if (active_ice_controller_) {
|
||||||
|
active_ice_controller_->OnConnectionUpdated(connection);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RTC_DCHECK_NOTREACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void P2PTransportChannel::IceControllerAdapter::OnSortAndSwitchRequest(
|
||||||
|
IceSwitchReason reason) {
|
||||||
|
active_ice_controller_
|
||||||
|
? active_ice_controller_->OnSortAndSwitchRequest(reason)
|
||||||
|
: transport_->RequestSortAndStateUpdate(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void P2PTransportChannel::IceControllerAdapter::OnImmediateSortAndSwitchRequest(
|
||||||
|
IceSwitchReason reason) {
|
||||||
|
active_ice_controller_
|
||||||
|
? active_ice_controller_->OnImmediateSortAndSwitchRequest(reason)
|
||||||
|
: transport_->SortConnectionsAndUpdateState(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool P2PTransportChannel::IceControllerAdapter::OnImmediateSwitchRequest(
|
||||||
|
IceSwitchReason reason,
|
||||||
|
const Connection* connection) {
|
||||||
|
return active_ice_controller_
|
||||||
|
? active_ice_controller_->OnImmediateSwitchRequest(reason,
|
||||||
|
connection)
|
||||||
|
: transport_->MaybeSwitchSelectedConnection(connection, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool P2PTransportChannel::IceControllerAdapter::GetUseCandidateAttribute(
|
||||||
|
const cricket::Connection* connection,
|
||||||
|
cricket::NominationMode mode,
|
||||||
|
cricket::IceMode remote_ice_mode) const {
|
||||||
|
return active_ice_controller_
|
||||||
|
? active_ice_controller_->GetUseCandidateAttribute(
|
||||||
|
connection, mode, remote_ice_mode)
|
||||||
|
: legacy_ice_controller_->GetUseCandidateAttr(connection, mode,
|
||||||
|
remote_ice_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Connection*
|
||||||
|
P2PTransportChannel::IceControllerAdapter::FindNextPingableConnection() {
|
||||||
|
return active_ice_controller_
|
||||||
|
? active_ice_controller_->FindNextPingableConnection()
|
||||||
|
: legacy_ice_controller_->FindNextPingableConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc::ArrayView<Connection*>
|
||||||
|
P2PTransportChannel::IceControllerAdapter::LegacyConnections() const {
|
||||||
|
RTC_DCHECK_RUN_ON(transport_->network_thread_);
|
||||||
|
if (active_ice_controller_) {
|
||||||
|
return rtc::ArrayView<Connection*>(transport_->connections_.data(),
|
||||||
|
transport_->connections_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc::ArrayView<const Connection*> res = legacy_ice_controller_->connections();
|
||||||
|
return rtc::ArrayView<Connection*>(const_cast<Connection**>(res.data()),
|
||||||
|
res.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool P2PTransportChannel::IceControllerAdapter::LegacyHasPingableConnection()
|
||||||
|
const {
|
||||||
|
if (active_ice_controller_) {
|
||||||
|
RTC_DCHECK_NOTREACHED();
|
||||||
|
}
|
||||||
|
return legacy_ice_controller_->HasPingableConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
IceControllerInterface::PingResult
|
||||||
|
P2PTransportChannel::IceControllerAdapter::LegacySelectConnectionToPing(
|
||||||
|
int64_t last_ping_sent_ms) {
|
||||||
|
if (active_ice_controller_) {
|
||||||
|
RTC_DCHECK_NOTREACHED();
|
||||||
|
}
|
||||||
|
return legacy_ice_controller_->SelectConnectionToPing(last_ping_sent_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
IceControllerInterface::SwitchResult
|
||||||
|
P2PTransportChannel::IceControllerAdapter::LegacyShouldSwitchConnection(
|
||||||
|
IceSwitchReason reason,
|
||||||
|
const Connection* connection) {
|
||||||
|
if (active_ice_controller_) {
|
||||||
|
RTC_DCHECK_NOTREACHED();
|
||||||
|
}
|
||||||
|
return legacy_ice_controller_->ShouldSwitchConnection(reason, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
IceControllerInterface::SwitchResult
|
||||||
|
P2PTransportChannel::IceControllerAdapter::LegacySortAndSwitchConnection(
|
||||||
|
IceSwitchReason reason) {
|
||||||
|
if (active_ice_controller_) {
|
||||||
|
RTC_DCHECK_NOTREACHED();
|
||||||
|
}
|
||||||
|
return legacy_ice_controller_->SortAndSwitchConnection(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const Connection*>
|
||||||
|
P2PTransportChannel::IceControllerAdapter::LegacyPruneConnections() {
|
||||||
|
if (active_ice_controller_) {
|
||||||
|
RTC_DCHECK_NOTREACHED();
|
||||||
|
}
|
||||||
|
return legacy_ice_controller_->PruneConnections();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace cricket
|
} // namespace cricket
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "api/transport/stun.h"
|
#include "api/transport/stun.h"
|
||||||
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
|
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
|
||||||
#include "logging/rtc_event_log/ice_logger.h"
|
#include "logging/rtc_event_log/ice_logger.h"
|
||||||
|
#include "p2p/base/active_ice_controller_factory_interface.h"
|
||||||
#include "p2p/base/basic_async_resolver_factory.h"
|
#include "p2p/base/basic_async_resolver_factory.h"
|
||||||
#include "p2p/base/candidate_pair_interface.h"
|
#include "p2p/base/candidate_pair_interface.h"
|
||||||
#include "p2p/base/connection.h"
|
#include "p2p/base/connection.h"
|
||||||
@ -265,7 +266,9 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
|
|||||||
owned_dns_resolver_factory,
|
owned_dns_resolver_factory,
|
||||||
webrtc::RtcEventLog* event_log,
|
webrtc::RtcEventLog* event_log,
|
||||||
IceControllerFactoryInterface* ice_controller_factory,
|
IceControllerFactoryInterface* ice_controller_factory,
|
||||||
|
ActiveIceControllerFactoryInterface* active_ice_controller_factory,
|
||||||
const webrtc::FieldTrialsView* field_trials);
|
const webrtc::FieldTrialsView* field_trials);
|
||||||
|
|
||||||
bool IsGettingPorts() {
|
bool IsGettingPorts() {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
return allocator_session()->IsGettingPorts();
|
return allocator_session()->IsGettingPorts();
|
||||||
@ -274,12 +277,15 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
|
|||||||
// Returns true if it's possible to send packets on `connection`.
|
// Returns true if it's possible to send packets on `connection`.
|
||||||
bool ReadyToSend(const Connection* connection) const;
|
bool ReadyToSend(const Connection* connection) const;
|
||||||
bool PresumedWritable(const Connection* conn) const;
|
bool PresumedWritable(const Connection* conn) const;
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
void RequestSortAndStateUpdate(IceSwitchReason reason_to_sort);
|
void RequestSortAndStateUpdate(IceSwitchReason reason_to_sort);
|
||||||
// Start pinging if we haven't already started, and we now have a connection
|
// Start pinging if we haven't already started, and we now have a connection
|
||||||
// that's pingable.
|
// that's pingable.
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
void MaybeStartPinging();
|
void MaybeStartPinging();
|
||||||
void SendPingRequestInternal(Connection* connection);
|
void SendPingRequestInternal(Connection* connection);
|
||||||
|
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
void SortConnectionsAndUpdateState(IceSwitchReason reason_to_sort);
|
void SortConnectionsAndUpdateState(IceSwitchReason reason_to_sort);
|
||||||
rtc::NetworkRoute ConfigureNetworkRoute(const Connection* conn);
|
rtc::NetworkRoute ConfigureNetworkRoute(const Connection* conn);
|
||||||
void SwitchSelectedConnectionInternal(Connection* conn,
|
void SwitchSelectedConnectionInternal(Connection* conn,
|
||||||
@ -348,6 +354,7 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
|
|||||||
|
|
||||||
void OnNominated(Connection* conn);
|
void OnNominated(Connection* conn);
|
||||||
|
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
void CheckAndPing();
|
void CheckAndPing();
|
||||||
|
|
||||||
void LogCandidatePairConfig(Connection* conn,
|
void LogCandidatePairConfig(Connection* conn,
|
||||||
@ -357,12 +364,15 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
|
|||||||
bool GetUseCandidateAttr(Connection* conn) const;
|
bool GetUseCandidateAttr(Connection* conn) const;
|
||||||
|
|
||||||
// Returns true if the new_connection is selected for transmission.
|
// Returns true if the new_connection is selected for transmission.
|
||||||
bool MaybeSwitchSelectedConnection(Connection* new_connection,
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
|
bool MaybeSwitchSelectedConnection(const Connection* new_connection,
|
||||||
IceSwitchReason reason);
|
IceSwitchReason reason);
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
bool MaybeSwitchSelectedConnection(
|
bool MaybeSwitchSelectedConnection(
|
||||||
IceSwitchReason reason,
|
IceSwitchReason reason,
|
||||||
IceControllerInterface::SwitchResult result);
|
IceControllerInterface::SwitchResult result);
|
||||||
bool AllowedToPruneConnections() const;
|
bool AllowedToPruneConnections() const;
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
void PruneConnections();
|
void PruneConnections();
|
||||||
|
|
||||||
// Returns the latest remote ICE parameters or nullptr if there are no remote
|
// Returns the latest remote ICE parameters or nullptr if there are no remote
|
||||||
@ -420,6 +430,7 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
|
|||||||
|
|
||||||
void ParseFieldTrials(const webrtc::FieldTrialsView* field_trials);
|
void ParseFieldTrials(const webrtc::FieldTrialsView* field_trials);
|
||||||
|
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
webrtc::ScopedTaskSafety task_safety_;
|
webrtc::ScopedTaskSafety task_safety_;
|
||||||
std::string transport_name_ RTC_GUARDED_BY(network_thread_);
|
std::string transport_name_ RTC_GUARDED_BY(network_thread_);
|
||||||
int component_ RTC_GUARDED_BY(network_thread_);
|
int component_ RTC_GUARDED_BY(network_thread_);
|
||||||
@ -447,6 +458,7 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
|
|||||||
|
|
||||||
std::vector<RemoteCandidate> remote_candidates_
|
std::vector<RemoteCandidate> remote_candidates_
|
||||||
RTC_GUARDED_BY(network_thread_);
|
RTC_GUARDED_BY(network_thread_);
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
bool sort_dirty_ RTC_GUARDED_BY(
|
bool sort_dirty_ RTC_GUARDED_BY(
|
||||||
network_thread_); // indicates whether another sort is needed right now
|
network_thread_); // indicates whether another sort is needed right now
|
||||||
bool had_connection_ RTC_GUARDED_BY(network_thread_) =
|
bool had_connection_ RTC_GUARDED_BY(network_thread_) =
|
||||||
@ -473,6 +485,7 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
|
|||||||
IceConfig config_ RTC_GUARDED_BY(network_thread_);
|
IceConfig config_ RTC_GUARDED_BY(network_thread_);
|
||||||
int last_sent_packet_id_ RTC_GUARDED_BY(network_thread_) =
|
int last_sent_packet_id_ RTC_GUARDED_BY(network_thread_) =
|
||||||
-1; // -1 indicates no packet was sent before.
|
-1; // -1 indicates no packet was sent before.
|
||||||
|
// TODO(bugs.webrtc.org/14367) remove once refactor lands.
|
||||||
bool started_pinging_ RTC_GUARDED_BY(network_thread_) = false;
|
bool started_pinging_ RTC_GUARDED_BY(network_thread_) = false;
|
||||||
// The value put in the "nomination" attribute for the next nominated
|
// The value put in the "nomination" attribute for the next nominated
|
||||||
// connection. A zero-value indicates the connection will not be nominated.
|
// connection. A zero-value indicates the connection will not be nominated.
|
||||||
@ -486,7 +499,53 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
|
|||||||
RTC_GUARDED_BY(network_thread_);
|
RTC_GUARDED_BY(network_thread_);
|
||||||
webrtc::IceEventLog ice_event_log_ RTC_GUARDED_BY(network_thread_);
|
webrtc::IceEventLog ice_event_log_ RTC_GUARDED_BY(network_thread_);
|
||||||
|
|
||||||
std::unique_ptr<IceControllerInterface> ice_controller_
|
// The adapter transparently delegates ICE controller interactions to either
|
||||||
|
// the legacy or the active ICE controller depending on field trials.
|
||||||
|
// TODO(bugs.webrtc.org/14367) replace with active ICE controller eventually.
|
||||||
|
class IceControllerAdapter : public ActiveIceControllerInterface {
|
||||||
|
public:
|
||||||
|
IceControllerAdapter(
|
||||||
|
const IceControllerFactoryArgs& args,
|
||||||
|
IceControllerFactoryInterface* ice_controller_factory,
|
||||||
|
ActiveIceControllerFactoryInterface* active_ice_controller_factory,
|
||||||
|
const webrtc::FieldTrialsView* field_trials,
|
||||||
|
P2PTransportChannel* transport);
|
||||||
|
~IceControllerAdapter() override;
|
||||||
|
|
||||||
|
// ActiveIceControllerInterface overrides
|
||||||
|
void SetIceConfig(const IceConfig& config) override;
|
||||||
|
void OnConnectionAdded(const Connection* connection) override;
|
||||||
|
void OnConnectionSwitched(const Connection* connection) override;
|
||||||
|
void OnConnectionPinged(const Connection* connection) override;
|
||||||
|
void OnConnectionDestroyed(const Connection* connection) override;
|
||||||
|
void OnConnectionUpdated(const Connection* connection) override;
|
||||||
|
void OnSortAndSwitchRequest(IceSwitchReason reason) override;
|
||||||
|
void OnImmediateSortAndSwitchRequest(IceSwitchReason reason) override;
|
||||||
|
bool OnImmediateSwitchRequest(IceSwitchReason reason,
|
||||||
|
const Connection* connection) override;
|
||||||
|
bool GetUseCandidateAttribute(const Connection* connection,
|
||||||
|
NominationMode mode,
|
||||||
|
IceMode remote_ice_mode) const override;
|
||||||
|
const Connection* FindNextPingableConnection() override;
|
||||||
|
|
||||||
|
// Methods only available with legacy ICE controller.
|
||||||
|
rtc::ArrayView<Connection*> LegacyConnections() const;
|
||||||
|
bool LegacyHasPingableConnection() const;
|
||||||
|
IceControllerInterface::PingResult LegacySelectConnectionToPing(
|
||||||
|
int64_t last_ping_sent_ms);
|
||||||
|
IceControllerInterface::SwitchResult LegacyShouldSwitchConnection(
|
||||||
|
IceSwitchReason reason,
|
||||||
|
const Connection* connection);
|
||||||
|
IceControllerInterface::SwitchResult LegacySortAndSwitchConnection(
|
||||||
|
IceSwitchReason reason);
|
||||||
|
std::vector<const Connection*> LegacyPruneConnections();
|
||||||
|
|
||||||
|
private:
|
||||||
|
P2PTransportChannel* transport_;
|
||||||
|
std::unique_ptr<IceControllerInterface> legacy_ice_controller_;
|
||||||
|
std::unique_ptr<ActiveIceControllerInterface> active_ice_controller_;
|
||||||
|
};
|
||||||
|
std::unique_ptr<IceControllerAdapter> ice_adapter_
|
||||||
RTC_GUARDED_BY(network_thread_);
|
RTC_GUARDED_BY(network_thread_);
|
||||||
|
|
||||||
struct CandidateAndResolver final {
|
struct CandidateAndResolver final {
|
||||||
|
@ -16,11 +16,15 @@
|
|||||||
|
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "api/test/mock_async_dns_resolver.h"
|
#include "api/test/mock_async_dns_resolver.h"
|
||||||
|
#include "p2p/base/active_ice_controller_factory_interface.h"
|
||||||
|
#include "p2p/base/active_ice_controller_interface.h"
|
||||||
#include "p2p/base/basic_ice_controller.h"
|
#include "p2p/base/basic_ice_controller.h"
|
||||||
#include "p2p/base/connection.h"
|
#include "p2p/base/connection.h"
|
||||||
#include "p2p/base/fake_port_allocator.h"
|
#include "p2p/base/fake_port_allocator.h"
|
||||||
#include "p2p/base/ice_transport_internal.h"
|
#include "p2p/base/ice_transport_internal.h"
|
||||||
|
#include "p2p/base/mock_active_ice_controller.h"
|
||||||
#include "p2p/base/mock_async_resolver.h"
|
#include "p2p/base/mock_async_resolver.h"
|
||||||
|
#include "p2p/base/mock_ice_controller.h"
|
||||||
#include "p2p/base/packet_transport_internal.h"
|
#include "p2p/base/packet_transport_internal.h"
|
||||||
#include "p2p/base/test_stun_server.h"
|
#include "p2p/base/test_stun_server.h"
|
||||||
#include "p2p/base/test_turn_server.h"
|
#include "p2p/base/test_turn_server.h"
|
||||||
@ -56,7 +60,6 @@ using ::testing::DoAll;
|
|||||||
using ::testing::InSequence;
|
using ::testing::InSequence;
|
||||||
using ::testing::InvokeArgument;
|
using ::testing::InvokeArgument;
|
||||||
using ::testing::InvokeWithoutArgs;
|
using ::testing::InvokeWithoutArgs;
|
||||||
using ::testing::NiceMock;
|
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
using ::testing::ReturnRef;
|
using ::testing::ReturnRef;
|
||||||
using ::testing::SaveArg;
|
using ::testing::SaveArg;
|
||||||
@ -184,18 +187,6 @@ cricket::BasicPortAllocator* CreateBasicPortAllocator(
|
|||||||
return allocator.release();
|
return allocator.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockIceControllerFactory : public cricket::IceControllerFactoryInterface {
|
|
||||||
public:
|
|
||||||
~MockIceControllerFactory() override = default;
|
|
||||||
std::unique_ptr<cricket::IceControllerInterface> Create(
|
|
||||||
const cricket::IceControllerFactoryArgs& args) override {
|
|
||||||
RecordIceControllerCreated();
|
|
||||||
return std::make_unique<cricket::BasicIceController>(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
MOCK_METHOD(void, RecordIceControllerCreated, ());
|
|
||||||
};
|
|
||||||
|
|
||||||
// An one-shot resolver factory with default return arguments.
|
// An one-shot resolver factory with default return arguments.
|
||||||
// Resolution is immediate, always succeeds, and returns nonsense.
|
// Resolution is immediate, always succeeds, and returns nonsense.
|
||||||
class ResolverFactoryFixture : public webrtc::MockAsyncDnsResolverFactory {
|
class ResolverFactoryFixture : public webrtc::MockAsyncDnsResolverFactory {
|
||||||
@ -6123,6 +6114,25 @@ TEST(P2PTransportChannel, InjectIceController) {
|
|||||||
/* component= */ 77, std::move(init));
|
/* component= */ 77, std::move(init));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(P2PTransportChannel, InjectActiveIceController) {
|
||||||
|
std::unique_ptr<rtc::SocketServer> socket_server =
|
||||||
|
rtc::CreateDefaultSocketServer();
|
||||||
|
rtc::AutoSocketServerThread main_thread(socket_server.get());
|
||||||
|
rtc::BasicPacketSocketFactory packet_socket_factory(socket_server.get());
|
||||||
|
MockActiveIceControllerFactory factory;
|
||||||
|
FakePortAllocator pa(rtc::Thread::Current(), &packet_socket_factory);
|
||||||
|
webrtc::test::ScopedKeyValueConfig field_trials(
|
||||||
|
"WebRTC-UseActiveIceController/Enabled/");
|
||||||
|
EXPECT_CALL(factory, RecordActiveIceControllerCreated()).Times(1);
|
||||||
|
webrtc::IceTransportInit init;
|
||||||
|
init.set_port_allocator(&pa);
|
||||||
|
init.set_active_ice_controller_factory(&factory);
|
||||||
|
init.set_field_trials(&field_trials);
|
||||||
|
auto dummy =
|
||||||
|
P2PTransportChannel::Create("transport_name",
|
||||||
|
/* component= */ 77, std::move(init));
|
||||||
|
}
|
||||||
|
|
||||||
class ForgetLearnedStateController : public cricket::BasicIceController {
|
class ForgetLearnedStateController : public cricket::BasicIceController {
|
||||||
public:
|
public:
|
||||||
explicit ForgetLearnedStateController(
|
explicit ForgetLearnedStateController(
|
||||||
|
Reference in New Issue
Block a user