Skip to content

Commit 30f8335

Browse files
committed
fix: restore cross-platform discovery heuristics
1 parent bfdb782 commit 30f8335

File tree

3 files changed

+92
-5
lines changed

3 files changed

+92
-5
lines changed

Companion.Tests/Services/OpenIpcDiscoveryServiceTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ public class OpenIpcDiscoveryServiceTests
1212
[Test]
1313
public void BuildDiscoveryScanPrefix_ClampsBroadSubnetToClassC()
1414
{
15+
if (!OperatingSystem.IsWindows())
16+
{
17+
Assert.Pass("Windows-specific discovery clamp.");
18+
return;
19+
}
20+
1521
var prefix = NetworkHelper.BuildDiscoveryScanPrefix(
1622
IPAddress.Parse("192.168.2.45"),
1723
IPAddress.Parse("255.255.0.0"));
@@ -55,4 +61,47 @@ public void SelectPreferredCandidates_PrefersUsbCandidatesOverVirtualNoGatewayAd
5561
Assert.That(selected.Select(candidate => candidate.InterfaceName).ToArray(),
5662
Is.EqualTo(new[] { "USB Ethernet/RNDIS Gadget" }));
5763
}
64+
65+
[Test]
66+
public void SelectPreferredCandidates_OnMacOsPrefersBridge100ForInternetSharing()
67+
{
68+
if (!OperatingSystem.IsMacOS())
69+
{
70+
Assert.Pass("macOS-specific bridge selection.");
71+
return;
72+
}
73+
74+
var method = typeof(OpenIpcDiscoveryService).GetMethod(
75+
"SelectPreferredCandidates",
76+
BindingFlags.NonPublic | BindingFlags.Static);
77+
78+
Assert.That(method, Is.Not.Null);
79+
80+
var candidates = new List<NetworkHelper.LocalNetworkCandidate>
81+
{
82+
new(
83+
IPAddress.Parse("192.168.1.55"),
84+
IPAddress.Parse("255.255.255.0"),
85+
"en17",
86+
60,
87+
false,
88+
false,
89+
false,
90+
true),
91+
new(
92+
IPAddress.Parse("192.168.2.1"),
93+
IPAddress.Parse("255.255.255.0"),
94+
"bridge100",
95+
35,
96+
false,
97+
false,
98+
false,
99+
true)
100+
};
101+
102+
var selected = (IReadOnlyList<NetworkHelper.LocalNetworkCandidate>)method!.Invoke(null, new object[] { candidates })!;
103+
104+
Assert.That(selected.Select(candidate => candidate.InterfaceName).ToArray(),
105+
Is.EqualTo(new[] { "bridge100" }));
106+
}
58107
}

Companion/Services/NetworkHelper.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ public static string BuildScanPrefix(IPAddress ipAddress, IPAddress mask)
133133

134134
public static string BuildDiscoveryScanPrefix(IPAddress ipAddress, IPAddress mask)
135135
{
136+
if (!OperatingSystem.IsWindows())
137+
return BuildScanPrefix(ipAddress, mask);
138+
136139
var prefix = BuildScanPrefix(ipAddress, mask);
137140
var parts = prefix.Split('.', StringSplitOptions.RemoveEmptyEntries);
138141

@@ -226,16 +229,40 @@ private static bool IsUsbLikeInterface(NetworkInterface nic)
226229
private static bool IsVirtualLikeInterface(NetworkInterface nic)
227230
{
228231
var descriptor = $"{nic.Name} {nic.Description} {nic.Id}";
232+
if (OperatingSystem.IsWindows())
233+
{
234+
return ContainsAny(descriptor,
235+
"virtual",
236+
"vmware",
237+
"hyper-v",
238+
"vbox",
239+
"docker",
240+
"wsl",
241+
"vethernet",
242+
"default switch",
243+
"tailscale",
244+
"zerotier");
245+
}
246+
247+
if (OperatingSystem.IsMacOS())
248+
{
249+
if (nic.Name.Equals("bridge100", StringComparison.OrdinalIgnoreCase))
250+
return false;
251+
252+
return ContainsAny(descriptor,
253+
"virtual",
254+
"vmware",
255+
"vbox",
256+
"docker",
257+
"tailscale",
258+
"zerotier");
259+
}
260+
229261
return ContainsAny(descriptor,
230-
"bridge",
231262
"virtual",
232263
"vmware",
233-
"hyper-v",
234264
"vbox",
235265
"docker",
236-
"wsl",
237-
"vethernet",
238-
"default switch",
239266
"tailscale",
240267
"zerotier");
241268
}

Companion/Services/OpenIpcDiscoveryService.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,17 @@ private async Task<bool> TryPingAsync(string host, CancellationToken cancellatio
187187
if (usbCandidates.Count > 0)
188188
return usbCandidates;
189189

190+
if (OperatingSystem.IsMacOS())
191+
{
192+
var macBridgeCandidates = candidates
193+
.Where(candidate => candidate.InterfaceName.Equals("bridge100", StringComparison.OrdinalIgnoreCase) &&
194+
candidate.IsPrivateIPv4)
195+
.ToList();
196+
197+
if (macBridgeCandidates.Count > 0)
198+
return macBridgeCandidates;
199+
}
200+
190201
var directAttached = candidates
191202
.Where(candidate => !candidate.HasGateway &&
192203
!candidate.IsVirtualLike &&

0 commit comments

Comments
 (0)