ris

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 19, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Overview

Package ris builds the dispatcher's ASN database from RIPE RIS routing data, the method RIPE Atlas uses for a probe's prefix and ASN: an address belongs to the longest prefix announced in BGP, and to that prefix's origin AS.

The inputs are RIPE RIS's daily whois dumps, which list every (origin, prefix) pair in the combined RIS routing tables with the number of RIS peers that see it, and RIPE's list of AS names. A pair counts when at least MinPeers RIS peers see it; a prefix announced by several origins (MOAS) is attributed to the origin the most peers see, the lowest AS number on a tie.

Index

Constants

View Source
const (
	IPv4DumpURL = "https://www.ris.ripe.net/dumps/riswhoisdump.IPv4.gz"
	IPv6DumpURL = "https://www.ris.ripe.net/dumps/riswhoisdump.IPv6.gz"
	ASNamesURL  = "https://ftp.ripe.net/ripe/asnames/asn.txt"

	// DefaultMaxAge refuses dumps RIS has not regenerated for three days.
	DefaultMaxAge = 72 * time.Hour
)

The published inputs.

View Source
const (
	// DefaultMinPeers is the visibility threshold: the number of RIS peers
	// that must see an (origin, prefix) pair. RIS has several hundred
	// full-table peers, so ten is a small fraction that still drops
	// prefixes only a handful of peers see: leaks, transient more-specifics
	// and peers' internal or default routes.
	DefaultMinPeers = 10

	// Minimum sizes of a usable build. Today's tables are roughly twice as
	// large; a smaller result means truncated or garbled input, or a
	// threshold that discards most of the table, and is refused.
	MinIPv4Prefixes = 500_000
	MinIPv6Prefixes = 100_000
	MinASNames      = 50_000
)
View Source
const DatabaseType = "Debuglet-RIS-ASN"

DatabaseType names the database in its metadata, and so in the database:<type>@<build_epoch> source of every value looked up in it.

Variables

This section is empty.

Functions

func ParseASNames

func ParseASNames(r io.Reader) (map[uint32]string, error)

ParseASNames reads RIPE's asn.txt: one "<number> <name>" per line. A name that is not printable text is dropped, leaving the AS unnamed; a name longer than the 128 characters the dispatcher accepts is shortened.

func PublicASN

func PublicASN(n uint32) bool

PublicASN reports whether n is outside the AS numbers IANA reserves for private use, documentation, AS_TRANS and future use.

func Select

func Select(rows []Row, minPeers int) ([]Route, Stats)

Select keeps the (origin, prefix) pairs at least minPeers RIS peers see, whose origin is a public AS and whose prefix is global unicast, and attributes each prefix to one origin: the one the most peers see, the lowest AS number on a tie. The result is sorted by prefix length, then address.

func Verify

func Verify(path string, routes []Route, names map[uint32]string, buildEpoch int64) error

Verify opens path with the dispatcher's own loader and looks up the first address of every route. Each must resolve to a selected route at least as specific as the one looked up, with that route's origin and name, under this build's source. It is the check a file passes before it replaces the database in use.

func Write

func Write(w io.Writer, routes []Route, names map[uint32]string, buildEpoch int64, minPeers int) error

Write encodes routes as an MMDB in the GeoIP2-ASN-compatible layout the dispatcher reads: autonomous_system_number and, when RIPE lists a name, autonomous_system_organization. announced_prefix_length records the length of the announced prefix, which a more-specific prefix carved out of it would otherwise hide. routes must be sorted by prefix length, as Select returns them, so that a more-specific prefix replaces its covering one.

Types

type Dump

type Dump struct {
	Generated time.Time
	Rows      []Row
}

Dump is one parsed RIS whois dump.

func ParseDump

func ParseDump(r io.Reader, ipv6 bool) (Dump, error)

ParseDump reads a decompressed riswhoisdump file of one address family. It refuses a file without its generation time or end marker, and any line it cannot read, rather than build from part of a table.

type Options

type Options struct {
	Output   string // the database path the dispatcher reads
	MinPeers int
	MaxAge   time.Duration

	// Minimum sizes of a usable build; zero selects MinIPv4Prefixes,
	// MinIPv6Prefixes and MinASNames.
	MinIPv4, MinIPv6, MinNames int

	IPv4URL, IPv6URL, ASNamesURL string
	Client                       *http.Client
	Now                          func() time.Time
}

Options configures Build. Zero values select the defaults.

type Route

type Route struct {
	Prefix netip.Prefix
	Origin uint32
}

Route is a selected prefix and the origin it is attributed to.

type Row

type Row struct {
	Origin uint32
	Prefix netip.Prefix
	Peers  int
}

Row is one line of a RIS whois dump. Origin is 0 for an AS set with more than one member, whose origin is ambiguous.

type Stats

type Stats struct {
	Rows, BelowThreshold, ASSets, ReservedOrigin, Unroutable int
	IPv4, IPv6, MOAS                                         int
}

Stats counts what Select kept and why it discarded rows.

type Summary

type Summary struct {
	Source    string // database:<type>@<epoch> of the database now at Output
	Replaced  bool   // false when Output already held this build or a newer one
	Generated time.Time
	Stats     Stats
	ASNames   int
}

Summary describes a build.

func Build

func Build(ctx context.Context, opts Options) (Summary, error)

Build downloads the RIS dumps and AS names, selects routes, writes the database to a staging file next to Output, verifies it with the dispatcher's own loader and renames it over Output. Output is replaced only by a complete, verified file and never by an older build. The build epoch is the generation time of the older of the two dumps, so a rebuild from the same dumps yields the same source.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL