{"id":38783811,"url":"https://github.com/antonio-prado/ping6-it","last_synced_at":"2026-01-19T16:01:26.020Z","repository":{"id":332080229,"uuid":"1130532466","full_name":"Antonio-Prado/ping6-it","owner":"Antonio-Prado","description":"Compare IPv4 vs IPv6 latency and reachability using Globalping probes (ping, traceroute, DNS, HTTP).","archived":false,"fork":false,"pushed_at":"2026-01-12T09:57:54.000Z","size":278,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-12T18:49:41.766Z","etag":null,"topics":["dns","globalping","http","ipv4","ipv6","mtr","network-measurement","observability","ping","react","traceroute"],"latest_commit_sha":null,"homepage":"https://ping6.it","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Antonio-Prado.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-08T16:33:11.000Z","updated_at":"2026-01-12T13:39:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Antonio-Prado/ping6-it","commit_stats":null,"previous_names":["antonio-prado/ping6-it"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Antonio-Prado/ping6-it","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Antonio-Prado%2Fping6-it","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Antonio-Prado%2Fping6-it/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Antonio-Prado%2Fping6-it/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Antonio-Prado%2Fping6-it/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Antonio-Prado","download_url":"https://codeload.github.com/Antonio-Prado/ping6-it/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Antonio-Prado%2Fping6-it/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28573281,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T15:45:05.669Z","status":"ssl_error","status_checked_at":"2026-01-19T15:44:23.317Z","response_time":67,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dns","globalping","http","ipv4","ipv6","mtr","network-measurement","observability","ping","react","traceroute"],"created_at":"2026-01-17T12:29:14.728Z","updated_at":"2026-01-19T16:01:26.008Z","avatar_url":"https://github.com/Antonio-Prado.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://ping6.it\"\u003e\n    \u003cimg src=\"./public/logo-badge.svg\" alt=\"ping6.it logo\" width=\"220\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# ping6.it\n\n**ping6.it** is a small web UI that runs the same network measurement over **IPv4 and IPv6** on the **same set of probes** (Globalping) and presents a side-by-side comparison.\n\nIt is intended for **quick, reproducible v4 vs v6 troubleshooting**: reachability gaps, latency deltas, loss anomalies, and routing/path asymmetries.\n\n\u003e Experimental beta: defaults, UI layout, and comparison logic may evolve.\n\nLive: https://ping6.it  \nFeedback: mailto:antonio@prado.it\n\n## Main features\n\n- **Fair v4/v6 comparison** by pinning both runs to the **same probes**\n- **Commands:** `ping`, `traceroute`, `mtr`, `dns`, `http`\n- **Geo selection** (macro region + sub-regions) and **Net** filter (eyeball/datacenter)\n- Probe filters: **limit**, **ASN**, **ISP**, **IPv6-capable probes only**\n- **Multi-target** mode (run the same command over multiple targets)\n- **Exports:** JSON (raw bundle) and CSV (per-probe rows)\n- **Share link** (settings) and **Report mode** (shareable link embedding results)\n- **History (local)** stored in your browser (and run-to-run comparison)\n\n## Table of contents\n\n- [What ping6.it is for](#what-ping6it-is-for)\n- [How the v4v6 comparison works](#how-the-v4v6-comparison-works)\n  - [Target validation](#target-validation)\n- [Common controls](#common-controls)\n- [Commands](#commands)\n  - [ping](#ping)\n  - [traceroute](#traceroute)\n  - [mtr](#mtr)\n  - [dns](#dns)\n  - [http](#http)\n- [Interpreting results](#interpreting-results)\n- [API endpoints](#api-endpoints)\n- [Limitations and notes](#limitations-and-notes)\n- [Development](#development)\n- [Contributing](#contributing)\n- [Security](#security)\n- [Acknowledgements](#acknowledgements)\n- [License](#license)\n\n## What ping6.it is for\n\nTypical use cases:\n\n- “IPv6 is slow” → quantify deltas and see where they appear\n- “IPv6 fails but IPv4 works” → validate reachability by region / eyeball vs DC\n- Resolver differences (DNS) and handshake/transfer timing differences (HTTP)\n- Path asymmetry hints (traceroute / mtr), including loss patterns\n\nThe goal is not to be a full monitoring suite, but a **fast comparison UI** with reproducible runs.\n\n## How the v4/v6 comparison works\n\nping6.it creates **two Globalping measurements** (v4 and v6) and ensures they run on the **same probe set**:\n\n- First run selects probes normally (based on `From`, `Net`, limit, ASN/ISP filters, etc.)\n- Second run is executed on the **exact same probes** by referencing the first measurement id as `locations`\n\nThe ordering depends on the **IPv6-capable probes only** toggle:\n\n- **Enabled (default):**\n  1) run **IPv6 first** (`ipVersion: 6`) to select probes that can actually execute IPv6  \n  2) run **IPv4** (`ipVersion: 4`) on the **same probes** by referencing the IPv6 measurement id\n\n- **Disabled:**\n  1) run **IPv4 first** (`ipVersion: 4`) to select probes  \n  2) run **IPv6** (`ipVersion: 6`) on the **same probes** by referencing the IPv4 measurement id\n\n### Target validation\n\n- For `ping`, `traceroute`, `mtr`, and `http`, the target must be a **hostname** (IP literals are rejected) to keep the comparison meaningful.\n- For `dns`, the input may also be an **IP literal** (e.g. `PTR`).\n- When the target is an IP literal, **IPv6-capable probes only** is disabled (probe selection cannot be safely pinned via hostname rules).\n\n## Common controls\n\n### Language\nThe UI supports English and Italian. Language is stored locally in your browser.\n\n### Target / Multi-target\n- **Single target:** one hostname (or IP literal for DNS).\n- **Multi-target:** paste multiple targets (one per line). ping6.it will run them sequentially and show a consolidated summary.\n\n### Command\nSelects the measurement type:\n\n- `ping`\n- `traceroute`\n- `mtr`\n- `dns`\n- `http`\n\nChanging the command resets the UI to **Basic** mode.\n\n### From (geo)\nSelects probe location(s). The UI provides macro regions and sub-regions; the resulting string is sent to Globalping.\n\n### Net\nFilters probes by network type:\n- `any`\n- `eyeball` (access/consumer)\n- `datacenter`\n\nInternally this is implemented via Globalping location tags.\n\n### Probes\nNumber of probes to select (clamped to a small max to reduce abuse and keep results readable).\n\n### ASN / ISP\nOptional filters that constrain probe selection:\n- **ASN:** numeric ASN (e.g. `12345`)\n- **ISP:** free-text label (as supported by Globalping metadata)\n\n### IPv6-capable probes only\nEnsures probe selection is driven by IPv6 reachability, then reuses the same probes for IPv4.\n\n### Δ alert (ms)\nOptional threshold used in summaries/reports to highlight large v6-v4 deltas.\n\n### Run / Cancel\n- **Run** starts the v4/v6 measurement pair on the same probes.\n- **Cancel** aborts the in-progress run.\n\n\u003e Note: a Cloudflare Turnstile challenge is used to reduce automated abuse. Verification is performed server-side.\n\n### Basic / Advanced\nToggles the visibility of additional options. Advanced options depend on the selected command.\n\n### Raw\nEnabled once both v4 and v6 results are present. Shows the **raw command output** returned by each probe for both IP versions.\n\n### Export JSON / Export CSV\nAvailable once results are present:\n- **JSON**: raw bundle (settings + per-probe raw results)\n- **CSV**: per-probe rows (useful for quick offline inspection)\n\n### Share link / Report mode\n- **Share link**: encodes current settings into URL query parameters.\n- **Report mode**: encodes both settings and results into the URL (shareable, read-only view).\n\n## Commands\n\n### ping\n\nBasic:\n- target (hostname)\n- probes, from/net filters\n\nAdvanced:\n- **Packets:** packets per probe\n\nOutput:\n- per-probe timing and loss\n- summary medians for v4/v6 and Δ\n\n### traceroute\n\nBasic:\n- target (hostname)\n\nAdvanced:\n- **Proto:** `icmp` / `udp` / `tcp` (depending on Globalping support)\n- **Port:** for UDP/TCP modes when applicable\n\nOutput:\n- reached/last hop, hop count, and timing summaries (v4 vs v6)\n\n### mtr\n\nBasic:\n- target (hostname)\n\nAdvanced:\n- **Packets/hop:** packets per hop\n\nOutput:\n- loss and latency summaries (v4 vs v6), reached flags\n\n### dns\n\nBasic:\n- target (hostname or IP literal for PTR)\n\nAdvanced:\n- **Query:** record type / query string (as supported by Globalping DNS measurement)\n- **Proto / Port**\n- **Resolver:** optional; empty means probe default resolver\n- **trace:** if enabled, include trace information when supported\n\nOutput:\n- totals (ms) and ratio v6/v4 where applicable\n\n### http\n\nBasic:\n- target (hostname, or a full URL which is split into host/path/query)\n\nAdvanced:\n- **Method**\n- **Proto:** `http` / `https`\n- **Path / Query / Port**\n- **Resolver:** optional; empty means probe default resolver\n\nOutput:\n- status codes and total times (ms), ratio v6/v4 where applicable\n\n## Interpreting results\n\n### winner\nA compact label indicating which stack “wins” for a given probe/summary:\n\n- `v4` / `v6`: lower time (or better outcome) for that probe\n- `tie`: values equal within reported granularity\n- `v4 only` / `v6 only`: only one stack returned a usable result\n\n### Δ v6-v4\n- Positive: v6 slower than v4\n- Negative: v6 faster than v4\n\n### ratio (DNS/HTTP)\nFor commands where ratio is shown:\n- `ratio = v6_total / v4_total`\n- `\u003e 1`: v6 slower\n- `\u003c 1`: v6 faster\n\n## API endpoints\n\nThis repo includes Cloudflare Pages Functions used by the UI:\n\n- `POST /api/measurements-pair`  \n  Creates a v4/v6 measurement pair and validates **Cloudflare Turnstile** server-side.\n\n- `POST /api/globalping/measurements`  \n  Proxy/sanitizer for Globalping create requests (defensive validation/clamping).\n\n- `GET /api/globalping/measurements/:id`  \n  Proxy for reading measurement results.\n\nThere is also an NLNOG Looking Glass proxy endpoint under `functions/api/nlnog/` (currently not exposed in the UI).\n\n## Limitations and notes\n\n- **Globalping availability varies.** Some geos and filters can return “no probes found”.\n- **IPv6-capable probes only** can reduce availability significantly in sparse regions.\n- **The From field is passed through.** If a location string is invalid, Globalping may return validation errors.\n- **Turnstile is enforced for pair creation.** Automated usage without a valid challenge token will fail.\n- **Experimental beta.** Defaults, UI layout, and comparison logic may evolve.\n\n## Development\n\nRequirements:\n- Node.js (the CI uses Node 20)\n\nInstall and run:\n```bash\nnpm ci\nnpm run dev\n```\n\nBuild:\n```bash\nnpm run build\nnpm run preview\n```\n\n### Cloudflare Pages / Functions configuration\n\nThe pair endpoint requires a Turnstile secret configured as an environment variable in Cloudflare:\n\n- `TURNSTILE_SECRET` (Pages environment variable)\n\nThe frontend also needs the corresponding Turnstile site key (as configured in the UI code/deployment). Keep the secret server-side only.\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md).\n\n## Security\n\nSee [SECURITY.md](./SECURITY.md).\n\n## Acknowledgements\n\nping6.it is built on top of the Globalping measurement platform (API + distributed probes).\n\n## License\n\n- Source code: GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later) — see [LICENSE](./LICENSE).\n- Documentation and website content: Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) — see [LICENSE-DOCS](./LICENSE-DOCS).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantonio-prado%2Fping6-it","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantonio-prado%2Fping6-it","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantonio-prado%2Fping6-it/lists"}