Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Network changed #43

Merged
merged 3 commits into from
Dec 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Spike/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ static void Main(string[] args)
{
["level"] = "TRACE",
["showLogName"] = "true",
["showDateTime"] = "true"
["showDateTime"] = "true",
["dateTimeFormat"] = "HH:mm:ss.fff"

};
LogManager.Adapter = new ConsoleOutLoggerFactoryAdapter(properties);

Expand Down
21 changes: 18 additions & 3 deletions src/MulticastClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Common.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -11,6 +12,7 @@ namespace Makaretu.Dns
{
class MulticastClient : IDisposable
{
static readonly ILog log = LogManager.GetLogger(typeof(MulticastClient));
public static readonly bool IP6;

readonly IPEndPoint multicastEndpoint;
Expand Down Expand Up @@ -38,13 +40,20 @@ public MulticastClient(IPEndPoint multicastEndpoint, IEnumerable<NetworkInterfac

foreach (var address in nics.SelectMany(GetNetworkInterfaceLocalAddresses))
{
if (senders.Keys.Contains(address))
{
continue;
}

var localEndpoint = new IPEndPoint(address, multicastEndpoint.Port);
log.Debug($"Will send to {localEndpoint}");
var sender = new UdpClient(multicastEndpoint.AddressFamily);
try
{
receiver.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(multicastEndpoint.Address, address));

var sender = new UdpClient(multicastEndpoint.AddressFamily);
sender.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
sender.Client.Bind(new IPEndPoint(address, multicastEndpoint.Port));
sender.Client.Bind(localEndpoint);
sender.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(multicastEndpoint.Address));
sender.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, true);

Expand All @@ -57,6 +66,12 @@ public MulticastClient(IPEndPoint multicastEndpoint, IEnumerable<NetworkInterfac
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.AddressNotAvailable)
{
// VPN NetworkInterfaces
sender.Dispose();
}
catch (Exception)
{
sender.Dispose();
throw;
}
}
}
Expand Down
77 changes: 48 additions & 29 deletions src/MulticastService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,48 +229,67 @@ public void Stop()

void FindNetworkInterfaces()
{
var currentNics = GetNetworkInterfaces().ToList();
log.Debug("Finding network interfaces");

var newNics = new List<NetworkInterface>();
var oldNics = new List<NetworkInterface>();

foreach (var nic in knownNics.Where(k => !currentNics.Any(n => k.Id == n.Id)))
try
{
oldNics.Add(nic);
var currentNics = GetNetworkInterfaces().ToList();

var newNics = new List<NetworkInterface>();
var oldNics = new List<NetworkInterface>();

if (log.IsDebugEnabled)
foreach (var nic in knownNics.Where(k => !currentNics.Any(n => k.Id == n.Id)))
{
log.Debug($"Removed nic '{nic.Name}'.");
}
}
oldNics.Add(nic);

foreach (var nic in currentNics.Where(nic => !knownNics.Any(k => k.Id == nic.Id)))
{
newNics.Add(nic);
if (log.IsDebugEnabled)
{
log.Debug($"Removed nic '{nic.Name}'.");
}
}

if (log.IsDebugEnabled)
foreach (var nic in currentNics.Where(nic => !knownNics.Any(k => k.Id == nic.Id)))
{
log.Debug($"Found nic '{nic.Name}'.");
newNics.Add(nic);

if (log.IsDebugEnabled)
{
log.Debug($"Found nic '{nic.Name}'.");
}
}
}

knownNics = currentNics;
knownNics = currentNics;

client?.Dispose();
client = new MulticastClient(MdnsEndpoint, networkInterfacesFilter?.Invoke(knownNics) ?? knownNics);
client.Receive(OnDnsMessage);
// Only create client if something has change.
if (newNics.Any() || oldNics.Any())
{
client?.Dispose();
client = new MulticastClient(MdnsEndpoint, networkInterfacesFilter?.Invoke(knownNics) ?? knownNics);
client.Receive(OnDnsMessage);
}

// Tell others.
if (newNics.Any())
{
NetworkInterfaceDiscovered?.Invoke(this, new NetworkInterfaceEventArgs
// Tell others.
if (newNics.Any())
{
NetworkInterfaces = newNics
});
}
NetworkInterfaceDiscovered?.Invoke(this, new NetworkInterfaceEventArgs
{
NetworkInterfaces = newNics
});
}

NetworkChange.NetworkAddressChanged -= OnNetworkAddressChanged;
NetworkChange.NetworkAddressChanged += OnNetworkAddressChanged;
// Magic from @eshvatskyi
//
// I've seen situation when NetworkAddressChanged is not triggered
// (wifi off, but NIC is not disabled, wifi - on, NIC was not changed
// so no event). Rebinding fixes this.
//
NetworkChange.NetworkAddressChanged -= OnNetworkAddressChanged;
NetworkChange.NetworkAddressChanged += OnNetworkAddressChanged;
}
catch (Exception e)
{
log.Error("FindNics failed", e);
}
}

/// <inheritdoc />
Expand Down