Skip to content

Commit 8f0a271

Browse files
authored
Merge pull request #63 from BornToBeRoot/traceroute-performance
Traceroute performance improved
2 parents ebfcfb0 + a438aa1 commit 8f0a271

3 files changed

Lines changed: 55 additions & 34 deletions

File tree

Source/NETworkManager/App.xaml.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,17 @@ private void Application_Startup(object sender, StartupEventArgs e)
5858
return;
5959
}
6060

61-
// Single instance
61+
// Create mutex
6262
_mutex = new Mutex(true, "{" + Guid + "}");
6363
bool mutexIsAcquired = _mutex.WaitOne(TimeSpan.Zero, true);
64+
65+
// Release mutex
66+
if (mutexIsAcquired)
67+
_mutex.ReleaseMutex();
6468

6569
if (SettingsManager.Current.Window_MultipleInstances || mutexIsAcquired)
6670
{
67-
StartupUri = new Uri("MainWindow.xaml", UriKind.Relative);
68-
69-
if (mutexIsAcquired)
70-
_mutex.ReleaseMutex();
71+
StartupUri = new Uri("MainWindow.xaml", UriKind.Relative);
7172
}
7273
else
7374
{

Source/NETworkManager/Models/Network/Traceroute.cs

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,37 +44,65 @@ public void TraceAsync(IPAddress ipAddress, TracerouteOptions traceOptions, Canc
4444
Task.Run(() =>
4545
{
4646
byte[] buffer = new byte[traceOptions.Buffer];
47-
int maximumHops = traceOptions.MaximumHops + 1;
47+
int maximumHops = traceOptions.MaximumHops;
4848

49-
int hop = 1;
49+
bool maximumHopsReached = false;
5050

51-
do
51+
// Get the ttl of the ip
52+
using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping())
5253
{
53-
List<Task<Tuple<PingReply, long>>> tasks = new List<Task<Tuple<PingReply, long>>>();
54+
PingReply pingReply;
5455

5556
for (int i = 0; i < 3; i++)
57+
{
58+
pingReply = ping.Send(ipAddress, traceOptions.Timeout, buffer, new System.Net.NetworkInformation.PingOptions() { Ttl = 64, DontFragment = traceOptions.DontFragement });
59+
60+
if (pingReply.Status == IPStatus.Success)
61+
{
62+
int ttl = 64 - pingReply.Options.Ttl;
63+
64+
if (ttl < maximumHops)
65+
maximumHops = ttl;
66+
else
67+
maximumHopsReached = true;
68+
69+
break;
70+
}
71+
}
72+
}
73+
74+
// Async check all hops
75+
Parallel.For(1, maximumHops + 1, new ParallelOptions() { CancellationToken = cancellationToken }, i =>
76+
{
77+
List<Task<Tuple<PingReply, long>>> tasks = new List<Task<Tuple<PingReply, long>>>();
78+
79+
for (int y = 0; y < 3; y++)
5680
{
5781
tasks.Add(Task.Run(() =>
58-
{
59-
Stopwatch stopwatch = new Stopwatch();
82+
{
83+
Stopwatch stopwatch = new Stopwatch();
6084

61-
PingReply pingReply;
85+
PingReply pingReply;
6286

63-
using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping())
64-
{
65-
stopwatch.Start();
87+
using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping())
88+
{
89+
stopwatch.Start();
6690

67-
pingReply = ping.Send(ipAddress, traceOptions.Timeout, buffer, new System.Net.NetworkInformation.PingOptions() { Ttl = hop, DontFragment = traceOptions.DontFragement });
91+
pingReply = ping.Send(ipAddress, traceOptions.Timeout, buffer, new System.Net.NetworkInformation.PingOptions() { Ttl = i, DontFragment = traceOptions.DontFragement });
6892

69-
stopwatch.Stop();
70-
}
93+
stopwatch.Stop();
94+
}
7195

72-
return Tuple.Create(pingReply, stopwatch.ElapsedMilliseconds);
73-
}));
96+
return Tuple.Create(pingReply, stopwatch.ElapsedMilliseconds);
97+
}));
7498
}
7599

76100
Task.WaitAll(tasks.ToArray());
77101

102+
// Here is a good point to cancel (Don't resolve dns...)
103+
if (cancellationToken.IsCancellationRequested)
104+
return;
105+
78106
IPAddress ipAddressHop = tasks.FirstOrDefault(x => x.Result.Item1 != null).Result.Item1.Address;
79107

80108
string hostname = string.Empty;
@@ -86,24 +114,15 @@ public void TraceAsync(IPAddress ipAddress, TracerouteOptions traceOptions, Canc
86114
}
87115
catch (SocketException) { } // Couldn't resolve hostname
88116

89-
OnHopReceived(new TracerouteHopReceivedArgs(hop, tasks[0].Result.Item2, tasks[1].Result.Item2, tasks[2].Result.Item2, ipAddressHop, hostname, tasks[0].Result.Item1.Status, tasks[1].Result.Item1.Status, tasks[2].Result.Item1.Status));
90-
91-
if (ipAddressHop != null)
92-
{
93-
if (ipAddressHop.ToString() == ipAddress.ToString())
94-
{
95-
OnTraceComplete();
96-
return;
97-
}
98-
}
99-
100-
hop++;
101-
} while (hop < maximumHops && !cancellationToken.IsCancellationRequested);
117+
OnHopReceived(new TracerouteHopReceivedArgs(i, tasks[0].Result.Item2, tasks[1].Result.Item2, tasks[2].Result.Item2, ipAddressHop, hostname, tasks[0].Result.Item1.Status, tasks[1].Result.Item1.Status, tasks[2].Result.Item1.Status));
118+
});
102119

103120
if (cancellationToken.IsCancellationRequested)
104121
OnUserHasCanceled();
105-
else if (hop == maximumHops)
122+
else if (maximumHopsReached)
106123
OnMaximumHopsReached(new MaximumHopsReachedArgs(traceOptions.MaximumHops));
124+
else
125+
OnTraceComplete();
107126

108127
}, cancellationToken);
109128
}

Source/NETworkManager/ViewModels/Applications/TracerouteViewModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ public int Hops
224224
public TracerouteViewModel()
225225
{
226226
_traceResultView = CollectionViewSource.GetDefaultView(TraceResult);
227+
_traceResultView.SortDescriptions.Add(new SortDescription("Hop", ListSortDirection.Ascending));
227228

228229
LoadSettings();
229230

0 commit comments

Comments
 (0)