Reuse the same wifi lan listening port number if endpoint ID stays the same.

PiperOrigin-RevId: 810534040
This commit is contained in:
Francis Tsui
2025-09-23 12:16:23 -07:00
committed by Copybara-Service
parent 6f92e238b0
commit 6d9122c4eb
5 changed files with 71 additions and 4 deletions
+13 -3
View File
@@ -106,17 +106,25 @@ ErrorOr<bool> WifiLan::StartAdvertising(const std::string& service_id,
}
nsd_service_info.SetServiceType(GenerateServiceType(service_id));
const auto& it = server_sockets_.find(service_id);
std::string mdns_service_name = nsd_service_info.GetServiceName();
int port = 0;
if (it != server_sockets_.end()) {
nsd_service_info.SetPort(it->second.GetPort());
port = it->second.GetPort();
} else {
int port = 0;
if (!mdns_service_name.empty() &&
mdns_service_name == last_mdns_service_name_) {
VLOG(1) << __func__
<< " reusing server port number: " << last_server_port_;
port = last_server_port_;
}
ErrorOr<int> port_result = StartAcceptingConnectionsLocked(
service_id, port, std::move(callback));
if (port_result.has_error()) {
return {port_result.error()};
}
nsd_service_info.SetPort(port_result.value());
port = port_result.value();
}
nsd_service_info.SetPort(port);
if (!medium_.StartAdvertising(nsd_service_info)) {
LOG(INFO) << "Failed to turn on WifiLan advertising with nsd_service_info="
<< &nsd_service_info
@@ -126,6 +134,8 @@ ErrorOr<bool> WifiLan::StartAdvertising(const std::string& service_id,
return {Error(
OperationResultCode::CONNECTIVITY_WIFI_LAN_START_ADVERTISING_FAILURE)};
}
last_mdns_service_name_ = std::move(mdns_service_name);
last_server_port_ = port;
LOG(INFO) << "Turned on WifiLan advertising with nsd_service_info="
<< &nsd_service_info
@@ -226,6 +226,9 @@ class WifiLan {
// A map of IpAddress -> MultiplexSocket.
absl::flat_hash_map<std::string, mediums::multiplex::MultiplexSocket*>
multiplex_sockets_ ABSL_GUARDED_BY(mutex_);
std::string last_mdns_service_name_ ABSL_GUARDED_BY(mutex_);
int last_server_port_ ABSL_GUARDED_BY(mutex_) = 0;
};
} // namespace connections
@@ -61,6 +61,51 @@ class WifiLanTest : public ::testing::TestWithParam<FeatureFlags> {
MediumEnvironment& env_{MediumEnvironment::Instance()};
};
TEST_P(WifiLanTest, AdvertiseSameServiceNameReusesPort) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
WifiLan wifi_lan_server;
std::string service_id(kServiceID);
std::string endpoint_info_name(kEndpointName);
WifiLanSocket socket_for_server;
NsdServiceInfo nsd_service_info;
nsd_service_info.SetServiceName(std::string(kServiceInfoName));
wifi_lan_server.StartAdvertising(service_id, nsd_service_info, {});
auto [address, port] = wifi_lan_server.GetCredentials(service_id);
wifi_lan_server.StopAdvertising(service_id);
wifi_lan_server.StopAcceptingConnections(service_id);
wifi_lan_server.StartAdvertising(service_id, nsd_service_info, {});
auto [address2, port2] = wifi_lan_server.GetCredentials(service_id);
EXPECT_EQ(port, port2);
env_.Stop();
}
TEST_P(WifiLanTest, AdvertiseDifferentServiceNameUsesDifferentPort) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
WifiLan wifi_lan_server;
std::string service_id(kServiceID);
std::string endpoint_info_name(kEndpointName);
WifiLanSocket socket_for_server;
NsdServiceInfo nsd_service_info;
nsd_service_info.SetServiceName(std::string(kServiceInfoName));
wifi_lan_server.StartAdvertising(service_id, nsd_service_info, {});
auto [address, port] = wifi_lan_server.GetCredentials(service_id);
wifi_lan_server.StopAdvertising(service_id);
wifi_lan_server.StopAcceptingConnections(service_id);
nsd_service_info.SetServiceName("ServiceInfoName2");
wifi_lan_server.StartAdvertising(service_id, nsd_service_info, {});
auto [address2, port2] = wifi_lan_server.GetCredentials(service_id);
EXPECT_NE(port, port2);
env_.Stop();
}
TEST_P(WifiLanTest, CanConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
@@ -203,7 +203,7 @@ class WifiLanMedium : public api::WifiLanMedium {
// Returns the port range as a pair of min and max port.
absl::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange()
override {
return std::make_pair(49152, 65535);
return std::nullopt;
}
private:
@@ -71,6 +71,15 @@ bool NearbyServerSocket::Listen(const std::string& ip_address, int port) {
} else {
serv_addr.sin_addr.s_addr = inet_addr(ip_address.c_str());
}
// Set REUSEADDR if a specific port is needed.
if (port != 0) {
BOOL flag = TRUE;
if (setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag,
sizeof(flag)) == SOCKET_ERROR) {
LOG(WARNING) << "Failed to set SO_REUSEADDR with error "
<< WSAGetLastError();
}
}
if (bind(/*s=*/socket_, /*addr=*/(struct sockaddr*)&serv_addr,
/*namelen=*/sizeof(serv_addr)) == SOCKET_ERROR) {