v0.4.0

Fast, dependency-free traceroute in pure C

Non-blocking sockets • TTL batching • Adaptive waits • Async DNS • Tunable pacing

Terminal
$ sudo ./fastrace google.com
        fastrace 0.4.0
        Tracing route to google.com (142.250.180.174)
        Maximum hops: 30, Probes per hop: 3, Protocol: UDP
        TTL | IP Address         (RTT ms)    Hostname
        ----+-----------------------------------------
        1   | -> 192.168.1.1     (  2.60 ms)
        2   | * * * (timeout)
        3   | * * * (timeout)
        4   | -> 185.89.159.5    (  6.81 ms)
        5   | -> 37.26.80.129    (  9.22 ms)
        6   | -> 193.77.91.225   ( 29.88 ms) bsn-77-91-225.static.siol.net
        7   | -> 193.77.107.46   ( 33.62 ms) bsn-77-107-46.static.siol.net

Overview

Fastrace is a blazingly fast traceroute utility designed for network diagnostics and performance analysis. It maps the route that packets take across an IP network from source to destination, providing detailed timing information and identifying potential bottlenecks or routing issues.

Zero Dependencies

Pure C: libc + raw sockets, nothing else

TTL Batching

Sets TTL once per hop and sends probes in bursts to cut syscalls

Adaptive Waits

Poll timing aligns to the next hop deadline to reduce idle spins

Non-Blocking Core

Event-driven pipeline with monotonic timing for stable RTTs

Tunable Pacing

Inter-probe delay flag (-d) to balance burstiness and jitter

Clear Output

Tree-style hops show load-balanced branches and precise RTTs

Async DNS

Dedicated thread for reverse lookups keeps the probe loop unblocked

Hardened Parsing

Bounds-checked ICMP handling and strict resource cleanup

Lightweight

Compact data structures sized to your trace configuration

Technical Architecture

Dual Socket Architecture

Fastrace uses two socket types for maximum effectiveness:

  • UDP socket (SOCK_DGRAM) for sending probe packets
  • Raw ICMP socket (SOCK_RAW) for receiving router responses
send_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
recv_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

Probe Structure

Each probe is tracked using a specialized structure with monotonic timing:

typedef struct {
    int ttl;                  /* Time-to-Live value */
    int probe;                /* Probe sequence number */
    struct timespec sent_time; /* Monotonic timestamp when sent */
    bool received;            /* Whether response was received */
    struct in_addr addr;      /* Address of responding hop */
    double rtt;               /* Round-trip time in ms */
    int port;                 /* UDP port used for this probe */
} probe_t;

Adaptive Route Discovery

Fastrace implements a configurable multi-TTL probing system with runtime-adjustable concurrency:

// Default concurrency window (tunable via -c flag)
config.max_active_ttls = 6;

// Probes per hop (tunable via -q flag)
config.num_probes = 3;

// Inter-probe delay in microseconds (tunable via -d flag)
config.probe_delay_us = 250;

Multiple TTLs stay in flight at once. Probes for a hop are batched under a single TTL setsockopt, cutting syscall overhead. Tuning -c, -q, and -d lets you balance speed and jitter.

Efficient Response Processing

The response processor uses a poll()-driven loop with non-blocking sockets to drain ICMP bursts. Time is monotonic throughout for stable RTT math:

int process_responses(int timeout_ms) {
    struct pollfd pfd = { .fd = recv_sock, .events = POLLIN | POLLERR | POLLHUP };
    if (timeout_ms > 0 && poll(&pfd, 1, timeout_ms) <= 0) return 0;
    return drain_icmp_socket();
}

static double timespec_diff_ms(const struct timespec *start, const struct timespec *end) {
    time_t sec = end->tv_sec - start->tv_sec;
    long nsec = end->tv_nsec - start->tv_nsec;
    if (nsec < 0) { sec -= 1; nsec += 1000000000L; }
    return (double)sec * 1000.0 + (double)nsec / 1000000.0;
}

Asynchronous DNS Resolution

Hostname lookups are offloaded to a dedicated background thread to prevent blocking the main packet loop:

static void *dns_worker(void *arg) {
    while (dns_running) {
        // ... wait for queue item ...
        if (getnameinfo(...) == 0) {
            host_cache_store(item->addr, host);
        }
    }
    return NULL;
}

Visual Path Representation

Fastrace provides a structured visual representation of network paths:

  • Tree-like format shows branching at load-balanced routes
  • Clear arrows indicate path progression
  • Distinct formatting for primary and alternative routes
7   │→ 72.14.209.224    ( 60.76 ms)
      └→ 72.14.223.184   ( 61.65 ms)
8   │→ 142.251.244.109  ( 59.57 ms)
      └→ 216.239.62.49   ( 71.36 ms)
      └→ 142.250.210.95  ( 70.25 ms)

Performance at a Glance

Designed to stay fast and responsive under load: batched TTL sends, adaptive waits, non-blocking sockets, and async DNS.

Faster Routes

Multiple TTLs in flight plus batched probes cut total trace time.

Lower Overhead

Fewer syscalls per hop and tight data structures reduce CPU and memory use.

Steady Timing

Monotonic clock for RTTs avoids drift from wall-clock adjustments.

Clear Output

Tree-style rendering highlights branching paths and per-hop RTTs.

Usage

Using Makefile

The project includes a Makefile for easy compilation and installation:

# Standard optimized build
make

# Build with debugging symbols
make debug

# Build with maximum performance optimizations
make optimized

# Install to system (default: /usr/local/bin)
sudo make install

# Uninstall from system
sudo make uninstall

# Clean build artifacts
make clean

Command-Line Options

# Disable DNS lookups for faster output
sudo ./fastrace -n google.com

# Set maximum hops and probes per hop
sudo ./fastrace -m 20 -q 5 google.com

# Adjust concurrent TTL window, pacing, and timeouts
sudo ./fastrace -c 8 -d 250 -W 2 -t 700 google.com

# Use custom base port
sudo ./fastrace -P 40000 google.com

# Show version
./fastrace -V
OptionDescription
-nDisable reverse DNS lookups
-m <hops>Maximum hop count (1-128, default 30)
-q <probes>Probes per hop (1-10, default 3)
-c <count>Concurrent TTL window size (default 6)
-W <ms>Poll wait timeout in milliseconds (default 2)
-t <ms>Hop completion timeout in milliseconds (default 700)
-d <us>Inter-probe delay in microseconds (default 250)
-P <port>Base UDP destination port (default 33434)
-VPrint version information
-hDisplay help message

Manual Compilation

gcc -O3 -pthread -o fastrace fastrace.c

For maximum performance:

gcc -O3 -march=native -mtune=native -flto -pthread -o fastrace fastrace.c

Basic Usage

sudo ./fastrace <target>

Example:

sudo ./fastrace google.com

Technical Requirements

System Requirements

  • Operating System: Linux, macOS, or other Unix-like systems with raw socket support
  • Permissions: Root/sudo access required (raw sockets)
  • Compiler: GCC with C99 support or later
  • Architecture: x86, x86_64, ARM, or any platform with standard C library support

Header Dependencies

#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <poll.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>