Skip to content

Commit

Permalink
Core: fix TraceRouteAsync could send more ICMP than required
Browse files Browse the repository at this point in the history
- abortScan: was never set to true, so any packets started up to 100ms after a successfull ping would still be sent
- add a random token in all ICMP packets sent during the same attempt, so that packets from the same "run" can be more easily identified
  • Loading branch information
KrzysFR committed Aug 1, 2024
1 parent 4cba7a1 commit 901afe0
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions Doxense.Core/Networking/IPAddressHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -701,10 +701,13 @@ public static async Task<TracerouteReply> TracerouteAsync(IPAddress address, int
var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
var delay = Task.Delay(Timeout.Infinite, cts.Token);

// we add a random token to more easily identify all the packets of the same traceroute run
var token = Guid.NewGuid().GetHashCode().ToString("X08");

async Task<TracerouteHop?> RunHop(int i)
{
var options = new PingOptions(i + 1, dontFragment: false);
var buffer = Encoding.ASCII.GetBytes($"Doxense-Traceroute-TTL{i + 1:D03}");
var buffer = Encoding.ASCII.GetBytes($"Doxense-Traceroute-{token}-TTL{i + 1:D03}");

using (var ping = new Ping())
{
Expand All @@ -719,12 +722,13 @@ public static async Task<TracerouteReply> TracerouteAsync(IPAddress address, int
sw.Stop();
var reply = await task.ConfigureAwait(false);

if (reply.Status == IPStatus.Success || reply.Status == IPStatus.DestinationHostUnreachable)
if (reply.Status is IPStatus.Success or IPStatus.DestinationHostUnreachable)
{ // ca ne sert a rien de continuer plus!
lock (cts)
{
if (!abortScan)
{
abortScan = true;
// cancel all remaining requests without waiting for the full timeout
try { cts.CancelAfter(100); } catch { }
}
Expand Down Expand Up @@ -809,12 +813,16 @@ public static async Task<TracerouteReply> TracerouteAsync(IPAddress address, int
[DebuggerDisplay("Status={Status}, MaxTtl={MaxTtl}, Hops={Hops.Count}")]
public sealed record TracerouteReply
{
/// <summary>Result of the traceroute</summary>
public required IPStatus Status { get; init; }

/// <summary>Maximum TTL</summary>
public required int MaxTtl { get; init; }

/// <summary>Timeout</summary>
public required TimeSpan Timeout { get; init; }

/// <summary>List of hops that have replied</summary>
public required List<TracerouteHop> Hops { get; init; }

}
Expand Down

0 comments on commit 901afe0

Please sign in to comment.