Skip to content

Commit 892459e

Browse files
authored
Remove need for machine to have a valid hostname in IdGenerator (#781)
### Summary & Motivation The code in IdGenerator that finds an IP for the local machine previously required the machine to have a valid hostname. This caused issue if a valid hostname was not specified, a problem I ran into on a new Mac. This change iterates network interfaces instead of resolving the IP of the computer hostname. It also improves the logic, in that it guarantees that the resolved IP will never be a loopback address (such as 127.0.0.1). ### Checklist - [x] I have added tests, or done manual regression tests - [x] I have updated the documentation, if necessary
2 parents a55cd4d + 6fb70eb commit 892459e

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

application/shared-kernel/SharedKernel/StronglyTypedIds/IdGenerator.cs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Net;
1+
using System.Net.NetworkInformation;
22
using System.Net.Sockets;
33

44
namespace PlatformPlatform.SharedKernel.StronglyTypedIds;
@@ -33,12 +33,28 @@ public static long NewId()
3333
/// </summary>
3434
private static int GetUniqueGeneratorIdFromIpAddress()
3535
{
36-
var host = Dns.GetHostEntry(Dns.GetHostName());
3736
const string noNetworkAdapters = "No network adapters with an IPv4 address in the system. IdGenerator is meant to create unique IDs across multiple machines, and requires an IP address to do so.";
38-
var ipAddress = Array.Find(host.AddressList, ip => ip.AddressFamily == AddressFamily.InterNetwork)
39-
?? throw new InvalidOperationException(noNetworkAdapters);
4037

41-
var lastSegment = ipAddress.ToString().Split('.')[3];
42-
return int.Parse(lastSegment);
38+
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces()
39+
.Where(ni => ni.OperationalStatus == OperationalStatus.Up &&
40+
ni.NetworkInterfaceType != NetworkInterfaceType.Loopback &&
41+
ni.NetworkInterfaceType != NetworkInterfaceType.Tunnel
42+
)
43+
.ToArray();
44+
45+
foreach (var networkInterface in networkInterfaces)
46+
{
47+
var properties = networkInterface.GetIPProperties();
48+
var ipv4Address = properties.UnicastAddresses
49+
.FirstOrDefault(addr => addr.Address.AddressFamily == AddressFamily.InterNetwork);
50+
51+
if (ipv4Address is not null)
52+
{
53+
var lastSegment = ipv4Address.Address.ToString().Split('.')[3];
54+
return int.Parse(lastSegment);
55+
}
56+
}
57+
58+
throw new InvalidOperationException(noNetworkAdapters);
4359
}
4460
}

0 commit comments

Comments
 (0)