mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Add additional state management while in the PCP flow
PiperOrigin-RevId: 945918080
This commit is contained in:
committed by
Copybara-Service
parent
44f37719e5
commit
df8291fc69
@@ -28,11 +28,13 @@
|
|||||||
#include "connections/implementation/client_proxy.h"
|
#include "connections/implementation/client_proxy.h"
|
||||||
#include "connections/implementation/endpoint_channel.h"
|
#include "connections/implementation/endpoint_channel.h"
|
||||||
#include "connections/implementation/endpoint_channel_manager.h"
|
#include "connections/implementation/endpoint_channel_manager.h"
|
||||||
|
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||||
#include "connections/implementation/offline_frames.h"
|
#include "connections/implementation/offline_frames.h"
|
||||||
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
||||||
#include "connections/implementation/service_id_constants.h"
|
#include "connections/implementation/service_id_constants.h"
|
||||||
#include "connections/listeners.h"
|
#include "connections/listeners.h"
|
||||||
#include "connections/medium_selector.h"
|
#include "connections/medium_selector.h"
|
||||||
|
#include "internal/flags/nearby_flags.h"
|
||||||
#include "internal/platform/byte_array.h"
|
#include "internal/platform/byte_array.h"
|
||||||
#include "internal/platform/count_down_latch.h"
|
#include "internal/platform/count_down_latch.h"
|
||||||
#include "internal/platform/exception.h"
|
#include "internal/platform/exception.h"
|
||||||
@@ -64,6 +66,15 @@ constexpr absl::Time kInvalidTimestamp = absl::InfinitePast();
|
|||||||
// The maximum time we will wait for the encryption setup during negotiating a
|
// The maximum time we will wait for the encryption setup during negotiating a
|
||||||
// connection.
|
// connection.
|
||||||
constexpr absl::Duration kDecryptRetryTimeout = absl::Seconds(3);
|
constexpr absl::Duration kDecryptRetryTimeout = absl::Seconds(3);
|
||||||
|
|
||||||
|
// Returns true if the given `frame_type` is allowed before the connection to
|
||||||
|
// the endpoint is confirmed (i.e., KEEP_ALIVE, CONNECTION_RESPONSE, and
|
||||||
|
// DISCONNECTION frames).
|
||||||
|
bool IsAllowedPreConfirmationFrameType(V1Frame::FrameType frame_type) {
|
||||||
|
return frame_type == V1Frame::KEEP_ALIVE ||
|
||||||
|
frame_type == V1Frame::CONNECTION_RESPONSE ||
|
||||||
|
frame_type == V1Frame::DISCONNECTION;
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class EndpointManager::LockedFrameProcessor {
|
class EndpointManager::LockedFrameProcessor {
|
||||||
@@ -275,6 +286,17 @@ ExceptionOr<bool> EndpointManager::HandleData(
|
|||||||
|
|
||||||
// Route the incoming offlineFrame to its registered processor.
|
// Route the incoming offlineFrame to its registered processor.
|
||||||
V1Frame::FrameType frame_type = parser::GetFrameType(frame);
|
V1Frame::FrameType frame_type = parser::GetFrameType(frame);
|
||||||
|
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||||
|
config_package_nearby::nearby_connections_feature::
|
||||||
|
kFilterUnconfirmedEndpointFrames) &&
|
||||||
|
client->HasPendingConnectionToEndpoint(endpoint_id) &&
|
||||||
|
!IsAllowedPreConfirmationFrameType(frame_type)) {
|
||||||
|
LOG(WARNING) << "EndpointManager discarded unauthorized frame ("
|
||||||
|
<< V1Frame::FrameType_Name(frame_type)
|
||||||
|
<< ") from unconfirmed endpoint " << endpoint_id << ".";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
LockedFrameProcessor frame_processor = GetFrameProcessor(frame_type);
|
LockedFrameProcessor frame_processor = GetFrameProcessor(frame_type);
|
||||||
if (!frame_processor) {
|
if (!frame_processor) {
|
||||||
// report messages without handlers, except KEEP_ALIVE, which has
|
// report messages without handlers, except KEEP_ALIVE, which has
|
||||||
|
|||||||
@@ -94,6 +94,10 @@ class SetSafeToDisconnect {
|
|||||||
config_package_nearby::nearby_connections_feature::
|
config_package_nearby::nearby_connections_feature::
|
||||||
kSafeToDisconnectVersion,
|
kSafeToDisconnectVersion,
|
||||||
safe_to_disconnect_version);
|
safe_to_disconnect_version);
|
||||||
|
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||||
|
config_package_nearby::nearby_connections_feature::
|
||||||
|
kFilterUnconfirmedEndpointFrames,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -108,11 +112,11 @@ class EndpointManagerTest : public ::testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
void RegisterEndpoint(std::unique_ptr<MockEndpointChannel> channel,
|
void RegisterEndpoint(std::unique_ptr<MockEndpointChannel> channel,
|
||||||
bool should_close = true) {
|
bool should_close = true) {
|
||||||
CountDownLatch done(1);
|
auto done = std::make_shared<CountDownLatch>(1);
|
||||||
if (should_close) {
|
if (should_close) {
|
||||||
ON_CALL(*channel, Close(_))
|
ON_CALL(*channel, Close(_))
|
||||||
.WillByDefault(
|
.WillByDefault(
|
||||||
[&done](DisconnectionReason reason) { done.CountDown(); });
|
[done](DisconnectionReason reason) { done->CountDown(); });
|
||||||
}
|
}
|
||||||
EXPECT_CALL(*channel, GetMedium()).WillRepeatedly(Return(Medium::BLE));
|
EXPECT_CALL(*channel, GetMedium()).WillRepeatedly(Return(Medium::BLE));
|
||||||
EXPECT_CALL(*channel, GetLastReadTimestamp())
|
EXPECT_CALL(*channel, GetLastReadTimestamp())
|
||||||
@@ -124,7 +128,7 @@ class EndpointManagerTest : public ::testing::Test {
|
|||||||
connection_options_, std::move(channel), listener_,
|
connection_options_, std::move(channel), listener_,
|
||||||
connection_token_);
|
connection_token_);
|
||||||
if (should_close) {
|
if (should_close) {
|
||||||
EXPECT_TRUE(done.Await(absl::Milliseconds(1000)).result());
|
EXPECT_TRUE(done->Await(absl::Milliseconds(1000)).result());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetSafeToDisconnect set_safe_to_disconnect_{true, true, 5};
|
SetSafeToDisconnect set_safe_to_disconnect_{true, true, 5};
|
||||||
@@ -429,6 +433,70 @@ TEST_F(EndpointManagerTest, TryDecrypt) {
|
|||||||
RegisterEndpoint(std::move(endpoint_channel));
|
RegisterEndpoint(std::move(endpoint_channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(EndpointManagerTest,
|
||||||
|
FilterUnconfirmedFrames_DiscardsPayloadBeforeConfirmation) {
|
||||||
|
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||||
|
config_package_nearby::nearby_connections_feature::
|
||||||
|
kFilterUnconfirmedEndpointFrames,
|
||||||
|
true);
|
||||||
|
PayloadTransferFrame::PayloadHeader header;
|
||||||
|
header.set_id(12345);
|
||||||
|
header.set_type(PayloadTransferFrame::PayloadHeader::BYTES);
|
||||||
|
header.set_total_size(1024);
|
||||||
|
PayloadTransferFrame::PayloadChunk chunk;
|
||||||
|
chunk.set_body("payload data");
|
||||||
|
chunk.set_offset(150);
|
||||||
|
chunk.set_flags(1);
|
||||||
|
std::string payload_bytes = parser::ForDataPayloadTransfer(header, chunk);
|
||||||
|
auto endpoint_channel = std::make_unique<MockEndpointChannel>();
|
||||||
|
auto payload_processor = std::make_unique<MockFrameProcessor>();
|
||||||
|
EXPECT_CALL(*payload_processor, OnIncomingFrame).Times(0);
|
||||||
|
EXPECT_CALL(*payload_processor, OnEndpointDisconnect);
|
||||||
|
EXPECT_CALL(*endpoint_channel, Read())
|
||||||
|
.WillOnce(Return(ExceptionOr<ByteArray>(ByteArray(payload_bytes))))
|
||||||
|
.WillRepeatedly(Return(ExceptionOr<ByteArray>(Exception::kIo)));
|
||||||
|
EXPECT_CALL(*endpoint_channel, Write(_))
|
||||||
|
.WillRepeatedly(Return(Exception{Exception::kSuccess}));
|
||||||
|
em_.RegisterFrameProcessor(V1Frame::PAYLOAD_TRANSFER,
|
||||||
|
payload_processor.get());
|
||||||
|
processors_.emplace_back(std::move(payload_processor));
|
||||||
|
RegisterEndpoint(std::move(endpoint_channel));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(EndpointManagerTest,
|
||||||
|
FilterUnconfirmedFrames_AllowsPayloadAfterConfirmation) {
|
||||||
|
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||||
|
config_package_nearby::nearby_connections_feature::
|
||||||
|
kFilterUnconfirmedEndpointFrames,
|
||||||
|
true);
|
||||||
|
PayloadTransferFrame::PayloadHeader header;
|
||||||
|
header.set_id(12345);
|
||||||
|
header.set_type(PayloadTransferFrame::PayloadHeader::BYTES);
|
||||||
|
header.set_total_size(1024);
|
||||||
|
PayloadTransferFrame::PayloadChunk chunk;
|
||||||
|
chunk.set_body("payload data");
|
||||||
|
chunk.set_offset(150);
|
||||||
|
chunk.set_flags(1);
|
||||||
|
std::string payload_bytes = parser::ForDataPayloadTransfer(header, chunk);
|
||||||
|
auto endpoint_channel = std::make_unique<MockEndpointChannel>();
|
||||||
|
auto payload_processor = std::make_unique<MockFrameProcessor>();
|
||||||
|
EXPECT_CALL(mock_listener_.accepted_cb, Call).Times(1);
|
||||||
|
EXPECT_CALL(*payload_processor, OnIncomingFrame).Times(1);
|
||||||
|
EXPECT_CALL(*payload_processor, OnEndpointDisconnect);
|
||||||
|
EXPECT_CALL(*endpoint_channel, Read())
|
||||||
|
.WillOnce([this, payload_bytes]() {
|
||||||
|
client_->OnConnectionAccepted(endpoint_id_);
|
||||||
|
return ExceptionOr<ByteArray>(ByteArray(payload_bytes));
|
||||||
|
})
|
||||||
|
.WillRepeatedly(Return(ExceptionOr<ByteArray>(Exception::kIo)));
|
||||||
|
EXPECT_CALL(*endpoint_channel, Write(_))
|
||||||
|
.WillRepeatedly(Return(Exception{Exception::kSuccess}));
|
||||||
|
em_.RegisterFrameProcessor(V1Frame::PAYLOAD_TRANSFER,
|
||||||
|
payload_processor.get());
|
||||||
|
processors_.emplace_back(std::move(payload_processor));
|
||||||
|
RegisterEndpoint(std::move(endpoint_channel));
|
||||||
|
}
|
||||||
|
|
||||||
// Regression test for b/278729669.
|
// Regression test for b/278729669.
|
||||||
//
|
//
|
||||||
// During the destruction of NearbyConnections, Core (which owns ClientProxy)
|
// During the destruction of NearbyConnections, Core (which owns ClientProxy)
|
||||||
|
|||||||
@@ -80,6 +80,11 @@ constexpr auto kEnableWifiDirect =
|
|||||||
// by default, enable Wi-Fi Hotspot client.
|
// by default, enable Wi-Fi Hotspot client.
|
||||||
constexpr auto kEnableWifiHotspotClient =
|
constexpr auto kEnableWifiHotspotClient =
|
||||||
flags::Flag<bool>(kConfigPackage, "45648734", true);
|
flags::Flag<bool>(kConfigPackage, "45648734", true);
|
||||||
|
// Enforces frame filtering on unconfirmed endpoints in EndpointManager and
|
||||||
|
// BaseEndpointChannel so application payloads and upgrade requests are blocked
|
||||||
|
// before connection acceptance.
|
||||||
|
constexpr auto kFilterUnconfirmedEndpointFrames =
|
||||||
|
flags::Flag<bool>(kConfigPackage, "45813128", true);
|
||||||
// When true, fix the BleServerSocket deadlock/use-after-free (b/494335036).
|
// When true, fix the BleServerSocket deadlock/use-after-free (b/494335036).
|
||||||
constexpr auto kFixBleServerSocketDeadlock =
|
constexpr auto kFixBleServerSocketDeadlock =
|
||||||
flags::Flag<bool>(kConfigPackage, "45782647", true);
|
flags::Flag<bool>(kConfigPackage, "45782647", true);
|
||||||
|
|||||||
Reference in New Issue
Block a user