check / check (push) Canceled after 0s
The routing table in memory now holds every route, so the two per-peer route tables go, with every write, delete, count and read that served them. The prefix handler applies each update to the table, writes the table's changes every second, and stores each new prefix with its first-seen time. The peer delete, its retry on the next flush and the updates held for it go too. The types and errors of the server's answers move to internal/server. The image's memory settings fit a full table of about 1 GB: GOMEMLIMIT of 2.5 GiB, a 512 MiB page cache for the writing connection, and SQLite heap limits of 768 MiB and 1 GiB. The README describes the new table, its database copy and the memory budget. Model: opus-5-5
68 lines
2.3 KiB
Go
68 lines
2.3 KiB
Go
package server
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
// ErrInvalidIP says that an IP address is malformed. The IP lookup returns
|
|
// it.
|
|
ErrInvalidIP = errors.New("invalid IP address")
|
|
// ErrNoRoute says that the routing table has no route for an address, a
|
|
// prefix or an AS. The lookups return it.
|
|
ErrNoRoute = errors.New("no route found")
|
|
)
|
|
|
|
// LiveRoute represents a route in the live routing table. JSON leaves out an
|
|
// empty AS path, next hop or time: the routing table in memory keeps them only
|
|
// for the two newest routes of each prefix and origin AS.
|
|
//
|
|
//nolint:tagliatelle // field names are the existing JSON API
|
|
type LiveRoute struct {
|
|
Prefix string `json:"prefix"`
|
|
MaskLength int `json:"mask_length"`
|
|
IPVersion int `json:"ip_version"`
|
|
OriginASN int `json:"origin_asn"`
|
|
PeerIP string `json:"peer_ip"`
|
|
ASPath []int `json:"as_path,omitempty"`
|
|
NextHop string `json:"next_hop,omitempty"`
|
|
LastUpdated time.Time `json:"last_updated,omitzero"`
|
|
}
|
|
|
|
// PrefixDistribution represents the distribution of prefixes by mask length
|
|
//
|
|
//nolint:tagliatelle // field names are the existing JSON API
|
|
type PrefixDistribution struct {
|
|
MaskLength int `json:"mask_length"`
|
|
Count int `json:"count"`
|
|
}
|
|
|
|
// IPInfo represents comprehensive IP information for the /ip endpoint
|
|
//
|
|
//nolint:tagliatelle // field names are the existing JSON API
|
|
type IPInfo struct {
|
|
IP string `json:"ip"`
|
|
Netblock string `json:"netblock"`
|
|
MaskLength int `json:"mask_length"`
|
|
IPVersion int `json:"ip_version"`
|
|
NumPeers int `json:"num_peers"`
|
|
// AS information
|
|
ASN int `json:"asn"`
|
|
ASName string `json:"as_name,omitempty"`
|
|
Handle string `json:"handle,omitempty"`
|
|
Description string `json:"description,omitempty"`
|
|
OrgName string `json:"org_name,omitempty"`
|
|
OrgID string `json:"org_id,omitempty"`
|
|
Address string `json:"address,omitempty"`
|
|
CountryCode string `json:"country_code,omitempty"`
|
|
AbuseEmail string `json:"abuse_email,omitempty"`
|
|
RIR string `json:"rir,omitempty"`
|
|
// Timestamps. LastSeen is zero, and left out of JSON, when the prefix
|
|
// keeps no route.
|
|
FirstSeen time.Time `json:"first_seen"`
|
|
LastSeen time.Time `json:"last_seen,omitzero"`
|
|
// Indicates if WHOIS data needs refresh (not serialized)
|
|
NeedsWHOISRefresh bool `json:"-"`
|
|
}
|