mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Improve usabilty of ServiceAddress.
PiperOrigin-RevId: 842439675
This commit is contained in:
committed by
Copybara-Service
parent
4652aef48c
commit
63f943aaed
@@ -427,6 +427,7 @@ let package = Package(
|
||||
"internal/platform/borrowable_test.cc",
|
||||
"internal/platform/implementation/windows/http_loader_test.cc",
|
||||
"internal/platform/blocking_queue_stream_test.cc",
|
||||
"internal/platform/service_address_test.cc",
|
||||
"internal/network/utils_test.cc",
|
||||
"internal/network/url_test.cc",
|
||||
"internal/network/http_response_test.cc",
|
||||
|
||||
@@ -42,6 +42,7 @@ cc_library(
|
||||
"base64_utils.cc",
|
||||
"input_stream.cc",
|
||||
"prng.cc",
|
||||
"service_address.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"base64_utils.h",
|
||||
@@ -59,6 +60,7 @@ cc_library(
|
||||
"payload_id.h",
|
||||
"prng.h",
|
||||
"runnable.h",
|
||||
"service_address.h",
|
||||
"socket.h",
|
||||
"types.h",
|
||||
"wifi_credential.h",
|
||||
@@ -70,6 +72,7 @@ cc_library(
|
||||
"//connections:partners",
|
||||
],
|
||||
deps = [
|
||||
"//connections/implementation/proto:offline_wire_formats_cc_proto",
|
||||
"//internal/platform/implementation:wifi_utils",
|
||||
"//proto:connections_enums_cc_proto",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
@@ -80,6 +83,7 @@ cc_library(
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
],
|
||||
@@ -606,3 +610,14 @@ cc_test(
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "service_address_test",
|
||||
srcs = ["service_address_test.cc"],
|
||||
deps = [
|
||||
":base",
|
||||
"//connections/implementation/proto:offline_wire_formats_cc_proto",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -354,6 +354,7 @@ cc_library(
|
||||
"//:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:logging",
|
||||
"@com_google_absl//absl/types:span",
|
||||
],
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "absl/types/span.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/service_address.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
|
||||
@@ -149,6 +150,11 @@ bool SocketAddress::FromBytes(SocketAddress& address,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketAddress::FromServiceAddress(SocketAddress& address,
|
||||
const ServiceAddress& service_address) {
|
||||
return FromBytes(address, service_address.address, service_address.port);
|
||||
}
|
||||
|
||||
int SocketAddress::port() const {
|
||||
DCHECK(address_.ss_family == AF_INET || address_.ss_family == AF_INET6);
|
||||
if (address_.ss_family == AF_INET) {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/span.h"
|
||||
#include "internal/platform/service_address.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
|
||||
@@ -63,6 +64,9 @@ class SocketAddress {
|
||||
static bool FromBytes(SocketAddress& address,
|
||||
absl::Span<const char> address_bytes, int port = 0);
|
||||
|
||||
static bool FromServiceAddress(SocketAddress& address,
|
||||
const ServiceAddress& service_address);
|
||||
|
||||
// Returns true if dual stack support has been enabled.
|
||||
bool dual_stack() const { return dual_stack_; }
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "internal/platform/implementation/windows/socket_address.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "internal/platform/service_address.h"
|
||||
|
||||
namespace nearby::windows {
|
||||
namespace {
|
||||
@@ -201,5 +202,58 @@ TEST(SocketAddressTest, IPv6LinkLocalFail) {
|
||||
EXPECT_FALSE(address.IsV6LinkLocal());
|
||||
}
|
||||
|
||||
TEST(SocketAddressTest, FromServiceAddressIPv4) {
|
||||
SocketAddress address;
|
||||
ServiceAddress service_address = {
|
||||
.address = {192, 168, 1, 1},
|
||||
.port = 8080,
|
||||
};
|
||||
EXPECT_TRUE(SocketAddress::FromServiceAddress(address, service_address));
|
||||
EXPECT_EQ(address.ToString(), "192.168.1.1:8080");
|
||||
EXPECT_EQ(address.port(), 8080);
|
||||
}
|
||||
|
||||
TEST(SocketAddressTest, FromServiceAddressIPv4DualStack) {
|
||||
SocketAddress address(/*dual_stack=*/true);
|
||||
ServiceAddress service_address = {
|
||||
.address = {192, 168, 1, 1},
|
||||
.port = 8080,
|
||||
};
|
||||
EXPECT_TRUE(SocketAddress::FromServiceAddress(address, service_address));
|
||||
EXPECT_EQ(address.ToString(), "[::ffff:192.168.1.1]:8080");
|
||||
EXPECT_EQ(address.port(), 8080);
|
||||
}
|
||||
|
||||
TEST(SocketAddressTest, FromServiceAddressIPv6) {
|
||||
SocketAddress address(/*dual_stack=*/true);
|
||||
ServiceAddress service_address = {
|
||||
.address = {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x4d, 0xb2, 0xb3, 0x5c, 0x22,
|
||||
0x03, 0x98, 0xa1},
|
||||
.port = 8080,
|
||||
};
|
||||
EXPECT_TRUE(SocketAddress::FromServiceAddress(address, service_address));
|
||||
EXPECT_EQ(address.ToString(), "[fe80::4db2:b35c:2203:98a1]:8080");
|
||||
EXPECT_EQ(address.port(), 8080);
|
||||
}
|
||||
|
||||
TEST(SocketAddressTest, FromServiceAddressIPv6NoDualStack) {
|
||||
SocketAddress address;
|
||||
ServiceAddress service_address = {
|
||||
.address = {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x4d, 0xb2, 0xb3, 0x5c, 0x22,
|
||||
0x03, 0x98, 0xa1},
|
||||
.port = 8080,
|
||||
};
|
||||
EXPECT_FALSE(SocketAddress::FromServiceAddress(address, service_address));
|
||||
}
|
||||
|
||||
TEST(SocketAddressTest, FromServiceAddressInvalidAddress) {
|
||||
SocketAddress address;
|
||||
ServiceAddress service_address = {
|
||||
.address = {192, 168, 1},
|
||||
.port = 8080,
|
||||
};
|
||||
EXPECT_FALSE(SocketAddress::FromServiceAddress(address, service_address));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby::windows
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/service_address.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
void ServiceAddressToProto(
|
||||
const ServiceAddress& service_address,
|
||||
location::nearby::connections::ServiceAddress& proto) {
|
||||
proto.set_ip_address(std::string(service_address.address.begin(),
|
||||
service_address.address.end()));
|
||||
proto.set_port(service_address.port);
|
||||
}
|
||||
|
||||
bool ServiceAddressFromProto(
|
||||
const location::nearby::connections::ServiceAddress& proto,
|
||||
ServiceAddress& service_address) {
|
||||
// Address must be either 4 or 16 bytes and port must be set.
|
||||
if ((proto.ip_address().size() != 16 && proto.ip_address().size() != 4) ||
|
||||
proto.port() == 0) {
|
||||
return false;
|
||||
}
|
||||
service_address.address = {proto.ip_address().begin(),
|
||||
proto.ip_address().end()};
|
||||
service_address.port = proto.port();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_SERVICE_ADDRESS_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_SERVICE_ADDRESS_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
||||
#include "internal/platform/implementation/wifi_utils.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
struct ServiceAddress {
|
||||
// IP address in MSB-first order.
|
||||
// IPv4 address is 4 bytes, and IPv6 address is 16 bytes.
|
||||
std::vector<char> address;
|
||||
uint16_t port;
|
||||
|
||||
bool operator==(const ServiceAddress& other) const = default;
|
||||
};
|
||||
|
||||
// Support logging of ServiceAddress.
|
||||
template <typename Sink>
|
||||
void AbslStringify(Sink& sink, const ServiceAddress& service_address) {
|
||||
absl::Format(
|
||||
&sink, "[%s]:%d",
|
||||
WifiUtils::GetHumanReadableIpAddress(std::string(
|
||||
service_address.address.begin(), service_address.address.end())),
|
||||
service_address.port);
|
||||
}
|
||||
|
||||
void ServiceAddressToProto(
|
||||
const ServiceAddress& service_address,
|
||||
location::nearby::connections::ServiceAddress& proto);
|
||||
|
||||
// Returns false is proto address does not contain an IPv4 or IPv6 address, or
|
||||
// if the proto port is 0.
|
||||
bool ServiceAddressFromProto(
|
||||
const location::nearby::connections::ServiceAddress& proto,
|
||||
ServiceAddress& service_address);
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_SERVICE_ADDRESS_H_
|
||||
@@ -0,0 +1,122 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/service_address.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
|
||||
using ProtoServiceAddress = ::location::nearby::connections::ServiceAddress;
|
||||
|
||||
TEST(ServiceAddressTest, IPv4ServiceAddressToProto) {
|
||||
ServiceAddress service_address = {
|
||||
.address = {127, 0, 0, 1},
|
||||
.port = 8080,
|
||||
};
|
||||
ProtoServiceAddress proto;
|
||||
ServiceAddressToProto(service_address, proto);
|
||||
EXPECT_EQ(proto.ip_address(), std::string("\x7f\0\0\1", 4));
|
||||
EXPECT_EQ(proto.port(), 8080);
|
||||
}
|
||||
|
||||
TEST(ServiceAddressTest, IPv4ServiceAddressFromProto) {
|
||||
ProtoServiceAddress proto;
|
||||
proto.set_ip_address(std::string("\x7f\0\0\1", 4));
|
||||
proto.set_port(8080);
|
||||
ServiceAddress service_address;
|
||||
EXPECT_TRUE(ServiceAddressFromProto(proto, service_address));
|
||||
EXPECT_EQ(service_address.address, std::vector<char>({127, 0, 0, 1}));
|
||||
EXPECT_EQ(service_address.port, 8080);
|
||||
}
|
||||
|
||||
TEST(ServiceAddressTest, IPv6ServiceAddressToProto) {
|
||||
ServiceAddress service_address = {
|
||||
.address = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||
.port = 8080,
|
||||
};
|
||||
ProtoServiceAddress proto;
|
||||
ServiceAddressToProto(service_address, proto);
|
||||
EXPECT_EQ(proto.ip_address(),
|
||||
std::string("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1", 16));
|
||||
EXPECT_EQ(proto.port(), 8080);
|
||||
}
|
||||
|
||||
TEST(ServiceAddressTest, IPv6ServiceAddressFromProto) {
|
||||
ProtoServiceAddress proto;
|
||||
proto.set_ip_address(std::string("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1", 16));
|
||||
proto.set_port(8080);
|
||||
ServiceAddress service_address;
|
||||
EXPECT_TRUE(ServiceAddressFromProto(proto, service_address));
|
||||
EXPECT_EQ(
|
||||
service_address.address,
|
||||
std::vector<char>({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}));
|
||||
EXPECT_EQ(service_address.port, 8080);
|
||||
}
|
||||
|
||||
TEST(ServiceAddressTest, ServiceAddressFromProtoInvalidAddress) {
|
||||
ProtoServiceAddress proto;
|
||||
proto.set_ip_address(std::string("\x7f\0\0", 3));
|
||||
proto.set_port(8080);
|
||||
ServiceAddress service_address;
|
||||
EXPECT_FALSE(ServiceAddressFromProto(proto, service_address));
|
||||
}
|
||||
|
||||
TEST(ServiceAddressTest, ServiceAddressFromProtoInvalidPort) {
|
||||
ProtoServiceAddress proto;
|
||||
proto.set_ip_address(std::string("\x7f\0\0\1", 4));
|
||||
proto.set_port(0);
|
||||
ServiceAddress service_address;
|
||||
EXPECT_FALSE(ServiceAddressFromProto(proto, service_address));
|
||||
}
|
||||
|
||||
TEST(ServiceAddressTest, ServiceAddressEquality) {
|
||||
ServiceAddress service_address1 = {
|
||||
.address = {127, 0, 0, 1},
|
||||
.port = 8080,
|
||||
};
|
||||
ServiceAddress service_address2 = {
|
||||
.address = {127, 0, 0, 1},
|
||||
.port = 8080,
|
||||
};
|
||||
ServiceAddress service_address3 = {
|
||||
.address = {127, 0, 0, 2},
|
||||
.port = 8080,
|
||||
};
|
||||
ServiceAddress service_address4 = {
|
||||
.address = {127, 0, 0, 1},
|
||||
.port = 8081,
|
||||
};
|
||||
ServiceAddress service_address5 = {
|
||||
.address = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||
.port = 8080,
|
||||
};
|
||||
ServiceAddress service_address6 = {
|
||||
.address = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||
.port = 8080,
|
||||
};
|
||||
EXPECT_EQ(service_address1, service_address2);
|
||||
EXPECT_NE(service_address1, service_address3);
|
||||
EXPECT_NE(service_address1, service_address4);
|
||||
EXPECT_NE(service_address1, service_address5);
|
||||
EXPECT_EQ(service_address5, service_address6);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby
|
||||
@@ -15,22 +15,15 @@
|
||||
#ifndef PLATFORM_BASE_WIFI_CREDENTIAL_H_
|
||||
#define PLATFORM_BASE_WIFI_CREDENTIAL_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "internal/platform/service_address.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
struct ServiceAddress {
|
||||
// IP address in MSB-first order.
|
||||
// IPv4 address is 4 bytes, and IPv6 address is 16 bytes.
|
||||
std::vector<char> address;
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
// Credentials for the currently-hosted Wifi hotspot (if any)
|
||||
// Class HotspotCredentials is copyable & movable
|
||||
class HotspotCredentials {
|
||||
|
||||
Reference in New Issue
Block a user