From 2fc61869f9f4f505b9e2eff840bf5764a2f76016 Mon Sep 17 00:00:00 2001 From: edwinwu Date: Wed, 15 Dec 2021 16:08:07 -0800 Subject: [PATCH] Add GetDynamicPortRange api for Wifilan medium PiperOrigin-RevId: 416669312 --- cpp/core/internal/mediums/wifi_lan.cc | 24 +++++++++++++++++-- cpp/core/internal/mediums/wifi_lan.h | 4 ++++ cpp/platform/api/wifi_lan.h | 4 ++++ cpp/platform/impl/g3/wifi_lan.h | 6 +++++ .../impl/ios/Source/Platform/wifi_lan.h | 4 ++++ cpp/platform/impl/windows/wifi_lan.h | 6 +++++ cpp/platform/public/wifi_lan.h | 5 ++++ 7 files changed, 51 insertions(+), 2 deletions(-) diff --git a/cpp/core/internal/mediums/wifi_lan.cc b/cpp/core/internal/mediums/wifi_lan.cc index 9e24c5fe..037da7d8 100644 --- a/cpp/core/internal/mediums/wifi_lan.cc +++ b/cpp/core/internal/mediums/wifi_lan.cc @@ -227,9 +227,16 @@ bool WifiLan::StartAcceptingConnections(const std::string& service_id, return false; } - // We can generate an exact port here on server socket; now we just assign 0 - // to let platform medium decide it. + auto port_range = medium_.GetDynamicPortRange(); + // Generate an exact port here on server socket; if platform doesn't provide + // range of port then assign 0 to let platform decide it. int port = 0; + if (port_range.has_value() && + (port_range->first > 0 && port_range->first <= 65535 && + port_range->second > 0 && port_range->second <= 65535 && + port_range->first <= port_range->second)) { + port = GeneratePort(service_id, port_range.value()); + } WifiLanServerSocket server_socket = medium_.ListenForService(port); if (!server_socket.IsValid()) { NEARBY_LOGS(INFO) @@ -404,6 +411,19 @@ std::string WifiLan::GenerateServiceType(const std::string& service_id) { service_id_hash_string); } +int WifiLan::GeneratePort(const std::string& service_id, + std::pair port_range) { + const std::string service_id_hash = + std::string(Utils::Sha256Hash(service_id, 4)); + + std::uint32_t uint_of_service_id_hash = + service_id_hash[0] << 24 | service_id_hash[1] << 16 | + service_id_hash[2] << 8 | service_id_hash[3]; + + return port_range.first + + (uint_of_service_id_hash % (port_range.second - port_range.first)); +} + } // namespace connections } // namespace nearby } // namespace location diff --git a/cpp/core/internal/mediums/wifi_lan.h b/cpp/core/internal/mediums/wifi_lan.h index dc5300f7..35fe76e5 100644 --- a/cpp/core/internal/mediums/wifi_lan.h +++ b/cpp/core/internal/mediums/wifi_lan.h @@ -170,6 +170,10 @@ class WifiLan { // Generates mDNS type. std::string GenerateServiceType(const std::string& service_id); + // Generates port number based on port_range_. + int GeneratePort(const std::string& service_id, + std::pair port_range); + mutable Mutex mutex_; WifiLanMedium medium_ ABSL_GUARDED_BY(mutex_); AdvertisingInfo advertising_info_ ABSL_GUARDED_BY(mutex_); diff --git a/cpp/platform/api/wifi_lan.h b/cpp/platform/api/wifi_lan.h index 9ba40a38..5c8f82e0 100644 --- a/cpp/platform/api/wifi_lan.h +++ b/cpp/platform/api/wifi_lan.h @@ -144,6 +144,10 @@ class WifiLanMedium { // On error, returns nullptr. virtual std::unique_ptr ListenForService( int port = 0) = 0; + + // Returns the port range as a pair of min and max port. + virtual absl::optional> + GetDynamicPortRange() = 0; }; } // namespace api diff --git a/cpp/platform/impl/g3/wifi_lan.h b/cpp/platform/impl/g3/wifi_lan.h index 8d95c673..4406ee66 100644 --- a/cpp/platform/impl/g3/wifi_lan.h +++ b/cpp/platform/impl/g3/wifi_lan.h @@ -233,6 +233,12 @@ class WifiLanMedium : public api::WifiLanMedium { std::unique_ptr ListenForService(int port) override ABSL_LOCKS_EXCLUDED(mutex_); + // Returns the port range as a pair of min and max port. + absl::optional> GetDynamicPortRange() + override { + return std::make_pair(49152, 65535); + } + private: struct AdvertisingInfo { bool Empty() const { return service_types.empty(); } diff --git a/cpp/platform/impl/ios/Source/Platform/wifi_lan.h b/cpp/platform/impl/ios/Source/Platform/wifi_lan.h index 9ed30d49..13062b4f 100644 --- a/cpp/platform/impl/ios/Source/Platform/wifi_lan.h +++ b/cpp/platform/impl/ios/Source/Platform/wifi_lan.h @@ -155,6 +155,10 @@ class WifiLanMedium : public api::WifiLanMedium { std::unique_ptr ListenForService(int port) override ABSL_LOCKS_EXCLUDED(mutex_); + absl::optional> GetDynamicPortRange() override { + return absl::nullopt; + } + private: struct AdvertisingInfo { bool Empty() const { return services.empty(); } diff --git a/cpp/platform/impl/windows/wifi_lan.h b/cpp/platform/impl/windows/wifi_lan.h index 5485367b..78481aa2 100644 --- a/cpp/platform/impl/windows/wifi_lan.h +++ b/cpp/platform/impl/windows/wifi_lan.h @@ -30,6 +30,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/synchronization/mutex.h" +#include "absl/types/optional.h" #include "platform/api/wifi_lan.h" #include "platform/base/exception.h" #include "platform/base/input_stream.h" @@ -247,6 +248,11 @@ class WifiLanMedium : public api::WifiLanMedium { // continue. void NotifyDnsServiceUnregistered(DWORD status); + absl::optional> GetDynamicPortRange() + override { + return absl::nullopt; + } + private: // mDNS text attributes static constexpr std::string_view KEY_ENDPOINT_INFO = "n"; diff --git a/cpp/platform/public/wifi_lan.h b/cpp/platform/public/wifi_lan.h index 9bf50926..f0a34dcc 100644 --- a/cpp/platform/public/wifi_lan.h +++ b/cpp/platform/public/wifi_lan.h @@ -187,6 +187,11 @@ class WifiLanMedium { return WifiLanServerSocket(impl_->ListenForService(port)); } + // Returns the port range as a pair of min and max port. + absl::optional> GetDynamicPortRange() { + return impl_->GetDynamicPortRange(); + } + bool IsValid() const { return impl_ != nullptr; } api::WifiLanMedium& GetImpl() { return *impl_; }