[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-82761":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":16,"starSnapshotCount":16,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},82761,"peer.as","Archeb\u002Fpeer.as","Archeb","PEER.AS — explore global BGP routing, IP prefixes, ASNs, AS_PATH, origins and peering.","https:\u002F\u002Fpeer.as",null,"JavaScript",102,9,62,1,0,13,38,4,50.3,false,"main",true,[],"2026-06-12 04:01:38","# PEER.AS\n\n**A static, reproducible explorer for the global IPv4 + IPv6 BGP table** — every prefix,\nits origin ASNs, and the actual **AS_PATH**s that reach it. The whole thing runs in\nyour browser: there is no backend, no API, and no database server. The site is just\na bundle of static files you can host, fork, or mirror anywhere.\n\nLive at **[peer.as](https:\u002F\u002Fpeer.as)**.\n\nIt's a looking-glass-style reference for the routing table, delivered as a\nself-hostable static artifact rather than a hosted service.\n\n---\n\n## The idea: the AS_PATH is the signal\n\nPEER.AS is built on one opinion about public BGP data: **the part worth reading is\nthe AS_PATH** — *which* ASNs carry a prefix, and in *what order*. Everything follows\nfrom that, and it deliberately avoids claims the data can't support:\n\n- **Order and adjacency matter.** Searching `23764 4809` means those two ASNs appear\n  **consecutively** in the path — a different question from \"the path contains both\n  somewhere.\" `1299 23764 4809` and `1299 4809` are genuinely different routes.\n- **No line-quality scoring.** A public collector can't distinguish premium from\n  standard transit (they often share an AS), so PEER.AS shows the path and does not\n  grade it.\n- **Origin AS is display-only.** It labels a prefix; it never drives ranking or\n  filtering.\n- **Multihoming falls out for free.** A collector's RIB is *per-peer*, so the set of\n  distinct paths to a prefix is its observed multihome \u002F equal-cost routing, straight\n  from the data — nothing inferred.\n\n## What you can do\n\n- **Search by AS_PATH** — type a sequence of ASNs and find every prefix whose path\n  contains that **consecutive** run. Supports wildcards (`*` any gap, `?` one hop)\n  and exclusion (`!N` = path must *not* contain ASN N). Works globally or scoped to a\n  country.\n- **Search by origin AS** — exact lookup of everything a given network originates.\n- **IP \u002F CIDR lookup** — enter an IPv4 **or IPv6** address or prefix (e.g.\n  `2001:db8::\u002F32`) and get every covering and more-specific prefix in the table, most-specific first.\n- **Per-prefix insight** — open any prefix for a **route graph** (origin → upstreams\n  → Tier-1) drawn from all observed paths, the **best path** highlighted, and its\n  **parent \u002F child prefixes** found live by numeric range.\n- **Browse by country & city** — prefixes (v4 and v6) are resolved against geo\n  databases and grouped into the regions they cover, **city level worldwide**. Hovering\n  an ASN shows its organization name.\n- **Bilingual (中文 \u002F English)** UI, pre-rendered per-country landing pages, a\n  sitemap, and `?lang` \u002F `?cc` \u002F `?city` deep links.\n- **Smart search box** — one field auto-detects IP \u002F CIDR \u002F ASN \u002F network-name input.\n\n## Static & reproducible\n\nThe dataset is exported to **Parquet** and queried in-browser with **DuckDB-WASM**,\ndirectly against the static files. There is no query server.\n\nHow a query stays cheap: `meta.json` carries compact **interval indexes** (by\ncountry, by origin ASN, by prefix id), so the browser loads only the **few Parquet\nshards a query actually needs** rather than the whole dataset. A country or origin-AS\nlookup typically pulls a few MB out of the ~0.7 GB dataset; a prefix's detail view\nreads one path shard. Pruning is at the **shard** level — DuckDB-WASM fetches each\nneeded shard in full (the files are sized small enough that whole-file downloads beat\nmany small range requests). The one heavy case is an **AS_PATH search with no origin\nfilter**, which has nothing to prune on and scans all path shards.\n\nThat design buys:\n\n- **Serverless & cheap** — deploys to any static host; no compute, no per-query cost.\n- **Reproducible** — data comes from a public source (RIPE RIS `rrc01`+`rrc06` MRT dumps);\n  anyone can re-run the pipeline and rebuild the same site.\n- **Self-hostable & mirrorable** — it's just files, so you can clone it for archival,\n  offline use, or running your own snapshot.\n\n## How it's built\n\n```\nRIPE rrc01 + rrc06 MRT RIBs ──ingest──► DuckDB working store (full v4+v6 table,\n                                  │       distinct paths deduped & merged across collectors)\n                                  └─export-parquet──► Parquet shards + meta.json\n                                                       (geo\u002F\u003Ccc>{,_v6}, prefixes{,_v6},\n                                                        paths{,_v6}, pathsearch{,_v6}) + SSG\n                                                          │\n                                          DuckDB-WASM (browser) ──fetch needed shards──► you\n```\n\n- **Collector** — a streaming MRT parser ingests the latest RIBs from two RIPE RIS\n  collectors (`rrc01` London + `rrc06` Tokyo) and stores every IPv4 **and IPv6** prefix\n  with its distinct AS_PATHs. Nothing is filtered out at ingest; paths are deduped and\n  merged across collectors (peer counts summed).\n- **Export** — the DuckDB store is exported to a Parquet dataset (a separate set of\n  shards per address family), each table sorted by its access key (prefixes by\n  `ip_start`, paths by prefix id, pathsearch by origin ASN) and split into small shards,\n  with interval indexes in `meta.json` so the frontend fetches only the relevant shards.\n  A static-site generator emits per-country pages.\n- **Frontend** — a Vite + Svelte 5 app running DuckDB-WASM against the Parquet files.\n  IPv6 addresses are 128-bit (`UHUGEINT`); range comparisons run in SQL so the browser\n  never loses precision.\n\n**Scale** (per daily `rrc01`+`rrc06` snapshot): **~1.10 M** IPv4 + **~0.26 M** IPv6\nprefixes, **~50 M** distinct AS_PATHs, ~1.7 M path segments, 250 countries — exported to\n**~0.7 GB** Parquet.\n\n### Geolocation: three-way merge\n\nThree geo sources are merged into one **non-overlapping** interval set so every prefix\nresolves cleanly, while the project stays fully open where possible:\n\n- **`ipdb`** — a city-level commercial database (private, **not** redistributable) used\n  by the hosted deployment for **mainland-China** cities (most accurate there).\n- **GeoLite2** — MaxMind's free City DB covers **everywhere else at city level** (v4 and\n  v6), and its ASN DB provides per-ASN **organization** names. Auto-downloaded and\n  refreshed when a new release appears.\n- **`rir`** — RIR delegated-extended stats as an openly-redistributable country-level\n  fallback for anyone rebuilding without the commercial DB.\n\n## Limitations (worth knowing)\n\n- AS_PATHs are the *outbound* view of whichever peers `rrc01`\u002F`rrc06` have; a given\n  network's true vantage is only as complete as those collectors. \"Path contains ASN X\"\n  is the most robust filter (peer-independent); strict ordering depends on the\n  collectors' view.\n- Parent \u002F child segments are computed over **collected** prefixes — a large slice of\n  the table, not a private global RIB — so coverage can be partial (the UI says so).\n- City-level geolocation is only as good as the underlying geo database.\n- An AS_PATH search without an origin filter scans every path shard (~hundreds of MB\n  downloaded); scope it by country or origin AS when you can.\n- This is a research \u002F education tool over a public, approximate snapshot. It can be\n  stale and is **not authoritative for operational decisions**.\n\n## Deploy your own\n\n> 💡 **Fast path — let your agent do it.** This repo is maintained end-to-end by an AI\n> coding agent, and **[`AGENTS.md`](AGENTS.md)** is the authoritative, always-current\n> runbook (exact build steps, Cloudflare Pages \u002F R2 specifics, gotchas, invariants).\n> Open the repo in a coding agent (e.g. Claude Code) and ask it to *\"deploy following\n> AGENTS.md\"* — it will build and push for you. The steps below are the same process\n> by hand.\n\nThe pipeline is a self-contained CLI (`ipc`).\n\n**1. Build the dataset and site**\n\n```bash\npip install -r requirements.txt              # Python deps (DuckDB, maxminddb, MRT parser, …)\n.\u002Fipc geo-import                             # build geo: GeoLite (auto-downloaded, city worldwide) [+ ipdb if present]\n.\u002Fipc ingest --reset                         # download & parse latest rrc01+rrc06 RIBs, full v4+v6 → DuckDB store\n( cd ipcollect\u002Fweb && npm ci && npm run build )   # build the Svelte frontend\n.\u002Fipc export-parquet --out dist              # DuckDB → Parquet(v4+v6) + meta.json + bilingual SSG, into dist\u002F\n```\n(`ingest` also auto-checks GeoLite freshness and rebuilds geo when it changes, so the\nexplicit `geo-import` is only needed for the very first run or a forced refresh.)\n\n`dist\u002F` is now a complete static site (frontend + `dist\u002Fdata\u002F` Parquet + per-country\nSEO pages).\n\n**2a. Host it anywhere (simplest)**\n\n```bash\n.\u002Fipc serve --port 8812                      # local preview of the same artifact\n```\n\nUpload `dist\u002F` to any static host (Cloudflare Pages, Netlify, S3, nginx…). Data is\nserved same-origin from `dist\u002Fdata\u002F`. That's it.\n\n**2b. Geo acceleration via a mirror (what peer.as runs)**\n\nData is served **same-origin** — there's no object-storage split (the in-browser\nDuckDB downloads whole shards, never HTTP Range, so an external data host like R2 adds\negress cost\u002Fabuse risk for no transfer benefit). For users far from Cloudflare's edge\n(e.g. mainland China), the hosted site runs a **second complete copy** of the site on a\nwell-connected VPS (`cn.peer.as`) and uses **GeoDNS** so `peer.as` resolves to that VPS\nwithin the region. The frontend's `configure()` picks the data source by hostname\u002Fgeo\nwith health-checked fallback:\n\n- on the mirror's hostname → same-origin (relative) data + self-hosted DuckDB-WASM;\n- on Cloudflare Pages but detected in-region (GeoDNS missed) → switch data to the mirror\n  (fallback to same-origin Pages + jsDelivr wasm);\n- otherwise → same-origin.\n\nSo both domains are standalone full sites with identical layout. Details + the GeoDNS \u002F\nTLS-cert caveats are in **[`AGENTS.md`](AGENTS.md)**.\n\n**3. Keep it fresh (optional)**\n\n`scripts\u002Fdaily-refresh.sh` chains ingest → export → rsync the full site to the mirror →\n`wrangler pages deploy`; run it from cron (the hosted site refreshes daily). Details in `AGENTS.md`.\n\nConfiguration lives in `config.json` (gitignored; template in `config.example.json`).\nSecrets — Cloudflare credentials, the private geo path, `VITE_DATA_BASE`, `R2_BUCKET`\n— go in `.env` (template `.env.example`) and are never committed.\n\n## Sponsors\n\nServers and infrastructure for the hosted **[peer.as](https:\u002F\u002Fpeer.as)** deployment\nare generously **sponsored by [DMIT](https:\u002F\u002Fwww.dmit.io)**.\n\n[![DMIT](ipcollect\u002Fweb\u002Fpublic\u002Fdmit.svg)](https:\u002F\u002Fwww.dmit.io)\n\n## Project notes\n\n- **Data source:** [RIPE RIS](https:\u002F\u002Fris.ripe.net\u002F) `rrc01` + `rrc06` public MRT RIB dumps.\n- **Changelog:** user-facing changes in **[`CHANGELOG.md`](CHANGELOG.md)** (also in-app).\n- **Maintenance & deployment:** **[`AGENTS.md`](AGENTS.md)** is the authoritative\n  runbook; the DuckDB + IPv6 design\u002Fcontract is in **`docs\u002FDUCKDB_V6_REFACTOR.md`**.\n- For BGP research and education only.\n","PEER.AS 是一个用于探索全球 BGP 路由、IP 前缀、AS 号码、AS_PATH、起源和对等关系的静态可重现浏览器工具。其核心功能包括通过 AS_PATH 搜索前缀、按原点 AS 查找所有相关网络信息以及 IP\u002FCIDR 查询等，支持 IPv4 和 IPv6 地址。项目使用 Python 编写，并基于 DuckDB-WASM 在浏览器中直接查询 Parquet 格式的数据文件，无需后端服务器或数据库支持。PEER.AS 适用于需要详细了解互联网路由结构的研究人员、网络管理员及安全专家，在没有API调用限制的情况下提供了一个强大的自我托管解决方案。",2,"2026-06-11 04:09:09","CREATED_QUERY"]