federationtracker

package
v0.39.0 Latest Latest
Warning

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

Go to latest
Published: Apr 13, 2026 License: GPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package federationtracker provides an in-memory tracker for federation diagnostics. Unlike servertracker (which hashes IPs for privacy), this tracker stores clear-text server domains for administrative diagnosis.

It provides:

  • Per-domain queue counts, failure diagnostics, and latency profiling
  • Thread-safe concurrent access via sync.RWMutex
  • Background periodic flushing to database for restart survival
  • Federation policy enforcement (ACCEPT/REJECT with domain exceptions)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckFederationPolicy

func CheckFederationPolicy(domain string, policy string, localDomain string, getSetting func(string) (string, bool, error)) bool

CheckFederationPolicy evaluates whether communication with the given domain is allowed based on the current policy and exception list.

Returns true if communication should proceed, false if it should be blocked.

Logic:

  • ACCEPT policy: allow all EXCEPT domains in the rules list (blocklist)
  • REJECT policy: deny all EXCEPT domains in the rules list (allowlist)

Domain normalization: IP literals like [1.1.1.1] are stripped of brackets, and all comparisons are case-insensitive.

Types

type FederationRule

type FederationRule struct {
	ID        uint   `gorm:"primaryKey"`
	Domain    string `gorm:"uniqueIndex"`
	CreatedAt int64
}

FederationRule is a domain exception stored in the database. When policy is ACCEPT, rules act as a blocklist. When policy is REJECT, rules act as an allowlist.

type FederationTracker

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

FederationTracker is the in-memory metrics store for federation diagnostics.

func Global

func Global() *FederationTracker

Global returns the singleton FederationTracker. Created on first call.

func (*FederationTracker) DecrementQueue

func (t *FederationTracker) DecrementQueue(domain string)

DecrementQueue subtracts 1 from the queued message count for a domain.

func (*FederationTracker) GetAll

func (t *FederationTracker) GetAll() []ServerStat

GetAll returns a snapshot of all tracked server stats. Mean latency is lazily computed here.

func (*FederationTracker) Hydrate

func (t *FederationTracker) Hydrate(db *gorm.DB)

Hydrate loads persisted stats from the database into memory. Called during server startup to survive restarts.

func (*FederationTracker) IncrementQueue

func (t *FederationTracker) IncrementQueue(domain string)

IncrementQueue adds 1 to the queued message count for a domain.

func (*FederationTracker) RecordFailure

func (t *FederationTracker) RecordFailure(domain, transport string)

RecordFailure records a delivery failure for a domain, classified by transport. transport must be one of "HTTP", "HTTPS", or "SMTP".

func (*FederationTracker) RecordSuccess

func (t *FederationTracker) RecordSuccess(domain string, latencyMs int64, transport string)

RecordSuccess records a successful delivery with the given latency in milliseconds. transport should be "HTTP", "HTTPS", "SMTP", or empty for inbound/unspecified.

func (*FederationTracker) StartFlusher

func (t *FederationTracker) StartFlusher(db *gorm.DB)

StartFlusher begins a background goroutine that periodically persists the in-memory stats to the database using UPSERT (ON CONFLICT DO UPDATE). This mirrors the proven flushMessageCounters() pattern from imapsql.go.

type PolicyStore

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

PolicyStore manages federation policy and domain exceptions. It uses a memory-first architecture: a hot map[string]struct{} guarded by sync.RWMutex is checked on every message — no DB SELECT per delivery.

func GlobalPolicy

func GlobalPolicy() *PolicyStore

GlobalPolicy returns the singleton PolicyStore.

func (*PolicyStore) AddRule

func (p *PolicyStore) AddRule(domain string) (int, error)

AddRule adds a domain exception. Writes to both DB and RAM synchronously. Returns the total count of rules after addition.

func (*PolicyStore) Count

func (p *PolicyStore) Count() int

Count returns the number of active rules.

func (*PolicyStore) FlushRules

func (p *PolicyStore) FlushRules() error

FlushRules removes ALL domain exceptions from both DB and RAM.

func (*PolicyStore) HasRule

func (p *PolicyStore) HasRule(domain string) bool

HasRule checks if a domain is in the exception list (from RAM, no DB hit).

func (*PolicyStore) Init

func (p *PolicyStore) Init(db *gorm.DB)

Init loads persisted federation rules from the database into memory. Must be called once during server startup.

func (*PolicyStore) ListRules

func (p *PolicyStore) ListRules() map[string]int64

ListRules returns all rules as domain -> created_at pairs from RAM.

func (*PolicyStore) RemoveRule

func (p *PolicyStore) RemoveRule(domain string) (int, error)

RemoveRule removes a domain exception from both DB and RAM. Returns the remaining count of rules.

type ServerStat

type ServerStat struct {
	Domain               string `json:"domain" gorm:"primaryKey"`
	QueuedMessages       int64  `json:"queued_messages"`
	FailedHTTP           int64  `json:"failed_http"`
	FailedHTTPS          int64  `json:"failed_https"`
	FailedSMTP           int64  `json:"failed_smtp"`
	SuccessHTTP          int64  `json:"success_http"`
	SuccessHTTPS         int64  `json:"success_https"`
	SuccessSMTP          int64  `json:"success_smtp"`
	SuccessfulDeliveries int64  `json:"successful_deliveries"`
	TotalLatencyMs       int64  `json:"total_latency_ms"`
	LastActive           int64  `json:"last_active"`
}

ServerStat holds per-domain delivery diagnostics.

func (ServerStat) TableName

func (ServerStat) TableName() string

TableName maps to the database table for persistence.

Jump to

Keyboard shortcuts

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