Help us shape the future of Go! Take the 2026 Go Developer Survey

federation

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Index

Constants

View Source
const MinTokenLen = 16

MinTokenLen is the shortest accepted peer token (the peer's RDPANEL_FEDERATION_TOKEN has the same minimum).

Variables

View Source
var ErrNoToken = errors.New("federation: no stored token for this peer")

ErrNoToken means a peer has no stored token (it was registered by a version that kept tokens in memory only): delete and re-add it.

Functions

func HashToken

func HashToken(token string) string

HashToken computes sha256 hex string for the peer auth token.

func NormalizeAPIURL added in v0.11.0

func NormalizeAPIURL(raw string) (string, *url.URL, error)

NormalizeAPIURL validates a peer base URL (http(s)://host[:port][/prefix], no credentials, query or fragment) and trims trailing slashes.

Types

type Config

type Config struct {
	Store        *Store
	Relays       RelaySource
	Version      string
	SyncInterval time.Duration
	Log          *slog.Logger
	// InboundToken is the bearer token peers must present to this panel's
	// federation endpoints (RDPANEL_FEDERATION_TOKEN). Empty refuses all.
	InboundToken string
	// AllowPrivate reports whether peers may live on private, loopback or
	// link-local addresses (the relays "allow private hosts" option).
	// nil: never.
	AllowPrivate func(context.Context) bool
	// HTTPClient overrides the outgoing client (tests). The default refuses
	// private addresses at dial time (unless AllowPrivate), ignores proxy
	// variables and does not follow redirects.
	HTTPClient *http.Client
	// Lookup resolves peer host names for the registration check
	// (default net.DefaultResolver.LookupNetIP).
	Lookup func(ctx context.Context, network, host string) ([]netip.Addr, error)
}

Config configures the federation service.

type CreatePeerInput

type CreatePeerInput struct {
	Name       string
	APIURL     string
	AuthToken  string
	SyncRelays bool
}

CreatePeerInput is input for registering a new peer panel.

type FederatedRelay

type FederatedRelay struct {
	ID         int64     `json:"id"`
	PeerID     int64     `json:"peer_id"`
	PeerName   string    `json:"peer_name,omitempty"`
	RemoteName string    `json:"remote_name"`
	PublicHost string    `json:"public_host"`
	Region     string    `json:"region,omitempty"`
	Health     string    `json:"health"`
	LastSyncAt time.Time `json:"last_sync_at"`
}

FederatedRelay represents a relay announced by a peered RD Panel.

type HealthDTO

type HealthDTO struct {
	Status        string `json:"status"`
	Version       string `json:"version"`
	ActiveRelays  int    `json:"active_relays"`
	TimestampNano int64  `json:"timestamp_nano"`
}

HealthDTO is the response to /api/v1/federation/health.

type Peer

type Peer struct {
	ID         int64      `json:"id"`
	Name       string     `json:"name"`
	APIURL     string     `json:"api_url"`
	TokenHash  string     `json:"-"`
	SyncRelays bool       `json:"sync_relays"`
	Status     PeerStatus `json:"status"`
	LastSyncAt *time.Time `json:"last_sync_at,omitempty"`
	LastError  *string    `json:"last_error,omitempty"`
	CreatedAt  time.Time  `json:"created_at"`
	UpdatedAt  time.Time  `json:"updated_at"`
}

Peer represents an external peered RD Panel instance.

type PeerStatus

type PeerStatus string

PeerStatus is the connection status of a peered RD Panel.

const (
	StatusUnknown PeerStatus = "unknown"
	StatusActive  PeerStatus = "active"
	// StatusUnreachable marks a peer whose last sync failed: unreachable,
	// token rejected, or an invalid answer. Peer.LastError says which.
	StatusUnreachable PeerStatus = "unreachable"
)

type PublicRelayDTO

type PublicRelayDTO struct {
	Name       string `json:"name"`
	PublicHost string `json:"public_host"`
	Region     string `json:"region,omitempty"`
	Health     string `json:"health"`
}

PublicRelayDTO is what a panel announces to peers.

type RelaySource

type RelaySource interface {
	List(ctx context.Context) ([]relays.View, relays.Rotation, error)
}

RelaySource provides active local relays to announce.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service manages federation peering, relay synchronization and public federation endpoints.

func NewService

func NewService(cfg Config) *Service

NewService creates a new federation service.

func (*Service) Authorized added in v0.11.0

func (s *Service) Authorized(r *http.Request) bool

Authorized reports whether r carries this panel's federation token. The comparison is constant-time over SHA-256 digests.

func (*Service) CreatePeer added in v0.11.0

func (s *Service) CreatePeer(ctx context.Context, in CreatePeerInput) (Peer, error)

CreatePeer validates and registers a peer. Unless private peers are allowed, an api_url pointing at a private, loopback or link-local address (literally or via DNS) is refused.

func (*Service) PublicHealth

func (s *Service) PublicHealth(ctx context.Context) HealthDTO

PublicHealth returns local health for peering verification.

func (*Service) PublicRelays

func (s *Service) PublicRelays(ctx context.Context) ([]PublicRelayDTO, error)

PublicRelays returns local active relays for peering peers.

func (*Service) RegisterPublic added in v0.11.0

func (s *Service) RegisterPublic(r chi.Router, limiter auth.Limiter)

RegisterPublic mounts GET /health and GET /relays (under /api/v1/federation). Both require the federation bearer token; failed attempts back off per client IP through limiter (nil: no limit).

func (*Service) Run added in v0.11.0

func (s *Service) Run(ctx context.Context)

Run is the background sync loop (an app worker); it returns when ctx ends.

func (*Service) Store

func (s *Service) Store() *Store

Store returns the underlying store.

func (*Service) SyncAll

func (s *Service) SyncAll(ctx context.Context)

SyncAll passes through all peers and attempts sync.

func (*Service) SyncPeer

func (s *Service) SyncPeer(ctx context.Context, id int64) error

SyncPeer checks a peer's health and, with sync_relays, imports the relays it announces. Any failure (unreachable, non-200, invalid or inconsistent answer) marks the peer unreachable with a short reason; the returned error's text is that reason.

type Store

type Store struct {
	DB *db.DB
	// AEAD seals peer tokens (required by Create and Token).
	AEAD *crypto.AEAD
	Now  func() time.Time
}

Store persists federation peers and announced relays.

The token this panel presents to a peer is needed in plaintext for every sync, so it is kept AEAD-sealed in the panel settings under "federation.peer.<id>.token" (crypto.FederationPeerTokenAD); the federation_peers.token_hash column only holds its SHA-256.

func (*Store) Create

func (s *Store) Create(ctx context.Context, in CreatePeerInput) (Peer, error)

Create registers a new peered panel and stores its token sealed.

func (*Store) Delete

func (s *Store) Delete(ctx context.Context, id int64) error

Delete removes a peer, its stored token and its announced relays (via CASCADE).

func (*Store) Get

func (s *Store) Get(ctx context.Context, id int64) (Peer, error)

Get returns one peer by ID.

func (*Store) List

func (s *Store) List(ctx context.Context) ([]Peer, error)

List returns all registered peers.

func (*Store) ListFederatedRelays

func (s *Store) ListFederatedRelays(ctx context.Context) ([]FederatedRelay, error)

ListFederatedRelays returns all federated relays from all active peers. They are shown for visibility only: nothing adds them to hbbs' rotation.

func (*Store) ReplaceFederatedRelays

func (s *Store) ReplaceFederatedRelays(ctx context.Context, peerID int64, relays []FederatedRelay) error

ReplaceFederatedRelays atomically replaces the relays associated with a peer.

func (*Store) Token added in v0.11.0

func (s *Store) Token(ctx context.Context, id int64) (string, error)

Token returns the token this panel presents to peer id (ErrNoToken when none is stored).

func (*Store) UpdateStatus

func (s *Store) UpdateStatus(ctx context.Context, id int64, status PeerStatus, errMsg *string) error

UpdateStatus records a peer's sync attempt and current connectivity status.

Jump to

Keyboard shortcuts

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