private void Configure([NotNull] string interfaceName, int port)
{
// In case the beacon was configured twice
if (m_udpSocket != null)
{
m_poller.Remove(m_udpSocket);
#if NET35
m_udpSocket.Close();
#else
m_udpSocket.Dispose();
#endif
}
m_udpPort = port;
m_udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_poller.Add(m_udpSocket, OnUdpReady);
// Ask operating system for broadcast permissions on socket
m_udpSocket.EnableBroadcast = true;
// Allow multiple owners to bind to socket; incoming
// messages will replicate to each owner
m_udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
IPAddress bindTo = null;
IPAddress sendTo = null;
if (interfaceName == "*")
{
bindTo = IPAddress.Any;
sendTo = IPAddress.Broadcast;
}
else if (interfaceName == "loopback")
{
bindTo = IPAddress.Loopback;
sendTo = IPAddress.Broadcast;
}
else
{
var interfaceCollection = new InterfaceCollection();
var interfaceAddress = !string.IsNullOrEmpty(interfaceName)
? IPAddress.Parse(interfaceName)
: null;
foreach (var @interface in interfaceCollection)
{
if (interfaceAddress == null || @interface.Address.Equals(interfaceAddress))
{
// because windows and unix differ in how they handle broadcast addressing this needs to be platform specific
// on windows any interface can recieve broadcast by requesting to enable broadcast on the socket
// on linux to recieve broadcast you must bind to the broadcast address specifically
//bindTo = @interface.Address;
sendTo = @interface.BroadcastAddress;
#if NET35 || NET40
if (Environment.OSVersion.Platform == PlatformID.Unix)
#else
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
#endif
{
bindTo = @interface.BroadcastAddress;
}
else
{
bindTo = @interface.Address;
}
sendTo = @interface.BroadcastAddress;
break;
}
}
}
if (bindTo != null)
{
m_broadcastAddress = new IPEndPoint(sendTo, m_udpPort);
m_udpSocket.Bind(new IPEndPoint(bindTo, m_udpPort));
}
m_pipe.SendFrame(bindTo?.ToString() ?? "");
}