tdns

package module
v2.0.0-...-f233696 Latest Latest
Warning

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

Go to latest
Published: Jan 25, 2026 License: BSD-2-Clause Imports: 57 Imported by: 0

Documentation

Overview

* Copyright (c) 2025 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) Johan Stenstam, <[email protected]>

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) Johan Stenstam, [email protected]

* Copyright (c) Johan Stenstam, [email protected]

* Copyright (c) Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) Johan Stenstam, [email protected]

* Copyright (c) Johan Stenstam, [email protected]

* Copyright (c) Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam

* Copyright (c) Johan Stenstam, [email protected]

* Copyright (c) Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2025 Johan Stenstam, [email protected]

* Copyright (c) 2025 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Transport signal synthesis (SVCB / TSYNC)

* Copyright (c) 2025 Johan Stenstam

* Copyright (c) DNS TAPIR

* Copyright (c) 2024 Johan Stenstam, [email protected]

* Copyright (c) 2024 Johan Stenstam, [email protected]

Index

Constants

View Source
const (
	MsgAccept               dns.MsgAcceptAction = iota // Accept the message
	MsgReject                                          // Reject the message with a RcodeFormatError
	MsgIgnore                                          // Ignore the error and send nothing back.
	MsgRejectNotImplemented                            // Reject the message with a RcodeNotImplemented
)

Allowed returned values from a MsgAcceptFunc.

View Source
const (
	// DNS limitations
	MaxDomainLength = 253 // Maximum length of a domain name (RFC 1035)
	MaxLabelLength  = 63  // Maximum length of a single label (RFC 1035)

	// Default cookie for chunk identification
	DefaultCookie = "c0"

	// Sequence number format (e.g., "00-")
	SequenceFormat = "%02d-"
	SequenceLength = 3 // XX- is 3 characters
)
View Source
const (
	DogCfgFile = "/etc/axfr.net/dog.yaml"

	// Legacy constants for backward compatibility
	// New code should use GetDefaultConfigFile() instead
	DefaultCliCfgFile = "/etc/tdns/tdns-cli.yaml"
	DefaultImrCfgFile = "/etc/tdns/tdns-imr.yaml"

	DefaultAuthCfgFile = "/etc/tdns/tdns-auth.yaml"

	DefaultAgentCfgFile    = "/etc/tdns/tdns-agent.yaml"
	DefaultCombinerCfgFile = "/etc/tdns/tdns-combiner.yaml"
	DefaultReporterCfgFile = "/etc/tdns/tdns-reporter.yaml"
	DefaultScannerCfgFile  = "/etc/tdns/tdns-scanner.yaml"
	DefaultKdcCfgFile      = "/etc/tdns/tdns-kdc.yaml"
	DefaultKrsCfgFile      = "/etc/tdns/tdns-krs.yaml"
)
View Source
const (
	UpdateModeReplace = "replace" // Replace all existing delegation data with new data
	UpdateModeDelta   = "delta"   // Use incremental adds/removes (delta updates)
)

Update mode constants for parent delegation updates

View Source
const (
	Sig0StateCreated     string = "created"
	Sig0StatePublished   string = "published"
	Sig0StateActive      string = "active"
	Sig0StateRetired     string = "retired"
	DnskeyStateCreated   string = "created"
	DnskeyStatePublished string = "published"
	DnskeyStateActive    string = "active"
	DnskeyStateRetired   string = "retired"
)
View Source
const (
	SvcbTransportKey uint16 = 65280
	SvcbTLSAKey      uint16 = 65281
)

Private-use SVCB key codes for TDNS. RFC 9460 reserves 65280–65534 for local assignments.

View Source
const (
	TimeLayout = "2006-01-02 15:04:05"
)

Variables

View Source
var AgentMsgToString = map[AgentMsg]string{
	AgentMsgHello:  "HELLO",
	AgentMsgBeat:   "BEAT",
	AgentMsgNotify: "NOTIFY",
	AgentMsgRfi:    "RFI",
	AgentMsgStatus: "STATUS",
}
View Source
var AgentStateToString = map[AgentState]string{
	AgentStateNeeded:      "NEEDED",
	AgentStateKnown:       "KNOWN",
	AgentStateIntroduced:  "INTRODUCED",
	AgentStateOperational: "OPERATIONAL",
	AgentStateDegraded:    "DEGRADED",
	AgentStateInterrupted: "INTERRUPTED",
	AgentStateError:       "ERROR",
}
View Source
var AllowedLocalRRtypes = map[uint16]bool{
	dns.TypeDNSKEY: true,
	dns.TypeCDS:    true,
	dns.TypeCSYNC:  true,
	dns.TypeNS:     true,
}
View Source
var AppTypeToString = map[AppType]string{
	AppTypeAuth:       "auth",
	AppTypeAgent:      "agent",
	AppTypeCombiner:   "combiner",
	AppTypeImr:        "imr",
	AppTypeCli:        "cli",
	AppTypeReporter:   "reporter",
	AppTypeScanner:    "scanner",
	AppTypeKdc:        "kdc",
	AppTypeKrs:        "krs",
	AppTypeEdgeSigner: "edgeSigner",
}
View Source
var AuthOptionToString = map[AuthOption]string{
	AuthOptParentUpdate: "parent-update",
}
View Source
var DefaultTables = map[string]string{

	"ChildDnskeys": `CREATE TABLE IF NOT EXISTS 'ChildDnskeys' (
id		  INTEGER PRIMARY KEY,
parent	  TEXT,
child	  TEXT,
keyid	  INTEGER,
trusted	  INTEGER,
keyrr	  TEXT,
comment	  TEXT,
UNIQUE (parent, child, keyid)
)`,

	"ChildDelegationData": `CREATE TABLE IF NOT EXISTS 'ChildDelegationData' (
id		  INTEGER PRIMARY KEY,
parent	  TEXT,
child	  TEXT,
owner	  TEXT,
rrtype	  TEXT,
rr		  TEXT,
UNIQUE (owner,rr)
)`,

	"Sig0TrustStore": `CREATE TABLE IF NOT EXISTS 'Sig0TrustStore' (
id		  		  INTEGER PRIMARY KEY,
zonename	  	  TEXT,
keyid		      INTEGER,
validated	      INTEGER DEFAULT 0,
trusted		      INTEGER DEFAULT 0,
dnssecvalidated	  INTEGER DEFAULT 0,
source		      TEXT,
keyrr		      TEXT,
comment		      TEXT,
UNIQUE (zonename, keyid)
)`,

	"Sig0KeyStore": `CREATE TABLE IF NOT EXISTS 'Sig0KeyStore' (
id		  INTEGER PRIMARY KEY,
zonename	  TEXT,
state		  TEXT,
keyid		  INTEGER,
algorithm	  TEXT,
creator	  	  TEXT,
privatekey	  TEXT,
keyrr		  TEXT,
comment		  TEXT,
UNIQUE (zonename, keyid)
)`,

	"DnssecKeyStore": `CREATE TABLE IF NOT EXISTS 'DnssecKeyStore' (
id		  INTEGER PRIMARY KEY,
zonename	  TEXT,
state		  TEXT,
keyid		  INTEGER,
flags		  INTEGER,
algorithm	  TEXT,
creator	  	  TEXT,
privatekey	  TEXT,
keyrr		  TEXT,
comment		  TEXT,
UNIQUE (zonename, keyid)
)`,
}
View Source
var ErrNotHandled = errors.New("query not handled by this handler")

ErrNotHandled is returned by query/notify handlers to indicate they don't handle this request. TDNS will try the next handler or fall back to the default handler.

View Source
var ErrorTypeToString = map[ErrorType]string{
	ConfigError:  "config",
	RefreshError: "refresh",
	AgentError:   "agent",
	DnssecError:  "DNSSEC",
}
View Source
var Globals = GlobalStuff{

	Verbose:    false,
	Debug:      false,
	ApiClients: map[string]*ApiClient{},
}
View Source
var ImrOptionToString = map[ImrOption]string{
	ImrOptRevalidateNS:            "revalidate-ns",
	ImrOptQueryForTransport:       "query-for-transport",
	ImrOptAlwaysQueryForTransport: "always-query-for-transport",
	ImrOptTransportSignalType:     "transport-signal-type",
	ImrOptQueryForTransportTLSA:   "query-for-transport-tlsa",
	ImrOptUseTransportSignals:     "use-transport-signals",
}
View Source
var KnownCsyncMinSOAs = map[string]uint32{}

Check the minsoa in this CSYNC against the minsoa in the possible already stored CSYNC in the CsyncStatus table. If not found or old min_soa is lower, then update table.

View Source
var ScanTypeToString = map[ScanType]string{
	ScanRRtype: "rrtype",
	ScanCDS:    "cds",
	ScanCSYNC:  "csync",
	ScanDNSKEY: "dnskey",
}
View Source
var ServerName string = "PLACEHOLDER"
View Source
var StringToAppType = map[string]AppType{
	"auth":       AppTypeAuth,
	"agent":      AppTypeAgent,
	"combiner":   AppTypeCombiner,
	"imr":        AppTypeImr,
	"cli":        AppTypeCli,
	"reporter":   AppTypeReporter,
	"scanner":    AppTypeScanner,
	"kdc":        AppTypeKdc,
	"krs":        AppTypeKrs,
	"edgeSigner": AppTypeEdgeSigner,
}
View Source
var StringToAuthOption = map[string]AuthOption{
	"parent-update": AuthOptParentUpdate,
}
View Source
var StringToImrOption = map[string]ImrOption{
	"revalidate-ns":              ImrOptRevalidateNS,
	"query-for-transport":        ImrOptQueryForTransport,
	"always-query-for-transport": ImrOptAlwaysQueryForTransport,
	"transport-signal-type":      ImrOptTransportSignalType,
	"query-for-transport-tlsa":   ImrOptQueryForTransportTLSA,
	"use-transport-signals":      ImrOptUseTransportSignals,
}
View Source
var StringToScanType = map[string]ScanType{
	"rrtype": ScanRRtype,
	"cds":    ScanCDS,
	"csync":  ScanCSYNC,
	"dnskey": ScanDNSKEY,
}
View Source
var StringToZoneOption = map[string]ZoneOption{
	"delegation-sync-parent":     OptDelSyncParent,
	"delegation-sync-child":      OptDelSyncChild,
	"allow-updates":              OptAllowUpdates,
	"allow-child-updates":        OptAllowChildUpdates,
	"allow-combine":              OptAllowCombine,
	"fold-case":                  OptFoldCase,
	"black-lies":                 OptBlackLies,
	"dont-publish-key":           OptDontPublishKey,
	"online-signing":             OptOnlineSigning,
	"multisigner":                OptMultiSigner,
	"dirty":                      OptDirty,
	"frozen":                     OptFrozen,
	"automatic-zone":             OptAutomaticZone,
	"add-transport-signal":       OptAddTransportSignal,
	"catalog-zone":               OptCatalogZone,
	"catalog-member-auto-create": OptCatalogMemberAutoCreate,
	"catalog-member-auto-delete": OptCatalogMemberAutoDelete,
}
View Source
var Templates = make(map[string]ZoneConf)

Add near the top of the file with other vars

View Source
var ZoneOptionToString = map[ZoneOption]string{
	OptDelSyncParent:     "delegation-sync-parent",
	OptDelSyncChild:      "delegation-sync-child",
	OptAllowUpdates:      "allow-updates",
	OptAllowChildUpdates: "allow-child-updates",
	OptAllowCombine:      "allow-combine",
	OptFoldCase:          "fold-case",
	OptBlackLies:         "black-lies",
	OptDontPublishKey:    "dont-publish-key",
	OptOnlineSigning:     "online-signing",
	OptMultiSigner:       "multisigner",
	OptDirty:             "dirty",
	OptFrozen:            "frozen",
	OptAutomaticZone:     "automatic-zone",

	OptAddTransportSignal:      "add-transport-signal",
	OptCatalogZone:             "catalog-zone",
	OptCatalogMemberAutoCreate: "catalog-member-auto-create",
	OptCatalogMemberAutoDelete: "catalog-member-auto-delete",
}
View Source
var ZoneStoreToString = map[ZoneStore]string{
	XfrZone:   "XfrZone",
	MapZone:   "MapZone",
	SliceZone: "SliceZone",
}
View Source
var ZoneTypeToString = map[ZoneType]string{
	Primary:   "primary",
	Secondary: "secondary",
}
View Source
var Zones = cmap.New[*ZoneData]()

Functions

func APICatalog

func APICatalog(app *AppDetails) func(w http.ResponseWriter, r *http.Request)

APICatalog handles catalog zone management operations

func APIcombiner

func APIcombiner(app *AppDetails, refreshZoneCh chan<- ZoneRefresher, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)

func APIcommand

func APIcommand(conf *Config, rtr *mux.Router) func(w http.ResponseWriter, r *http.Request)

func APIcommand(stopCh chan struct{}) func(w http.ResponseWriter, r *http.Request) {

func APIconfig

func APIconfig(conf *Config) func(w http.ResponseWriter, r *http.Request)

func APIdebug

func APIdebug(conf *Config) func(w http.ResponseWriter, r *http.Request)

func APIdelegation

func APIdelegation(delsyncq chan DelegationSyncRequest) func(w http.ResponseWriter, r *http.Request)

func APIdispatcher

func APIdispatcher(conf *Config, router *mux.Router, done <-chan struct{}) error

func APIdispatcherNG

func APIdispatcherNG(conf *Config, router *mux.Router, addrs []string, certFile string, keyFile string, done <-chan struct{}) error

APIdispatcherNG differs from APIdispatcher in that it allows for a different set of addresses and certificate files to be used for the API server.

func APImultisigner

func APImultisigner(kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)

func APIping

func APIping(conf *Config) func(w http.ResponseWriter, r *http.Request)

func APIscanner

func APIscanner(conf *Config, app *AppDetails, scannerq chan ScanRequest, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)

func APIscannerDelete

func APIscannerDelete(conf *Config) func(w http.ResponseWriter, r *http.Request)

APIscannerDelete handles DELETE requests for scan job deletion

func APIscannerStatus

func APIscannerStatus(conf *Config) func(w http.ResponseWriter, r *http.Request)

APIscannerStatus handles GET requests for scan job status

func APIzone

func APIzone(app *AppDetails, refreshq chan ZoneRefresher, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)

func APIzoneDsync

func APIzoneDsync(ctx context.Context, app *AppDetails, refreshq chan ZoneRefresher, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)

func AgentToString

func AgentToString(a *Agent) string

func AuthDNSQuery

func AuthDNSQuery(qname string, lg *log.Logger, nameservers []string,
	rrtype uint16, verbose bool) (*core.RRset, int, error)

XXX: Do we still use this anywhere?

func AuthQuery

func AuthQuery(qname, ns string, rrtype uint16) ([]dns.RR, error)

func AuthQueryEngine

func AuthQueryEngine(ctx context.Context, requests chan AuthQueryRequest)

func AutoConfigureZonesFromCatalog

func AutoConfigureZonesFromCatalog(ctx context.Context, update *CatalogZoneUpdate, conf *Config) error

AutoConfigureZonesFromCatalog auto-configures zones based on catalog and meta groups

func BailiwickNS

func BailiwickNS(zonename string, nsrrs []dns.RR) ([]string, error)

Return the names of NS RRs that are in bailiwick for the zone.

func Base32Decode

func Base32Decode(data string) ([]byte, error)

Base32Decode decodes base32 data

func Base32Encode

func Base32Encode(data []byte) string

Base32Encode encodes data to base32

func CaseFoldContains

func CaseFoldContains(slice []string, str string) bool

func ChildDelegationDataUnsynched

func ChildDelegationDataUnsynched(zone, pzone, childpri, parpri string) (bool, []dns.RR, []dns.RR, error)

func ChildGlueRRsToAddrs

func ChildGlueRRsToAddrs(v4glue, v6glue []dns.RR) ([]string, error)

func ChildGlueRRsetsToAddrs

func ChildGlueRRsetsToAddrs(v4glue, v6glue []*core.RRset) ([]string, error)

func Chomp

func Chomp(s string) string

func ChunkBase32Data

func ChunkBase32Data(base32Data string, cookie string) []string

ChunkBase32Data splits base32 data into chunks of maximum size and adds cookie and sequence prefixes

func ChunksToDomains

func ChunksToDomains(chunks []string, domainSuffix string) []string

ChunksToDomains combines chunks into domain names It dynamically calculates how many chunks can fit in each domain

func ComputeBailiwickNS

func ComputeBailiwickNS(childpri, parpri, owner string) ([]string, []string)

XXX: Should be replaced by four calls: one per child and parent primary to get

the NS RRsets and one to new ComputeBailiwickNS() that takes a []dns.RR + zone name

func ComputeDo53Remainder

func ComputeDo53Remainder(pct map[string]uint8) uint8

ComputeDo53Remainder returns the implicit remainder for do53 (clip at 0).

func ComputeRRDiff

func ComputeRRDiff(childpri, parpri, owner string, rrtype uint16) (bool, []dns.RR, []dns.RR)

Only used in the CLI version

func CopyFile

func CopyFile(src, dst string) (int64, error)

func CreateChildReplaceUpdate

func CreateChildReplaceUpdate(parent, child string, newNS, newA, newAAAA []dns.RR) (*dns.Msg, error)

CreateChildReplaceUpdate creates a DNS UPDATE message that replaces all delegation data CreateChildReplaceUpdate creates a DNS UPDATE message for parent that replaces the delegation for child. It removes all existing NS records for the child and deletes A/AAAA glue for any in-bailiwick nameservers discovered among the provided new NS, A, and AAAA records, then inserts the new NS and glue RRs. Returns an error if parent or child is empty or equal to ".".

func CreateChildUpdate

func CreateChildUpdate(parent, child string, adds, removes []dns.RR) (*dns.Msg, error)

Parent is the zone to apply the update to. XXX: This is to focused on creating updates for child delegation info. Need a more general CreateChildUpdate constructs a DNS UPDATE message for the given parent zone that applies the provided additions and removals for a child delegation.

If any removed RR is an NS whose target name is within the child zone, the function also removes A and AAAA glue RRsets for that NS name. It validates that parent and child are non-empty and not ".", returning an error when validation fails. When Globals.Debug is set, the resulting message is printed.

It returns the constructed DNS UPDATE message, or an error if validation fails.

func CreateUpdate

func CreateUpdate(zone string, adds, removes []dns.RR) (*dns.Msg, error)

CreateUpdate creates a DNS UPDATE message for the given zone, applies the provided removals and additions, and enables EDNS0 (payload 1232 with the DO bit set) so that EDNS0 Extended DNS Error (EDE) information can be returned. It returns the constructed *dns.Msg, or an error if the zone is empty or ".".

func DefaultQueryHandler

func DefaultQueryHandler(ctx context.Context, req *DnsQueryRequest) error

DefaultQueryHandler handles all other queries using zone-based query handling. This is registered with qtype=0 to catch all query types that aren't handled by other handlers. Exported so apps (like KDC) can register it even when no zones are in config.

func DnsDoHEngine

func DnsDoHEngine(ctx context.Context, conf *Config, dohaddrs []string, certFile, keyFile string,
	ourDNSHandler func(w dns.ResponseWriter, r *dns.Msg)) error

func DnsDoQEngine

func DnsDoQEngine(ctx context.Context, conf *Config, doqaddrs []string, cert *tls.Certificate,
	ourDNSHandler func(w dns.ResponseWriter, r *dns.Msg)) error

func DnsDoTEngine

func DnsDoTEngine(ctx context.Context, conf *Config, dotaddrs []string, cert *tls.Certificate,
	ourDNSHandler func(w dns.ResponseWriter, r *dns.Msg)) error

func DnsEngine

func DnsEngine(ctx context.Context, conf *Config) error

func DomainsToBase32

func DomainsToBase32(domains []string, cookie string) (string, error)

DomainsToBase32 extracts and combines base32 data from domain names

func DomainsToJson

func DomainsToJson(domains []string, cookie string) ([]byte, error)

DomainsToJson converts domain names back to JSON

func DomainsToStruct

func DomainsToStruct(domains []string, cookie string, result interface{}) error

DomainsToStruct converts domain names back to a struct

func DotServerQnameResponse

func DotServerQnameResponse(qname string, w dns.ResponseWriter, r *dns.Msg)

func ExpirationFromTtl

func ExpirationFromTtl(addedAt time.Time, ttl uint32) time.Time

ExpirationFromTtl converts an insertion time and TTL seconds to an expiration time. This is only used for formatting and display, not for cache logic.

func FetchSVCB

func FetchSVCB(baseurl string, resolvers []string, timeout time.Duration,
	retries int) (*dns.SVCB, []string, uint16, string, error)

func FindSoaRefresh

func FindSoaRefresh(zd *ZoneData) (uint32, error)

func GenerateJobID

func GenerateJobID() string

GenerateJobID generates a unique job ID

func GetAlpn

func GetAlpn(svcb *dns.SVCB) []string

GetAlpn extracts the ALPN protocols from an SVCB RR (from SVCBAlpn param).

func GetDefaultConfigFile

func GetDefaultConfigFile() string

GetDefaultConfigFile returns the default config file path based on Globals.App.Name. The path is constructed as /etc/tdns/{app-name}.yaml. If Globals.App.Name is empty, it returns an empty string.

func GetDynamicZoneFilePath

func GetDynamicZoneFilePath(zoneName, zoneDirectory string) string

GetDynamicZoneFilePath returns the expected file path for a dynamic zone file This is useful for checking if a file exists before attempting to load it

func GetNameservers

func GetNameservers(KeyName string, zd *ZoneData) ([]string, error)

func GetTransportParam

func GetTransportParam(svcb *dns.SVCB) (map[string]uint8, bool, error)

GetTransportParam fetches and parses the transport parameter from the SVCB RR, if present.

func HsyncEngine

func HsyncEngine(ctx context.Context, conf *Config, agentQs *AgentQs)

func InBailiwick

func InBailiwick(zone string, ns *dns.NS) bool

func IsIxfr

func IsIxfr(rrs []dns.RR) bool

func IsPEMFormat

func IsPEMFormat(keyData string) bool

IsPEMFormat detects if a stored private key is in PKCS#8 PEM format (new format). It returns true if the data decodes to a PEM block of type "PRIVATE KEY"; otherwise false.

func JsonToBase32Domains

func JsonToBase32Domains(jsonData []byte, domainSuffix string, cookie string) ([]string, error)

JsonToBase32Domains converts JSON data to a set of domain names Each domain name contains chunks of base32-encoded data with maximized label sizes

func LookupSVCB

func LookupSVCB(name string) (*core.RRset, error)

func LookupTlsaRR

func LookupTlsaRR(name string) (*core.RRset, error)

func MarshalTLSAToString

func MarshalTLSAToString(tlsa *dns.TLSA) (string, error)

MarshalTLSAToString renders a TLSA record to the "usage selector matching data" representation.

func MarshalTransport

func MarshalTransport(transports map[string]uint8) string

MarshalTransport converts a transport map back to a canonical string (sorted by key).

func MsgAcceptFunc

func MsgAcceptFunc(dh dns.Header) dns.MsgAcceptAction

func MsgPrint

func MsgPrint(m *dns.Msg, server string, elapsed time.Duration, short bool, options map[string]string)

func NSInBailiwick

func NSInBailiwick(zone string, ns *dns.NS) bool

func NeedsResigning

func NeedsResigning(rrsig *dns.RRSIG) bool

XXX: Perhaps a working algorithm woul be to test for the remaining signature lifetime to be something like

less than 3 x resigning interval?

func Notifier

func Notifier(ctx context.Context, notifyreqQ chan NotifyRequest) error

XXX: The whole point with the NotifierEngine is to be able to control the max rate of send notifications per zone. This is not yet implemented, but this is where to do it.

func NotifyCatalogZoneUpdate

func NotifyCatalogZoneUpdate(update *CatalogZoneUpdate) error

NotifyCatalogZoneUpdate invokes all registered callbacks

func NotifyHandler

func NotifyHandler(ctx context.Context, conf *Config) error

func NotifyHandlerWithCallback

func NotifyHandlerWithCallback(ctx context.Context, conf *Config, handlerFunc func(context.Context, *DnsNotifyRequest) error) error

NotifyHandlerWithCallback consumes DnsNotifyRequest messages from the DnsNotifyQ channel and calls the provided handler function. This allows custom NOTIFY handlers (like KDC for confirmation NOTIFYs) to process NOTIFYs via channels. handlerFunc: Function that processes a DnsNotifyRequest

func NotifyReporter

func NotifyReporter(conf *Config, tsigSecrets map[string]string, addr string) (stop func(context.Context) error, err error)

func NotifyResponder

func NotifyResponder(ctx context.Context, dnr *DnsNotifyRequest, zonech chan ZoneRefresher, scannerq chan ScanRequest, imr *Imr) error

func PEMToPrivateKey

func PEMToPrivateKey(pemData string) (crypto.PrivateKey, error)

PEMToPrivateKey parses pemData as a PKCS#8 PEM-encoded private key and returns it as a crypto.PrivateKey.

The input must contain a PEM block of type "PRIVATE KEY" encoded in PKCS#8. Returns an error if the input PEMToPrivateKey parses a PKCS#8 PEM-encoded private key and returns the corresponding crypto.PrivateKey. It returns an error if pemData is empty, if no PEM block can be decoded, if the PEM block type is not "PRIVATE KEY", or if PKCS#8 parsing fails.

func ParsePrivateKeyFromDB

func ParsePrivateKeyFromDB(privatekey, algorithm, keyrrstr string) (crypto.PrivateKey, uint8, string, error)

ParsePrivateKeyFromDB parses a private key from the database, detecting whether it's in old BIND format or new PEM format, and returns a crypto.PrivateKey. ParsePrivateKeyFromDB parses a private key stored in the database, accepting either PKCS#8 PEM (new) or legacy BIND private-key formats.

It returns the parsed crypto.PrivateKey, the DNSSEC algorithm numeric code, and a BIND-format private-key string suitable for backward compatibility. An error is ParsePrivateKeyFromDB parses a stored private key (either PKCS#8 PEM or legacy BIND format) and returns the crypto.PrivateKey, the DNSSEC algorithm numeric code, and a BIND-format private-key string suitable for use with PrepareKeyCache.

If the input `privatekey` is detected as a PKCS#8 PEM, the function parses it and derives a BIND-format private-key string from `keyrrstr` (a DNSKEY/KEY RR string) for compatibility. If `privatekey` is not PEM, it is treated as the legacy BIND private-key material and is wrapped into a full BIND-format string. The `algorithm` parameter is validated and converted to the corresponding DNSSEC algorithm code.

Returns an error if the algorithm is unknown, PEM decoding/parsing fails, the public key RR cannot be parsed, conversion to BIND format fails, or the legacy BIND parsing logic fails.

func ParseTLSAFromSvcbLocal

func ParseTLSAFromSvcbLocal(local *dns.SVCBLocal) (*dns.TLSA, error)

ParseTLSAFromSvcbLocal parses a private SVCB TLSA key into a dns.TLSA.

func ParseTLSAString

func ParseTLSAString(s string) (*dns.TLSA, error)

ParseTLSAString parses a TLSA RDATA string of the form "usage selector matching data".

func ParseTsigKeys

func ParseTsigKeys(keyconf *KeyConf) (int, map[string]string)

ParseTsigKeys parses the TSIG keys from the configuration and returns the number of keys and the secrets in the format expected by the dns.Server and the dns.Client. It also stores the keys with more details in the tdns.Globals struct.

func PrintDsRR

func PrintDsRR(rr dns.RR, leftpad, rightmargin int)

func PrintGenericRR

func PrintGenericRR(rr dns.RR, leftpad, rightmargin int)

func PrintKeyRR

func PrintKeyRR(rr dns.RR, rrtype, ktype string, keyid uint16, leftpad, rightmargin int)

leftpad = amount of white space instead of the domain name on continuation lines during multiline output

func PrintMsgFull

func PrintMsgFull(m *dns.Msg, width int) string

func PrintMsgSection

func PrintMsgSection(header string, section []dns.RR, width int) string

func PrintRR

func PrintRR(rr dns.RR, leftpad int, options map[string]string) error

func PrintRrsigRR

func PrintRrsigRR(rr dns.RR, leftpad, rightmargin int)

func PrintSoaRR

func PrintSoaRR(rr dns.RR, leftpad, rightmargin int)

func PrintSvcbRR

func PrintSvcbRR(rr dns.RR, leftpad, rightmargin int)

func PrivKeyToBindFormat

func PrivKeyToBindFormat(privkey, algorithm string) (string, error)

func PrivateKeyToPEM

func PrivateKeyToPEM(privkey crypto.PrivateKey) (string, error)

PrivateKeyToPEM converts a crypto.PrivateKey to PKCS#8 PEM format. PrivateKeyToPEM converts a crypto.PrivateKey to a PKCS#8 PEM-encoded string. PrivateKeyToPEM converts a crypto.PrivateKey into a PKCS#8 PEM-encoded string.

It returns the PEM-formatted private key. An error is returned if the provided private key is nil or if marshaling the key to PKCS#8 DER fails.

func QueryHandler

func QueryHandler(ctx context.Context, conf *Config, handlerFunc func(context.Context, *DnsQueryRequest) error) error

QueryHandler consumes DnsQueryRequest messages from the DnsQueryQ channel and calls the provided handler function. This allows custom query handlers (like KDC for KMREQ queries) to process queries via channels. handlerFunc: Function that processes a DnsQueryRequest

func RRsetToString

func RRsetToString(rrset *core.RRset) string

func ReadPubKey

func ReadPubKey(filename string) (dns.RR, uint16, uint8, error)

func ReadPubKeys

func ReadPubKeys(keydir string) (map[string]dns.KEY, error)

ReadPubKeys reads all ".key" public key files in the given directory and returns a mapping from each key's owner name to its dns.KEY record.

If keydir is empty, the function returns an error. Only files with the ".key" suffix are processed; other files are ignored. Each processed file is parsed as a DNS RR and must be of type KEY; parse failures, unexpected RR ReadPubKeys reads all files with the ".key" suffix in the provided directory, parses each as a DNS KEY RR, and returns a map from the RR owner name to the dns.KEY value.

The keydir parameter is the path to the directory containing public key files. Non-".key" files are ignored. If any filesystem operation fails or a file cannot be parsed as a DNS KEY RR, an error is returned.

func RecursiveDNSQuery

func RecursiveDNSQuery(server, qname string, qtype uint16, timeout time.Duration, retries int) (*core.RRset, error)

func RecursiveDNSQueryWithConfig

func RecursiveDNSQueryWithConfig(qname string, qtype uint16, timeout time.Duration, retries int) (*core.RRset, error)

func RecursiveDNSQueryWithResolvConf

func RecursiveDNSQueryWithResolvConf(qname string, qtype uint16, timeout time.Duration, retries int) (*core.RRset, error)

func RecursiveDNSQueryWithServers

func RecursiveDNSQueryWithServers(qname string, qtype uint16, timeout time.Duration,
	retries int, resolvers []string) (*core.RRset, error)

func RefreshEngine

func RefreshEngine(ctx context.Context, conf *Config)

func RegisterAPIRoute

func RegisterAPIRoute(routeFunc APIRouteFunc) error

RegisterAPIRoute registers a function that will add API routes to the router. IMPORTANT: The route registration function is called DURING SetupAPIRouter(), so routes must be registered BEFORE calling SetupAPIRouter(). For apps that call SetupAPIRouter() before initializing their subsystems, routes should be registered directly on the router after SetupAPIRouter() returns, rather than using RegisterAPIRoute().

Example usage:

tdns.RegisterAPIRoute(func(router *mux.Router) error {
    router.PathPrefix("/api/v1/kdc").HandlerFunc(kdc.APIKdcZone)
    return nil
})

func RegisterCatalogZoneCallback

func RegisterCatalogZoneCallback(callback CatalogZoneCallback)

RegisterCatalogZoneCallback registers a callback for catalog zone updates

func RegisterDebugNotifyHandler

func RegisterDebugNotifyHandler() error

RegisterDebugNotifyHandler registers a debug handler that logs all DNS NOTIFY messages. The handler logs NOTIFY details and always returns ErrNotHandled to pass through to the next handler. This is useful for debugging and monitoring.

The handler is registered with qtype=0, meaning it will be called for ALL NOTIFYs before any specific qtype handlers. It should be registered first (before other handlers).

Example usage:

tdns.RegisterDebugNotifyHandler()
tdns.RegisterNotifyHandler(core.TypeCHUNK, myHandler)

func RegisterDebugQueryHandler

func RegisterDebugQueryHandler() error

RegisterDebugQueryHandler registers a debug handler that logs all DNS queries. The handler logs query details and always returns ErrNotHandled to pass through to the next handler. This is useful for debugging and monitoring.

The handler is registered with qtype=0, meaning it will be called for ALL queries before any specific qtype handlers. It should be registered first (before other handlers).

Example usage:

tdns.RegisterDebugQueryHandler()
tdns.RegisterQueryHandler(hpke.TypeKMREQ, myHandler)

func RegisterDefaultQueryHandlers

func RegisterDefaultQueryHandlers(conf *Config) error

RegisterDefaultQueryHandlers registers the default zone-based query handler. This is called automatically during TDNS initialization. The default handler is only registered if zones are configured in the config (TDNS-internal check). Apps that need .server. query support should register ServerQueryHandler themselves.

func RegisterEngine

func RegisterEngine(name string, engine EngineFunc) error

RegisterEngine registers a long-running engine that will be started by TDNS. Engines are started as goroutines and run until the context is cancelled. They are started after TDNS initialization is complete.

Example usage:

tdns.RegisterEngine("KeyStateWorker", func(ctx context.Context) error {
    return kdc.KeyStateWorker(ctx, kdcDB, &kdcConf)
})

func RegisterNotifyHandler

func RegisterNotifyHandler(qtype uint16, handler NotifyHandlerFunc) error

RegisterNotifyHandler registers a handler for DNS NOTIFY messages. Multiple handlers can be registered for the same qtype - they will be called in registration order. If a handler returns ErrNotHandled, TDNS will try the next handler or fall back to default. If qtype is 0, handler is called for ALL NOTIFYs (use with caution, e.g., for debug handlers). Handlers registered with qtype=0 are called before handlers registered for specific qtypes.

This function can be called before TDNS is initialized (uses global storage), or after initialization (uses conf.Internal.NotifyHandlers). During NOTIFY processing, TDNS checks both locations.

func RegisterQueryHandler

func RegisterQueryHandler(qtype uint16, handler QueryHandlerFunc) error

RegisterQueryHandler registers a handler for a specific query type. Multiple handlers can be registered for the same qtype - they will be called in registration order. If a handler returns ErrNotHandled, TDNS will try the next handler or fall back to default. If qtype is 0, handler is called for ALL query types (use with caution, e.g., for debug handlers). Handlers registered with qtype=0 are called before handlers registered for specific qtypes.

This function can be called before TDNS is initialized (uses global storage), or after initialization (uses conf.Internal.QueryHandlers). During query processing, TDNS checks both locations.

func RegisterUpdateHandler

func RegisterUpdateHandler(matcher UpdateMatcherFunc, handler UpdateHandlerFunc) error

RegisterUpdateHandler registers a handler for DNS UPDATE messages. The matcher function determines which UPDATEs should be handled by this handler. Multiple handlers can be registered - they will be called in registration order. If a handler returns ErrNotHandled, TDNS will try the next handler or fall back to default.

This function can be called before TDNS is initialized (uses global storage), or after initialization (uses conf.Internal.UpdateHandlers). During UPDATE processing, TDNS checks both locations.

Example usage:

// Match bootstrap UPDATEs (name pattern _bootstrap.*)
tdns.RegisterUpdateHandler(
	func(req *tdns.DnsUpdateRequest) bool {
		for _, rr := range req.Msg.Ns {
			if strings.HasPrefix(rr.Header().Name, "_bootstrap.") {
				return true
			}
		}
		return false
	},
	func(ctx context.Context, req *tdns.DnsUpdateRequest) error {
		return kdc.HandleBootstrapUpdate(ctx, req, kdcDB, &kdcConf)
	},
)

func ResignerEngine

func ResignerEngine(ctx context.Context, zoneresignch chan *ZoneData)

func ResignerEngine(zoneresignch chan ZoneRefresher, stopch chan struct{}) {

func SanitizeForJSON

func SanitizeForJSON(v interface{}) interface{}

SanitizeForJSON is a wrapper function that sanitizes a struct for JSON serialization

func ScannerEngine

func ScannerEngine(ctx context.Context, conf *Config) error

func SendUnixPing

func SendUnixPing(target string, dieOnError bool) (bool, error)

func ServerQueryHandler

func ServerQueryHandler(ctx context.Context, req *DnsQueryRequest) error

ServerQueryHandler handles queries for qnames ending in ".server." with ClassCHAOS. NOTE: This function is now optional. .server. queries are automatically handled by createAuthDnsHandler() in do53.go as a fallback before returning REFUSED. This exported function is kept for backward compatibility or for apps that want to handle .server. queries earlier in the handler chain.

func SetupCliLogging

func SetupCliLogging()

SetupCliLogging sets up logging for CLI commands with file/line info when verbose or debug mode is enabled. This is called for CLI commands that may not have a log file configured. Default CLI logging has no timestamps; verbose/debug mode adds file/line info.

func SetupLogging

func SetupLogging(logfile string) error

func ShowAPI

func ShowAPI(rtr *mux.Router) ([]string, error)

Stolen from labstuff:apihandler_funcs.go

func Shutdowner

func Shutdowner(conf *Config, msg string)

func SignMsg

func SignMsg(m dns.Msg, signer string, sak *Sig0ActiveKeys) (*dns.Msg, error)

func SprintUpdates

func SprintUpdates(actions []dns.RR) string

func StartRegisteredEngines

func StartRegisteredEngines(ctx context.Context)

StartRegisteredEngines starts all registered engines as goroutines. This should be called after TDNS initialization is complete. Engines run until the context is cancelled.

func StructToBase32Domains

func StructToBase32Domains(data interface{}, domainSuffix string, cookie string) ([]string, error)

StructToBase32Domains converts a Go struct to a set of domain names Each domain name contains chunks of base32-encoded data with maximized label sizes

func TLSAToSvcbLocal

func TLSAToSvcbLocal(tlsa *dns.TLSA) (*dns.SVCBLocal, error)

TLSAToSvcbLocal marshals a TLSA record into a private SVCB key/value pair.

func TtlPrint

func TtlPrint(expiration time.Time) string

TtlPrint returns a human-friendly TTL remaining until expiration. If the expiration time has passed, it returns "expired".

func TtyIntQuestion

func TtyIntQuestion(query string, oldval int, force bool) int

func TtyQuestion

func TtyQuestion(query, oldval string, force bool) string

func TtyRadioButtonQ

func TtyRadioButtonQ(query, defval string, choices []string) string

func TtyYesNo

func TtyYesNo(query, defval string) string

func TypeBitMapToString

func TypeBitMapToString(tbm []uint16) string

func UpdateHandler

func UpdateHandler(ctx context.Context, conf *Config) error

func UpdateResponder

func UpdateResponder(dur *DnsUpdateRequest, updateq chan UpdateRequest) error

func ValidateBySection

func ValidateBySection(config *Config, configsections map[string]interface{}, cfgfile string) (string, error)

func ValidateCertAndKeyFiles

func ValidateCertAndKeyFiles(fl validator.FieldLevel) bool

validateCertAndKeyFiles is the custom validation function

func ValidateConfig

func ValidateConfig(v *viper.Viper, cfgfile string) error

func ValidateConfigWithCustomValidator

func ValidateConfigWithCustomValidator(v *viper.Viper, cfgfile string) error

ValidateConfigWithCustomValidator validates the config using the custom validator XXX: Not used at the moment.

func ValidateExplicitServerSVCB

func ValidateExplicitServerSVCB(svcb *dns.SVCB) error

ValidateExplicitServerSVCB validates an explicit SVCB RR for server use. It checks transport weights against the ALPN list, if present. If transport is absent, the record is accepted as-is. If transport is present but alpn is missing, it's invalid.

func ValidateZones

func ValidateZones(c *Config, cfgfile string) error

func ValidatorEngine

func ValidatorEngine(ctx context.Context, conf *Config)

func VerifyCertAgainstTlsaRR

func VerifyCertAgainstTlsaRR(tlsarr *dns.TLSA, rawcert []byte) error

func VerifyKey

func VerifyKey(KeyName string, key string, keyid uint16, zd *ZoneData, updatetrustq chan<- KeyBootstrapperRequest)

func WalkRoutes

func WalkRoutes(router *mux.Router, address string)

func WildcardReplace

func WildcardReplace(rrs []dns.RR, qname, origqname string) []dns.RR

func ZoneIsReady

func ZoneIsReady(zonename string) func() bool

ZoneIsReady returns a function that can be used as a PreCondition for a DeferredUpdate. The returned function will return true if the zone exists and is ready, otherwise false.

func ZoneTransferPrint

func ZoneTransferPrint(zname, upstream string, serial uint32, ttype uint16, options map[string]string) error

Types

type APIRouteFunc

type APIRouteFunc func(router *mux.Router) error

APIRouteFunc is the function signature for API route registration. The function receives the API router and should register routes on it.

type APIRouteRegistration

type APIRouteRegistration struct {
	RouteFunc APIRouteFunc
}

APIRouteRegistration stores an API route registration

type Agent

type Agent struct {
	Identity AgentId

	InitialZone   ZoneName
	ApiDetails    *AgentDetails
	DnsDetails    *AgentDetails
	ApiMethod     bool
	DnsMethod     bool
	Zones         map[ZoneName]bool
	Api           *AgentApi
	State         AgentState // Agent states: needed, known, hello-done, operational, error
	LastState     time.Time  // When state last changed
	ErrorMsg      string     // Error message if state is error
	DeferredTasks []DeferredAgentTask
	// contains filtered or unexported fields
}

func (*Agent) AddDeferredAgentTask

func (agent *Agent) AddDeferredAgentTask(task *DeferredAgentTask)

XXX: The DeferredAgentTask functions are not yet fully thought out (and not in use yet).

func (*Agent) CheckState

func (agent *Agent) CheckState(ourBeatInterval uint32)

func (*Agent) CreateAgentUpstreamRFI

func (agent *Agent) CreateAgentUpstreamRFI() *DeferredAgentTask

func (*Agent) CreateOperationalAgentTask

func (agent *Agent) CreateOperationalAgentTask(action func() (bool, error), desc string) *DeferredAgentTask

func (*Agent) MarshalJSON

func (agent *Agent) MarshalJSON() ([]byte, error)

func (*Agent) NewAgentSyncApiClient

func (agent *Agent) NewAgentSyncApiClient(localagent *LocalAgentConf) error

func (*Agent) SendApiBeat

func (agent *Agent) SendApiBeat(msg *AgentBeatPost) (*AgentBeatResponse, error)

func (*Agent) SendApiHello

func (agent *Agent) SendApiHello(msg *AgentHelloPost) (*AgentHelloResponse, error)

func (*Agent) SendApiMsg

func (agent *Agent) SendApiMsg(msg *AgentMsgPost) (*AgentMsgResponse, error)

Helper methods for SendBeat

func (*Agent) SendDnsMsg

func (agent *Agent) SendDnsMsg(msg *AgentMsgPost) (int, []byte, error)

type AgentApi

type AgentApi struct {
	Name       string
	Client     *http.Client
	BaseUrl    string
	ApiKey     string // TODO: to remove, but we still need it for a while
	Authmethod string

	// normal TDNS API client, we're using most of the tdns API client,
	ApiClient *ApiClient
}

type AgentBeatPost

type AgentBeatPost struct {
	MessageType    AgentMsg
	MyIdentity     AgentId
	YourIdentity   AgentId
	MyBeatInterval uint32   // intended, in seconds
	Zones          []string // Zones that we share with the remote agent
	Time           time.Time
}

type AgentBeatReport

type AgentBeatReport struct {
	Time time.Time
	Beat AgentBeatPost
}

type AgentBeatResponse

type AgentBeatResponse struct {
	Status       string // ok | error | ...
	MyIdentity   AgentId
	YourIdentity AgentId
	Time         time.Time
	Client       string
	Msg          string
	Error        bool
	ErrorMsg     string
}

type AgentDebugPost

type AgentDebugPost struct {
	Command string   `json:"command"`
	Zone    ZoneName `json:"zone"`
	AgentId AgentId  `json:"agent_id"`
	RRType  uint16
	RR      string
	Data    ZoneUpdate
}

also mgmt API, same response struct

type AgentDetails

type AgentDetails struct {
	Addrs   []string
	Port    uint16
	BaseUri string
	UriRR   *dns.URI
	//	SvcbRR  *dns.SVCB
	Host   string    // the host part of the BaseUri
	KeyRR  *dns.KEY  // for DNS transport
	TlsaRR *dns.TLSA // for HTTPS transport
	//	LastHB      time.Time
	Endpoint    string
	ContactInfo string // "none", "partial", "complete"
	//	Zones           map[ZoneName]bool // zones we share with this agent
	State           AgentState // "discovered", "contact_attempted", "connected", "failed"
	LatestError     string
	LatestErrorTime time.Time
	HelloTime       time.Time
	BeatInterval    uint32
	SentBeats       uint32
	ReceivedBeats   uint32
	LatestSBeat     time.Time
	LatestRBeat     time.Time
}

type AgentHelloPost

type AgentHelloPost struct {
	MessageType  AgentMsg
	Name         string
	MyIdentity   AgentId
	YourIdentity AgentId
	Addresses    []string
	Port         uint16
	TLSA         dns.TLSA
	Zone         ZoneName // in the /hello we only send one zone, the one that triggered the /hello
}

type AgentHelloResponse

type AgentHelloResponse struct {
	Status       string // ok | error | ...
	MyIdentity   AgentId
	YourIdentity AgentId
	Time         time.Time
	// Client       string
	Msg      string
	Error    bool
	ErrorMsg string
}

type AgentId

type AgentId string

func (AgentId) String

func (id AgentId) String() string

type AgentMgmtPost

type AgentMgmtPost struct {
	Command     string `json:"command"`
	MessageType AgentMsg
	Zone        ZoneName `json:"zone"`
	AgentId     AgentId  `json:"agent_id"`
	RRType      uint16
	RR          string
	RRs         []string
	AddedRRs    []string // for update-local-zonedata
	RemovedRRs  []string // for update-local-zonedata
	Upstream    AgentId
	Downstream  AgentId
	RfiType     string
}

AgentMgmt{Post,Response} are used in the mgmt API

type AgentMgmtPostPlus

type AgentMgmtPostPlus struct {
	AgentMgmtPost
	Response chan *AgentMgmtResponse
}

The ...Plus structs are always the original struct + a response channel

type AgentMgmtResponse

type AgentMgmtResponse struct {
	Identity      AgentId
	Status        string
	Time          time.Time
	Agents        []*Agent // used for hsync-agentstatus
	ZoneAgentData *ZoneAgentData
	HsyncRRs      []string
	AgentConfig   LocalAgentConf
	RfiType       string
	RfiResponse   map[AgentId]*RfiData
	AgentRegistry *AgentRegistry
	// ZoneDataRepo  *ZoneDataRepo
	// ZoneDataRepo map[ZoneName]map[AgentId]*OwnerData
	ZoneDataRepo map[ZoneName]map[AgentId]map[uint16][]string
	Msg          string
	Error        bool
	ErrorMsg     string
}

type AgentMsg

type AgentMsg uint8
const (
	AgentMsgHello AgentMsg = iota + 1
	AgentMsgBeat
	AgentMsgNotify
	AgentMsgRfi
	AgentMsgStatus
)

type AgentMsgPost

type AgentMsgPost struct {
	MessageType  AgentMsg // "NOTIFY", ...
	MyIdentity   AgentId
	YourIdentity AgentId
	Addresses    []string
	Port         uint16
	TLSA         dns.TLSA
	Zone         ZoneName // An AgentMsgPost should always only refer to one zone.
	// Data	     map[AgentId]map[uint16]RRset
	RRs []string // cannot send more structured format, as dns.RR cannot be json marshalled.
	// Zones []string
	Time    time.Time
	RfiType string
}

AgentMsg{Post,Response} are intended for agent-to-agent messaging

type AgentMsgPostPlus

type AgentMsgPostPlus struct {
	AgentMsgPost
	Response chan *AgentMsgResponse
}

type AgentMsgReport

type AgentMsgReport struct {
	Transport    string
	MessageType  AgentMsg
	Zone         ZoneName
	Identity     AgentId
	BeatInterval uint32
	Msg          interface{}
	RfiType      string
	Response     chan *SynchedDataResponse
}

type AgentMsgResponse

type AgentMsgResponse struct {
	Status string // ok | error | ...
	Time   time.Time
	// Client      string
	AgentId     AgentId
	Msg         string
	Zone        ZoneName
	RfiResponse map[AgentId]*RfiData
	Error       bool
	ErrorMsg    string
}

type AgentQs

type AgentQs struct {
	Hello chan *AgentMsgReport // incoming /hello from other agents
	Beat  chan *AgentMsgReport // incoming /beat from other agents
	// Msg               chan *AgentMsgReport    // incoming /msg from other agents
	Msg               chan *AgentMsgPostPlus  // incoming /msg from other agents
	Command           chan *AgentMgmtPostPlus // local commands TO the agent, usually for passing on to other agents
	DebugCommand      chan *AgentMgmtPostPlus // local commands TO the agent, usually for passing on to other agents
	SynchedDataUpdate chan *SynchedDataUpdate // incoming combiner updates
	SynchedDataCmd    chan *SynchedDataCmd    // local commands TO the combiner
}

type AgentRegistry

type AgentRegistry struct {
	S            core.ConcurrentMap[AgentId, *Agent]
	RegularS     map[AgentId]*Agent
	RemoteAgents map[ZoneName][]AgentId

	LocalAgent     *LocalAgentConf // our own identity
	LocateInterval int             // seconds to wait between locating agents (until success)
	// contains filtered or unexported fields
}

func (*AgentRegistry) AddRemoteAgent

func (ar *AgentRegistry) AddRemoteAgent(zonename ZoneName, agent *Agent)

AddRemoteAgent adds an agent to the list of remote agents for a zone

func (*AgentRegistry) AddZoneToAgent

func (ar *AgentRegistry) AddZoneToAgent(identity AgentId, zone ZoneName)

func (*AgentRegistry) CleanupZoneRelationships

func (ar *AgentRegistry) CleanupZoneRelationships(zonename ZoneName)

CleanupZoneRelationships handles the complex cleanup when we're no longer involved in a zone's management

func (*AgentRegistry) CommandHandler

func (ar *AgentRegistry) CommandHandler(msg *AgentMgmtPostPlus, synchedDataUpdateQ chan *SynchedDataUpdate)

Handler for local commands from CLI or other components in the same organization

func (*AgentRegistry) EvaluateHello

func (ar *AgentRegistry) EvaluateHello(ahp *AgentHelloPost) (bool, string, error)

func (*AgentRegistry) GetAgentInfo

func (ar *AgentRegistry) GetAgentInfo(identity AgentId) (*Agent, error)

Create a new synchronous function for code that needs immediate results

func (*AgentRegistry) GetAgentsForZone

func (ar *AgentRegistry) GetAgentsForZone(zone ZoneName) []*Agent

func (*AgentRegistry) GetZoneAgentData

func (ar *AgentRegistry) GetZoneAgentData(zonename ZoneName) (*ZoneAgentData, error)

GetRemoteAgents returns a list of remote agents for a zone. It does not check if the agents are operational, or try to get missing information. func (ar *AgentRegistry) GetRemoteAgents(zonename ZoneName) ([]*Agent, error) {

func (*AgentRegistry) HandleStatusRequest

func (ar *AgentRegistry) HandleStatusRequest(req SyncStatus)

XXX: Not used at the moment.

func (*AgentRegistry) HeartbeatHandler

func (ar *AgentRegistry) HeartbeatHandler(report *AgentMsgReport)

func (*AgentRegistry) HelloHandler

func (ar *AgentRegistry) HelloHandler(report *AgentMsgReport)

func (*AgentRegistry) HelloRetrier

func (ar *AgentRegistry) HelloRetrier()

func (*AgentRegistry) HelloRetrierNG

func (ar *AgentRegistry) HelloRetrierNG(ctx context.Context, agent *Agent)

XXX: This is a modified version of HelloRetrier that uses a context to stop the retrier (suggested by the coderabbit)when the agent is no longer in state KNOWN. Not sure if this is what we want.

func (*AgentRegistry) LocateAgent

func (ar *AgentRegistry) LocateAgent(remoteid AgentId, zonename ZoneName, deferredTask *DeferredAgentTask)

LocateAgent is completely asynchronous with no return values

func (*AgentRegistry) MsgHandler

func (ar *AgentRegistry) MsgHandler(ampp *AgentMsgPostPlus, synchedDataUpdateQ chan *SynchedDataUpdate)

Handler for messages received from other agents

func (*AgentRegistry) RemoteOperationalAgents

func (ar *AgentRegistry) RemoteOperationalAgents(zone ZoneName) (*ZoneAgentData, map[AgentId]bool, error)

func (*AgentRegistry) RemoveRemoteAgent

func (ar *AgentRegistry) RemoveRemoteAgent(zonename ZoneName, identity AgentId)

RemoveRemoteAgent removes an agent from the list of remote agents for a zone

func (*AgentRegistry) SendHeartbeats

func (ar *AgentRegistry) SendHeartbeats()

func (*AgentRegistry) SingleHello

func (ar *AgentRegistry) SingleHello(agent *Agent, zone ZoneName)

func (*AgentRegistry) SyncRequestHandler

func (ar *AgentRegistry) SyncRequestHandler(ourId AgentId, req SyncRequest, synchedDataUpdateQ chan *SynchedDataUpdate)

func (*AgentRegistry) UpdateAgents

func (ar *AgentRegistry) UpdateAgents(ourId AgentId, req SyncRequest, zonename ZoneName, synchedDataUpdateQ chan *SynchedDataUpdate) error

XXX: This is likely not sufficient, we must also be able to deal with HSYNC RRs that simply "change" (i.e. the same identity, but now roles). ADD+REMOVE doesn't deal with that.

type AgentRepo

type AgentRepo struct {
	// Data map[AgentId]OwnerData // map[agentid]data
	Data core.ConcurrentMap[AgentId, *OwnerData] // map[agentid]data
}

func NewAgentRepo

func NewAgentRepo() (*AgentRepo, error)

func (*AgentRepo) Get

func (ar *AgentRepo) Get(agentId AgentId) (*OwnerData, bool)

func (*AgentRepo) Set

func (ar *AgentRepo) Set(agentId AgentId, ownerData *OwnerData)

type AgentState

type AgentState uint8
const (
	AgentStateNeeded      AgentState = iota + 1 // Agent is required but we don't have complete information
	AgentStateKnown                             // We have complete information but haven't established communication
	AgentStateIntroduced                        // We got a nice reply to our HELLO
	AgentStateOperational                       // We got a nice reply to our (secure) BEAT
	AgentStateDegraded                          // Last successful heartbeat (in either direction) was more than 2x normal interval ago
	AgentStateInterrupted                       // Last successful heartbeat (in either direction) was more than 10x normal interval ago
	AgentStateError                             // We have tried to establish communication but failed
)

type ApiClient

type ApiClient struct {
	Name      string
	Client    *http.Client
	BaseUrl   string
	Addresses []string // if non-empty, replace the host part of the BaseUrl with each of these

	AuthMethod string
	UseTLS     bool
	Verbose    bool
	Debug      bool

	// deSEC stuff (from MUSIC)
	Email    string
	Password string
	TokViper *viper.Viper
	// contains filtered or unexported fields
}

func NewClient

func NewClient(name, baseurl, apikey, authmethod, rootcafile string) *ApiClient

func (*ApiClient) Delete

func (api *ApiClient) Delete(endpoint string) (int, []byte, error)

api Delete (not tested)

func (*ApiClient) Get

func (api *ApiClient) Get(endpoint string) (int, []byte, error)

api Get (not tested)

func (*ApiClient) Post

func (api *ApiClient) Post(endpoint string, data []byte) (int, []byte, error)

func (*ApiClient) Put

func (api *ApiClient) Put(endpoint string, data []byte) (int, []byte, error)

api Put

func (*ApiClient) RequestNG

func (api *ApiClient) RequestNG(method, endpoint string, data interface{}, dieOnError bool) (int, []byte, error)

func (*ApiClient) RequestNGWithContext

func (api *ApiClient) RequestNGWithContext(ctx context.Context, method, endpoint string, data interface{}, dieOnError bool) (int, []byte, error)

func (*ApiClient) SendPing

func (api *ApiClient) SendPing(pingcount int, dieOnError bool) (PingResponse, error)

func (*ApiClient) ShowApi

func (api *ApiClient) ShowApi()

func (*ApiClient) StartDaemon

func (api *ApiClient) StartDaemon(maxwait int, slurp bool, command string)

slurp means that we'll connect to stdout and stderr on the underlying daemon to check for possible error messages (if it dies somehow). The problem is that connecting to stdout doesn't work well, it kills the daemon after a while. So we only want to slurp when explicitly checking for errors. command is an optional parameter specifying the daemon binary path. If empty, it falls back to viper.GetString("common.command") for backward compatibility.

func (*ApiClient) StopDaemon

func (api *ApiClient) StopDaemon()

func (*ApiClient) UpdateDaemon

func (api *ApiClient) UpdateDaemon(data CommandPost, dieOnError bool) (int, CommandResponse, error)

func (*ApiClient) UrlReport

func (api *ApiClient) UrlReport(method, endpoint string, data []byte)

func (*ApiClient) UrlReportNG

func (api *ApiClient) UrlReportNG(method, fullurl string, data []byte)

type ApiServerAppConf

type ApiServerAppConf struct {
	Addresses []string
	ApiKey    string
}

type ApiServerConf

type ApiServerConf struct {
	Addresses []string `validate:"required"` // Must be in addr:port format
	ApiKey    string   `validate:"required"`
	CertFile  string   `validate:"required,file,certkey"`
	KeyFile   string   `validate:"required,file"`
	UseTLS    bool
	Server    ApiServerAppConf
	Agent     ApiServerAppConf
	// MSA       ApiServerAppConf
	Combiner ApiServerAppConf
}

type AppDetails

type AppDetails struct {
	Name             string
	Version          string
	Type             AppType
	Date             string
	ServerBootTime   time.Time
	ServerConfigTime time.Time
}

type AppType

type AppType uint8
const (
	AppTypeAuth AppType = iota + 1
	AppTypeAgent
	AppTypeCombiner
	AppTypeImr // simplified recursor
	AppTypeCli
	AppTypeReporter
	AppTypeScanner
	AppTypeKdc        // Key Distribution Center
	AppTypeKrs        // Key Receiving Service (edge receiver)
	AppTypeEdgeSigner // NYI
)

type AuthOption

type AuthOption uint8
const (
	AuthOptParentUpdate AuthOption = iota + 1
)

type AuthQueryRequest

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

AuthQueryNG is the same as AuthQuery, but returns an RRset instead of a []dns.RR to be able to keep any RRSIGs. AuthQuery should be phased out. ns must be in addr:port format

type AuthQueryResponse

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

type BindPrivateKey

type BindPrivateKey struct {
	Private_Key_Format string `yaml:"Private-key-format"`
	Algorithm          string `yaml:"Algorithm"`
	PrivateKey         string `yaml:"PrivateKey"`
}

type BumperData

type BumperData struct {
	Zone   string
	Result chan BumperResponse
}

type BumperResponse

type BumperResponse struct {
	Time      time.Time
	Zone      string
	Msg       string
	OldSerial uint32
	NewSerial uint32
	Error     bool
	ErrorMsg  string
	Status    bool
}

type CatalogConf

type CatalogConf struct {
	GroupPrefixes GroupPrefixesConf             `yaml:"group_prefixes" mapstructure:"group_prefixes"`
	Policy        CatalogPolicy                 `yaml:"policy" mapstructure:"policy"` // Deprecated, kept for backward compatibility
	ConfigGroups  map[string]*ConfigGroupConfig `yaml:"config_groups" mapstructure:"config_groups"`
	MetaGroups    map[string]*ConfigGroupConfig `yaml:"meta_groups" mapstructure:"meta_groups"` // Deprecated, kept for backward compatibility
	SigningGroups map[string]*SigningGroupInfo  `yaml:"signing_groups" mapstructure:"signing_groups"`
}

CatalogConf defines configuration for catalog zone support (RFC 9432)

type CatalogMemberZone

type CatalogMemberZone struct {
	ZoneName     string
	Hash         string    // SHA256 hash of zone name (first 16 chars)
	Groups       []string  // List of group names associated with this zone (RFC 9432 terminology)
	DiscoveredAt time.Time // Timestamp when the zone was first added to the catalog
}

CatalogMemberZone represents a member zone in the catalog

type CatalogMembership

type CatalogMembership struct {
	CatalogZoneName string
	MemberZones     map[string]*CatalogMemberZone // zonename -> member data
	AvailableGroups []string                      // List of all defined groups (RFC 9432 terminology)
	// contains filtered or unexported fields
}

CatalogMembership manages the membership data for a catalog zone

func GetOrCreateCatalogMembership

func GetOrCreateCatalogMembership(catalogZoneName string) *CatalogMembership

GetOrCreateCatalogMembership returns the membership for a catalog zone, creating if needed

func (*CatalogMembership) AddGroup

func (cm *CatalogMembership) AddGroup(group string) error

AddGroup adds a group to the available groups list

func (*CatalogMembership) AddMemberZone

func (cm *CatalogMembership) AddMemberZone(zoneName string) error

AddMemberZone adds a zone to the catalog

func (*CatalogMembership) AddZoneGroup

func (cm *CatalogMembership) AddZoneGroup(zoneName, group string) error

AddZoneGroup associates a group with a zone

func (*CatalogMembership) GetGroups

func (cm *CatalogMembership) GetGroups() []string

GetGroups returns all available groups (thread-safe copy)

func (*CatalogMembership) GetMemberZones

func (cm *CatalogMembership) GetMemberZones() map[string]*MemberZone

GetMemberZones returns all member zones (thread-safe copy)

func (*CatalogMembership) RemoveGroup

func (cm *CatalogMembership) RemoveGroup(group string) error

RemoveGroup removes a group from the available groups list

func (*CatalogMembership) RemoveMemberZone

func (cm *CatalogMembership) RemoveMemberZone(zoneName string) error

RemoveMemberZone removes a zone from the catalog

func (*CatalogMembership) RemoveZoneGroup

func (cm *CatalogMembership) RemoveZoneGroup(zoneName, group string) error

RemoveZoneGroup disassociates a group from a zone

type CatalogPolicy

type CatalogPolicy struct {
	Zones struct {
		Add    string `yaml:"add" mapstructure:"add" validate:"omitempty,oneof=auto manual"`       // "auto" or "manual"
		Remove string `yaml:"remove" mapstructure:"remove" validate:"omitempty,oneof=auto manual"` // "auto" or "manual"
	} `yaml:"zones" mapstructure:"zones"`
}

CatalogPolicy defines policy for how catalog zones are processed

type CatalogPost

type CatalogPost struct {
	Command     string   `json:"command"`      // "create" | "zone-add" | "zone-delete" | "zone-list" | "group-add" | "group-delete" | "group-list" | "zone-group-add" | "zone-group-delete" | "notify-add" | "notify-remove" | "notify-list"
	CatalogZone string   `json:"catalog_zone"` // Name of the catalog zone
	Zone        string   `json:"zone"`         // Member zone name
	Group       string   `json:"group"`        // Group name (RFC 9432 terminology)
	Groups      []string `json:"groups"`       // Multiple groups (for zone-add with --groups flag)
	Address     string   `json:"address"`      // Notify address (IP:port) for notify-add/notify-remove
}

CatalogPost represents a request to manage catalog zones

type CatalogResponse

type CatalogResponse struct {
	Time            time.Time              `json:"time"`
	Error           bool                   `json:"error"`
	ErrorMsg        string                 `json:"error_msg,omitempty"`
	Msg             string                 `json:"msg,omitempty"`
	Zones           map[string]*MemberZone `json:"zones,omitempty"`            // For zone-list command
	Groups          []string               `json:"groups,omitempty"`           // For group-list command
	NotifyAddresses []string               `json:"notify_addresses,omitempty"` // For notify-list command
}

CatalogResponse represents the response from catalog operations

type CatalogZoneCallback

type CatalogZoneCallback func(update *CatalogZoneUpdate) error

CatalogZoneCallback is called when a catalog zone is updated

type CatalogZoneUpdate

type CatalogZoneUpdate struct {
	CatalogZone string                 `json:"catalog_zone"`
	MemberZones map[string]*MemberZone `json:"member_zones"`
	Serial      uint32                 `json:"serial"`
	UpdateTime  time.Time              `json:"update_time"`
}

CatalogZoneUpdate contains information about catalog zone changes

func ParseCatalogZone

func ParseCatalogZone(zd *ZoneData) (*CatalogZoneUpdate, error)

ParseCatalogZone parses a catalog zone and extracts member zones and groups

type ChildDelegationData

type ChildDelegationData struct {
	DelHasChanged    bool      // When returned from a scanner, this indicates that a change has been detected
	ParentSerial     uint32    // The parent serial that this data was correct for
	Timestamp        time.Time // Time at which this data was fetched
	ChildName        string
	RRsets           map[string]map[uint16]core.RRset // map[ownername]map[rrtype]RRset
	NS_rrs           []dns.RR
	A_glue           []dns.RR
	A_glue_rrsigs    []dns.RR
	AAAA_glue        []dns.RR
	AAAA_glue_rrsigs []dns.RR
	NS_rrset         *core.RRset
	DS_rrset         *core.RRset
	A_rrsets         []*core.RRset
	AAAA_rrsets      []*core.RRset
}

type CombinerPost

type CombinerPost struct {
	Command string              `json:"command"` // add, list, remove
	Zone    string              `json:"zone"`    // zone name
	Data    map[string][]string `json:"data"`    // The RRs as strings, indexed by owner name
}

type CombinerResponse

type CombinerResponse struct {
	Time     time.Time                `json:"time"`
	Error    bool                     `json:"error"`
	ErrorMsg string                   `json:"error_msg,omitempty"`
	Msg      string                   `json:"msg,omitempty"`
	Data     map[string][]RRsetString `json:"data,omitempty"`
}

type CommandPost

type CommandPost struct {
	Command    string
	SubCommand string
	Zone       string
	Force      bool
}

type CommandResponse

type CommandResponse struct {
	AppName      string
	Time         time.Time
	Status       string
	Zone         string
	Names        []string
	Zones        map[string]ZoneConf
	Msg          string
	ApiEndpoints []string
	Error        bool
	ErrorMsg     string
}

type Config

type Config struct {
	Service        ServiceConf
	DnsEngine      DnsEngineConf
	Imr            ImrEngineConf `yaml:"imrengine" mapstructure:"imrengine"`
	ApiServer      ApiServerConf
	DnssecPolicies map[string]DnssecPolicyConf
	MultiSigner    map[string]MultiSignerConf `yaml:"multisigner"`
	Catalog        CatalogConf                `yaml:"catalog" mapstructure:"catalog"`
	DynamicZones   DynamicZonesConf           `yaml:"dynamiczones" mapstructure:"dynamiczones"`
	Zones          []ZoneConf                 `yaml:"zones"`
	Templates      []ZoneConf                 `yaml:"templates"`
	Keys           KeyConf
	Db             DbConf
	Registrars     map[string][]string
	Log            struct {
		File string `validate:"required"`
	}
	Agent    LocalAgentConf
	Internal InternalConf
}
var Conf Config

func (*Config) APIagent

func (conf *Config) APIagent(refreshZoneCh chan<- ZoneRefresher, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)

func (*Config) APIagentDebug

func (conf *Config) APIagentDebug() func(w http.ResponseWriter, r *http.Request)

func (*Config) APIbeat

func (conf *Config) APIbeat() func(w http.ResponseWriter, r *http.Request)

func (*Config) APIhello

func (conf *Config) APIhello() func(w http.ResponseWriter, r *http.Request)

This is the agent-to-agent sync API hello handler.

func (*Config) APImsg

func (conf *Config) APImsg() func(w http.ResponseWriter, r *http.Request)

func (*Config) AddDynamicZoneToConfig

func (conf *Config) AddDynamicZoneToConfig(zd *ZoneData) error

AddDynamicZoneToConfig adds or updates a zone in the dynamic config file

func (*Config) CheckDynamicConfigFileIncluded

func (conf *Config) CheckDynamicConfigFileIncluded(includedFiles []string) bool

CheckDynamicConfigFileIncluded checks if the dynamic config file is included in the main config Returns true if included, false otherwise (logs warning if not included)

func (*Config) FindDnsEngineAddrs

func (conf *Config) FindDnsEngineAddrs() ([]string, error)

Extract the addresses we listen on from the dnsengine configuration. Exclude localhost and non-standard ports.

func (*Config) ImrEngine

func (conf *Config) ImrEngine(ctx context.Context, quiet bool) error

func (*Config) InitializeKeyDB

func (conf *Config) InitializeKeyDB() error

func (*Config) LoadDynamicZoneFiles

func (conf *Config) LoadDynamicZoneFiles(ctx context.Context) error

LoadDynamicZoneFiles loads dynamic zones from the dynamic config file on startup This should be called after ParseZones() but before engines start It loads zones that were persisted in previous runs

func (*Config) MainInit

func (conf *Config) MainInit(ctx context.Context, defaultcfg string) error

func (*Config) MainLoop

func (conf *Config) MainLoop(ctx context.Context, cancel context.CancelFunc)

func (*Config) NewAgentRegistry

func (conf *Config) NewAgentRegistry() *AgentRegistry

func (*Config) ParseConfig

func (conf *Config) ParseConfig(reload bool) error

func (*Config) ParseZones

func (conf *Config) ParseZones(ctx context.Context, reload bool) ([]string, error)

func ParseZones(zones map[string]tdns.ZoneConf, zrch chan tdns.ZoneRefresher) error {

func (*Config) ReloadConfig

func (conf *Config) ReloadConfig() (string, error)

func (*Config) ReloadZoneConfig

func (conf *Config) ReloadZoneConfig(ctx context.Context) (string, error)

func (*Config) RemoveDynamicZoneFromConfig

func (conf *Config) RemoveDynamicZoneFromConfig(zoneName string) error

RemoveDynamicZoneFromConfig removes a zone from the dynamic config file

func (*Config) SetupAPIRouter

func (conf *Config) SetupAPIRouter(ctx context.Context) (*mux.Router, error)

func (*Config) SetupAgent

func (conf *Config) SetupAgent(all_zones []string) error

func (*Config) SetupAgentAutoZone

func (conf *Config) SetupAgentAutoZone(zonename string) (*ZoneData, error)

func (*Config) SetupAgentSyncRouter

func (conf *Config) SetupAgentSyncRouter(ctx context.Context) (*mux.Router, error)

This is the agent-to-agent sync API router.

func (*Config) SetupApiTransport

func (conf *Config) SetupApiTransport() error

func (*Config) SetupDnsTransport

func (conf *Config) SetupDnsTransport() error

func (*Config) SetupSimpleAPIRouter

func (conf *Config) SetupSimpleAPIRouter(ctx context.Context) (*mux.Router, error)

The simple API router is sufficient for tdns-imr, tdns-scanner and tdns-reporter.

func (*Config) ShouldPersistZone

func (conf *Config) ShouldPersistZone(zd *ZoneData) bool

ShouldPersistZone checks if a zone should be persisted based on configuration Returns true if the zone should be written to disk

func (*Config) StartAgent

func (conf *Config) StartAgent(ctx context.Context, apirouter *mux.Router) error

StartAgent starts subsystems for tdns-agent

func (*Config) StartAuth

func (conf *Config) StartAuth(ctx context.Context, apirouter *mux.Router) error

StartAuth starts subsystems for tdns-auth

func (*Config) StartCombiner

func (conf *Config) StartCombiner(ctx context.Context, apirouter *mux.Router) error

StartCombiner starts subsystems for tdns-combiner

func (*Config) StartImr

func (conf *Config) StartImr(ctx context.Context, apirouter *mux.Router) error

StartImr starts subsystems for tdns-imr

func (*Config) StartScanner

func (conf *Config) StartScanner(ctx context.Context, apirouter *mux.Router) error

StartScanner starts subsystems for tdns-scanner

func (*Config) SynchedDataEngine

func (conf *Config) SynchedDataEngine(ctx context.Context, agentQs *AgentQs)

SynchedDataEngine is a component that updates the combiner with new information received from the agents that are sharing zones with us.

func (*Config) WriteDynamicConfigFile

func (conf *Config) WriteDynamicConfigFile() error

WriteDynamicConfigFile writes the current dynamic zones to the config file This should be called whenever a dynamic zone is created, updated, or deleted

type ConfigEntry

type ConfigEntry struct {
	Key   string
	Value interface{}
}

OrderedConfig preserves the order of configuration entries

type ConfigGroupConfig

type ConfigGroupConfig struct {
	Name     string   `yaml:"-" mapstructure:"-"` // Populated from map key
	Upstream string   `yaml:"upstream" mapstructure:"upstream"`
	TsigKey  string   `yaml:"tsig_key" mapstructure:"tsig_key"`
	Store    string   `yaml:"store" mapstructure:"store"`
	Options  []string `yaml:"options" mapstructure:"options"`
}

ConfigGroupConfig provides configuration for zone transfers from catalog config groups (RFC 9432 terminology)

type ConfigPost

type ConfigPost struct {
	Command string // status | sync | ...
}

type ConfigResponse

type ConfigResponse struct {
	AppName    string
	Time       time.Time
	DnsEngine  DnsEngineConf
	ApiServer  ApiServerConf
	Identities []string
	Msg        string
	Error      bool
	ErrorMsg   string
}

type CurrentScanData

type CurrentScanData struct {
	RRset  *core.RRset `json:"-"` // Current RRset for ScanRRtype test, nil if no data exists (not JSON serialized)
	CDS    *core.RRset `json:"-"` // Current CDS RRset for ScanCDS test, nil if no data exists (not JSON serialized)
	CSYNC  *core.RRset `json:"-"` // Current CSYNC RRset for ScanCSYNC test, nil if no data exists (not JSON serialized)
	DNSKEY *core.RRset `json:"-"` // Current DNSKEY RRset for ScanDNSKEY test, nil if no data exists (not JSON serialized)
}

ScanCurrentData holds the current data for a scan test For ScanRRtype tests, it contains the current RRset for the queried RRtype at the name Note: This struct is not JSON-serializable directly. Use ToJSON() to convert to CurrentScanDataJSON.

func (*CurrentScanData) ToJSON

func (csd *CurrentScanData) ToJSON() CurrentScanDataJSON

ToJSON converts CurrentScanData to a JSON-serializable format

type CurrentScanDataJSON

type CurrentScanDataJSON struct {
	RRset  *core.RRsetString `json:"rrset,omitempty"`
	CDS    *core.RRsetString `json:"cds,omitempty"`
	CSYNC  *core.RRsetString `json:"csync,omitempty"`
	DNSKEY *core.RRsetString `json:"dnskey,omitempty"`
}

CurrentScanDataJSON is the JSON-serializable version of CurrentScanData

type CustomValidator

type CustomValidator struct {
	*validator.Validate
}

CustomValidator is a struct that embeds the validator.Validate type

func NewCustomValidator

func NewCustomValidator() (*CustomValidator, error)

NewCustomValidator creates a new instance of CustomValidator

type DbConf

type DbConf struct {
	File string // `validate:"required"`
}

type DebugPost

type DebugPost struct {
	Command string
	Zone    string
	Qname   string
	Qtype   uint16
	Verbose bool
}

type DebugResponse

type DebugResponse struct {
	AppName    string
	Time       time.Time
	Status     string
	Zone       string
	OwnerIndex map[string]int
	RRset      core.RRset
	//	TrustedDnskeys	map[string]dns.DNSKEY
	//	TrustedSig0keys	map[string]dns.KEY
	TrustedDnskeys  []cache.CachedDnskeyRRset
	TrustedSig0keys map[string]Sig0Key
	CachedRRsets    []cache.CachedRRset
	Validated       bool
	Msg             string
	Error           bool
	ErrorMsg        string
}

type DeferredAgentTask

type DeferredAgentTask struct {
	Precondition func() bool
	Action       func() (bool, error)
	Desc         string
}

AgentTask is a task that needs to be executed once the Precondition is met. A typical case is when we need to talk to a remote agent regarding zone transfer provisioning, but cannot do that until the remote agent is operational. The Precondition is checked every time a heartbeat is received from the remote agent.

type DeferredTask

type DeferredTask struct {
	Action      string
	Target      string
	ZoneName    string
	RetryCount  int
	MaxRetries  int
	LastAttempt time.Time
}

Define task struct for deferred operations

type DeferredUpdate

type DeferredUpdate struct {
	Cmd          string
	ZoneName     string
	AddTime      time.Time
	Description  string
	PreCondition func() bool
	Action       func() error
}

type DelegationData

type DelegationData struct {
	CurrentNS *core.RRset
	AddedNS   *core.RRset
	RemovedNS *core.RRset

	BailiwickNS []string
	A_glue      map[string]*core.RRset // map[nsname]
	AAAA_glue   map[string]*core.RRset // map[nsname]
	Actions     []dns.RR               // actions are DNS UPDATE actions that modify delegation data
	Time        time.Time
}

type DelegationPost

type DelegationPost struct {
	Command string // status | sync | ...
	Scheme  uint8  // 1=notify | 2=update
	Zone    string
	Force   bool
}

type DelegationResponse

type DelegationResponse struct {
	AppName    string
	Time       time.Time
	Zone       string
	SyncStatus DelegationSyncStatus
	Msg        string
	Error      bool
	ErrorMsg   string
}

type DelegationSyncRequest

type DelegationSyncRequest struct {
	Command      string
	ZoneName     string
	ZoneData     *ZoneData
	SyncStatus   DelegationSyncStatus
	OldDnskeys   *core.RRset
	NewDnskeys   *core.RRset
	MsignerGroup *core.RRset
	Response     chan DelegationSyncStatus // used for API-based requests
}

type DelegationSyncStatus

type DelegationSyncStatus struct {
	ZoneName      string
	Parent        string // use zd.Parent instead
	Time          time.Time
	InSync        bool
	Status        string
	Msg           string
	Rcode         uint8
	Adds          []dns.RR
	Removes       []dns.RR
	NsAdds        []dns.RR
	NsRemoves     []dns.RR
	AAdds         []dns.RR
	ARemoves      []dns.RR
	AAAAAdds      []dns.RR
	AAAARemoves   []dns.RR
	DNSKEYAdds    []dns.RR
	DNSKEYRemoves []dns.RR
	Error         bool
	ErrorMsg      string
	UpdateResult  UpdateResult // Experimental
	// Complete new delegation data for replace mode
	NewNS   []dns.RR // Complete NS RRset after update
	NewA    []dns.RR // Complete A glue RRs after update
	NewAAAA []dns.RR // Complete AAAA glue RRs after update
}

type DnsEngineConf

type DnsEngineConf struct {
	Addresses   []string              `yaml:"addresses" validate:"required"`
	CertFile    string                `yaml:"certfile,omitempty"`
	KeyFile     string                `yaml:"keyfile,omitempty"`
	Transports  []string              `yaml:"transports" validate:"required,min=1,dive,oneof=do53 dot doh doq"` // "do53", "dot", "doh", "doq"
	OptionsStrs []string              `yaml:"options" mapstructure:"options"`
	Options     map[AuthOption]string `yaml:"-" mapstructure:"-"`
}

type DnsHandlerRequest

type DnsHandlerRequest struct {
	ResponseWriter dns.ResponseWriter
	Msg            *dns.Msg
	Qname          string
}

type DnsNotifyRequest

type DnsNotifyRequest struct {
	ResponseWriter dns.ResponseWriter
	Msg            *dns.Msg
	Qname          string
	Options        *edns0.MsgOptions
	Status         *NotifyStatus
}

type DnsQueryRequest

type DnsQueryRequest struct {
	ResponseWriter dns.ResponseWriter
	Msg            *dns.Msg
	Qname          string
	Qtype          uint16
	Options        *edns0.MsgOptions
}

type DnsUpdateRequest

type DnsUpdateRequest struct {
	ResponseWriter dns.ResponseWriter
	Msg            *dns.Msg
	Qname          string
	Options        *edns0.MsgOptions
	Status         *UpdateStatus
}

func (*DnsUpdateRequest) Log

func (dur *DnsUpdateRequest) Log(fmt string, v ...any)

type DnssecKey

type DnssecKey struct {
	Name       string
	State      string
	Keyid      uint16
	Flags      uint16
	Algorithm  string
	Creator    string
	PrivateKey string //
	Key        dns.DNSKEY
	Keystr     string
}

type DnssecKeys

type DnssecKeys struct {
	KSKs []*PrivateKeyCache
	ZSKs []*PrivateKeyCache
}

type DnssecPolicy

type DnssecPolicy struct {
	Name      string
	Algorithm uint8

	KSK KeyLifetime
	ZSK KeyLifetime
	CSK KeyLifetime
}

DnssecPolicy is what is actually used; it is created from the corresponding DnssecPolicyConf

type DnssecPolicyConf

type DnssecPolicyConf struct {
	Name      string
	Algorithm string

	KSK struct {
		Lifetime    string
		SigValidity string
	}
	ZSK struct {
		Lifetime    string
		SigValidity string
	}
	CSK struct {
		Lifetime    string
		SigValidity string
	}
}

DnssecPolicyConf should match the configuration

type DsyncResult

type DsyncResult struct {
	Qname  string
	Rdata  []*core.DSYNC
	Parent string
	Error  error
}

type DsyncTarget

type DsyncTarget struct {
	Name      string
	Scheme    core.DsyncScheme
	Port      uint16
	Addresses []string // in addr:port format
	RR        *core.DSYNC
}

type DynamicCatalogMemberConf

type DynamicCatalogMemberConf struct {
	Allowed bool   `yaml:"allowed" mapstructure:"allowed"`                                              // Whether catalog member zones are allowed
	Storage string `yaml:"storage" mapstructure:"storage" validate:"omitempty,oneof=memory persistent"` // "memory" or "persistent"
	Add     string `yaml:"add" mapstructure:"add" validate:"omitempty,oneof=auto manual"`               // "auto" or "manual" - Enable auto-configuration from catalog
	Remove  string `yaml:"remove" mapstructure:"remove" validate:"omitempty,oneof=auto manual"`         // "auto" or "manual" - Whether to remove zones when deleted from catalog
}

DynamicCatalogMemberConf defines configuration for catalog member zones (includes add/remove policy)

type DynamicConfigFile

type DynamicConfigFile struct {
	Zones []ZoneConf `yaml:"zones"`
}

DynamicConfigFile represents the structure of the dynamic zones config file

type DynamicZoneTypeConf

type DynamicZoneTypeConf struct {
	Allowed bool   `yaml:"allowed" mapstructure:"allowed"`                                              // Whether this type of zone is allowed
	Storage string `yaml:"storage" mapstructure:"storage" validate:"omitempty,oneof=memory persistent"` // "memory" or "persistent"
}

DynamicZoneTypeConf defines configuration for a type of dynamic zone

type DynamicZonesConf

type DynamicZonesConf struct {
	ConfigFile     string                   `yaml:"configfile" mapstructure:"configfile"`           // Absolute path to dynamic config file
	ZoneDirectory  string                   `yaml:"zonedirectory" mapstructure:"zonedirectory"`     // Absolute path to zone file directory
	CatalogZones   DynamicZoneTypeConf      `yaml:"catalog_zones" mapstructure:"catalog_zones"`     // Configuration for catalog zones
	CatalogMembers DynamicCatalogMemberConf `yaml:"catalog_members" mapstructure:"catalog_members"` // Configuration for catalog member zones
	Dynamic        DynamicZoneTypeConf      `yaml:"dynamic" mapstructure:"dynamic"`                 // Configuration for direct API-created zones (future)
}

DynamicZonesConf defines configuration for dynamically created zones (catalog zones, catalog members, etc.)

type EngineFunc

type EngineFunc func(ctx context.Context) error

EngineFunc is the function signature for registered engines. Engines are long-running goroutines that run until the context is cancelled. They should return nil when the context is cancelled, or an error if they fail.

type EngineRegistration

type EngineRegistration struct {
	Name   string
	Engine EngineFunc
}

EngineRegistration stores an engine registration

type ErrorType

type ErrorType uint8
const (
	NoError ErrorType = iota
	ConfigError
	RefreshError
	AgentError
	DnssecError
)

type GlobalStuff

type GlobalStuff struct {
	// IMR         string  // trying to get rid of this, use Imr instead
	ImrEngine   *Imr
	Verbose     bool
	Debug       bool
	Zonename    string
	AgentId     AgentId
	ParentZone  string
	Sig0Keyfile string
	Api         *ApiClient
	ApiClients  map[string]*ApiClient // tdns-cli has multiple clients
	PingCount   int
	Slurp       bool
	Algorithm   string
	Rrtype      string
	ShowHeaders bool // -H in various CLI commands
	BaseUri     string
	Port        uint16
	Address     string
	App         AppDetails
	ServerSVCB  *dns.SVCB // ALPN for DoH/DoQ
	TsigKeys    map[string]*TsigDetails
}

func (*GlobalStuff) Validate

func (gs *GlobalStuff) Validate() error

type GroupPrefixesConf

type GroupPrefixesConf struct {
	Config  string `yaml:"config" mapstructure:"config" validate:"required"`   // Prefix for config/transfer groups, or "none" to disable
	Signing string `yaml:"signing" mapstructure:"signing" validate:"required"` // Prefix for signing groups, or "none" to disable
}

GroupPrefixesConf defines prefixes that identify special group types in catalog zones

type HsyncAgentStatus

type HsyncAgentStatus struct {
	Identity    string
	LastContact time.Time
	State       string   // "discovered", "contact_attempted", "connected", "failed"
	LastError   string   // If state is "failed"
	Endpoints   []string // Discovered API/DNS endpoints
}

HsyncAgentStatus represents the current status of a remote agent

type HsyncStatus

type HsyncStatus struct {
	Time         time.Time
	ZoneName     string
	Command      string
	Status       bool
	Error        bool
	ErrorMsg     string
	Msg          string
	HsyncAdds    []dns.RR // Changed from Adds
	HsyncRemoves []dns.RR // Changed from Removes
}

type Imr

type Imr struct {
	Cache       *cache.RRsetCacheT
	DnskeyCache *cache.DnskeyCacheT
	Options     map[ImrOption]string
	LineWidth   int // used to truncate long lines in logging and output (eg. DNSKEYs and RRSIGs)
	Verbose     bool
	Debug       bool
	Quiet       bool // if true, suppress informational logging (useful for CLI tools)
}

func (*Imr) AuthDNSQuery

func (imr *Imr) AuthDNSQuery(ctx context.Context, qname string, qtype uint16, nameservers []string,
	lg *log.Logger, verbose bool) (*core.RRset, int, cache.CacheContext, error)

func (*Imr) CollectNSAddresses

func (imr *Imr) CollectNSAddresses(ctx context.Context, rrset *core.RRset, respch chan *ImrResponse) error

CollectNSAddresses - given an NS RRset, chase down the A and AAAA records corresponding to each nsname

func (*Imr) DefaultDNSKEYFetcher

func (imr *Imr) DefaultDNSKEYFetcher(ctx context.Context, name string) (*core.RRset, error)

func (*Imr) DefaultRRsetFetcher

func (imr *Imr) DefaultRRsetFetcher(ctx context.Context, qname string, qtype uint16) (*core.RRset, error)

func (*Imr) DsyncDiscovery

func (imr *Imr) DsyncDiscovery(ctx context.Context, child string, verbose bool) (DsyncResult, error)

func (*Imr) ImrQuery

func (imr *Imr) ImrQuery(ctx context.Context, qname string, qtype uint16, qclass uint16, respch chan *ImrResponse) (*ImrResponse, error)

func (*Imr) ImrResponder

func (imr *Imr) ImrResponder(ctx context.Context, w dns.ResponseWriter, r *dns.Msg, qname string, qtype uint16, msgoptions *edns0.MsgOptions)

func (*Imr) IterativeDNSQuery

func (imr *Imr) IterativeDNSQuery(ctx context.Context, qname string, qtype uint16, serverMap map[string]*cache.AuthServer, force bool, requireEncrypted bool) (*core.RRset, int, cache.CacheContext, core.Transport, error)

force is true if we should force a lookup even if the answer is in the cache visitedZones tracks which zones we've been referred to for this qname to prevent referral loops requireEncrypted is true if PR flag is set and only encrypted transports should be used Returns: rrset, rcode, context, transport, error

func (*Imr) IterativeDNSQueryFetcher

func (imr *Imr) IterativeDNSQueryFetcher() cache.RRsetFetcher

IterativeDNSQueryFetcher adapts IterativeDNSQuery to the RRsetFetcher interface. It discards the rcode and CacheContext return values, only returning the RRset and error.

func (*Imr) IterativeDNSQueryWithLoopDetection

func (imr *Imr) IterativeDNSQueryWithLoopDetection(ctx context.Context, qname string, qtype uint16, serverMap map[string]*cache.AuthServer, force bool, visitedZones map[string]bool, requireEncrypted bool) (*core.RRset, int, cache.CacheContext, core.Transport, error)

IterativeDNSQueryWithLoopDetection is the internal implementation with loop detection visitedZones tracks which zones we've been referred to for this qname (format: "qname:zone") requireEncrypted is true if PR flag is set and only encrypted transports should be used Returns: rrset, rcode, context, transport, error

func (*Imr) LookupDSYNCTarget

func (imr *Imr) LookupDSYNCTarget(ctx context.Context, childzone string, dtype uint16, scheme core.DsyncScheme) (*DsyncTarget, error)

dtype = the type of DSYNC RR to look for (dns.TypeCDS, dns.TypeCSYNC, dns.TypeANY, ...) scheme = the DSYNC scheme (SchemeNotify | SchemeUpdate)

func (*Imr) ParentZone

func (imr *Imr) ParentZone(z string) (string, error)

func (*Imr) ParseAdditionalForNSAddrs

func (imr *Imr) ParseAdditionalForNSAddrs(ctx context.Context, src string, nsrrset *core.RRset, zonename string,
	nsMap map[string]bool, r *dns.Msg) (map[string]*cache.AuthServer, error)

func (*Imr) ProcessAuthDNSResponse

func (imr *Imr) ProcessAuthDNSResponse(ctx context.Context, qname string, qtype uint16, rrset *core.RRset, rcode int, context cache.CacheContext, msgoptions *edns0.MsgOptions, m *dns.Msg, w dns.ResponseWriter, r *dns.Msg, transport core.Transport) (bool, error)

returns true if we have a response (i.e. we're done), false if we have an error all errors are treated as "done"

func (*Imr) SendRfc9567ErrorReport

func (imr *Imr) SendRfc9567ErrorReport(ctx context.Context, qname string, qtype uint16, ede_code uint16, msgoptions *edns0.MsgOptions) error

func (*Imr) StartImrEngineListeners

func (imr *Imr) StartImrEngineListeners(ctx context.Context, conf *Config) error

func (*Imr) TransportSignalCached

func (imr *Imr) TransportSignalCached(owner string) bool

func (*Imr) TransportSignalRRType

func (imr *Imr) TransportSignalRRType() uint16

type ImrEngineConf

type ImrEngineConf struct {
	Active      *bool                `yaml:"active" mapstructure:"active"`         // If nil or true, IMR is active. Only false explicitly disables it.
	RootHints   string               `yaml:"root-hints" mapstructure:"root-hints"` // Path to root hints file. If empty, uses compiled-in hints.
	Addresses   []string             `yaml:"addresses" mapstructure:"addresses" validate:"required"`
	CertFile    string               `yaml:"certfile" mapstructure:"certfile"`
	KeyFile     string               `yaml:"keyfile" mapstructure:"keyfile"`
	Transports  []string             `yaml:"transports" mapstructure:"transports" validate:"required"` // "do53", "dot", "doh", "doq"
	Stubs       []ImrStubConf        `yaml:"stubs"`
	OptionsStrs []string             `yaml:"options" mapstructure:"options"`
	Options     map[ImrOption]string `yaml:"-" mapstructure:"-"`
	// Trust anchors for recursive validation. Provide either DS or DNSKEY as
	// full RR text (zonefile format). DS is preferred as it is more convenient.
	TrustAnchorDS     string `yaml:"trust_anchor_ds"`
	TrustAnchorDNSKEY string `yaml:"trust_anchor_dnskey"`
	// Unbound-style file with one RR per line (DNSKEY and/or DS). Absolute path.
	TrustAnchorFile string `yaml:"trust-anchor-file"`
	Verbose         bool
	Debug           bool
}

type ImrOption

type ImrOption uint8
const (
	ImrOptRevalidateNS ImrOption = iota + 1
	ImrOptQueryForTransport
	ImrOptAlwaysQueryForTransport
	ImrOptTransportSignalType
	ImrOptQueryForTransportTLSA
	ImrOptUseTransportSignals
)

type ImrRequest

type ImrRequest struct {
	Qname      string
	Qtype      uint16
	Qclass     uint16
	ResponseCh chan ImrResponse
}

type ImrResponse

type ImrResponse struct {
	RRset     *core.RRset
	Validated bool
	Error     bool
	ErrorMsg  string
	Msg       string
}

type ImrStubConf

type ImrStubConf struct {
	Zone string `validate:"required"`
	// Servers []StubServerConf `validate:"required"`
	Servers []cache.AuthServer `validate:"required"`
}

type InternalConf

type InternalConf struct {
	CfgFile             string //
	DebugMode           bool   // if true, may activate dangerous tests
	ZonesCfgFile        string //
	CertData            string // PEM encoded certificate
	KeyData             string // PEM encoded key
	KeyDB               *KeyDB
	AllZones            []string
	DnssecPolicies      map[string]DnssecPolicy
	StopCh              chan struct{}
	APIStopCh           chan struct{}
	StopOnce            sync.Once
	RefreshZoneCh       chan ZoneRefresher
	BumpZoneCh          chan BumperData
	ValidatorCh         chan ValidatorRequest
	RecursorCh          chan ImrRequest
	ScannerQ            chan ScanRequest
	UpdateQ             chan UpdateRequest
	DeferredUpdateQ     chan DeferredUpdate
	DnsUpdateQ          chan DnsUpdateRequest
	DnsNotifyQ          chan DnsNotifyRequest
	DnsQueryQ           chan DnsQueryRequest           // Optional: if nil, queries use direct call to QueryResponder
	QueryHandlers       map[uint16][]QueryHandlerFunc  // qtype -> list of handlers (registered via RegisterQueryHandler)
	QueryHandlersMutex  sync.RWMutex                   // protects QueryHandlers map
	NotifyHandlers      map[uint16][]NotifyHandlerFunc // qtype -> list of handlers (registered via RegisterNotifyHandler, 0 = all NOTIFYs)
	NotifyHandlersMutex sync.RWMutex                   // protects NotifyHandlers map
	UpdateHandlers      []UpdateHandlerRegistration    // UPDATE handlers (registered via RegisterUpdateHandler)
	UpdateHandlersMutex sync.RWMutex                   // protects UpdateHandlers slice
	DelegationSyncQ     chan DelegationSyncRequest
	MusicSyncQ          chan MusicSyncRequest
	NotifyQ             chan NotifyRequest
	AuthQueryQ          chan AuthQueryRequest
	ResignQ             chan *ZoneData // the names of zones that should be kept re-signed should be sent into this channel
	SyncQ               chan SyncRequest
	AgentQs             *AgentQs // aggregated channels for agent communication
	SyncStatusQ         chan SyncStatus
	AgentRegistry       *AgentRegistry
	ZoneDataRepo        *ZoneDataRepo
	RRsetCache          *cache.RRsetCacheT // ConcurrentMap of cached RRsets from queries
	ImrEngine           *Imr
	KdcDB               interface{} // *kdc.KdcDB - using interface{} to avoid circular import
	KdcConf             interface{} // *kdc.KdcConf - using interface{} to avoid circular import
	KrsDB               interface{} // *krs.KrsDB - using interface{} to avoid circular import
	KrsConf             interface{} // *krs.KrsConf - using interface{} to avoid circular import
	Scanner             *Scanner    // Scanner instance for async job tracking
}

type Ixfr

type Ixfr struct {
	FromSerial uint32
	ToSerial   uint32
	Removed    []core.RRset
	Added      []core.RRset
}

type KeyBootstrapperRequest

type KeyBootstrapperRequest struct {
	Cmd          string
	KeyName      string
	ZoneName     string
	ZoneData     *ZoneData
	Key          string
	Verified     bool
	Keyid        uint16
	ResponseChan chan *VerificationInfo
}

type KeyConf

type KeyConf struct {
	Tsig []TsigDetails
}

type KeyDB

type KeyDB struct {
	DB *sql.DB

	// Sig0Cache   map[string]*Sig0KeyCache
	KeystoreSig0Cache   map[string]*Sig0ActiveKeys
	TruststoreSig0Cache *Sig0StoreT            // was *Sig0StoreT
	KeystoreDnskeyCache map[string]*DnssecKeys // map[zonename]*DnssecActiveKeys
	Ctx                 string
	UpdateQ             chan UpdateRequest
	DeferredUpdateQ     chan DeferredUpdate
	KeyBootstrapperQ    chan KeyBootstrapperRequest
	Options             map[AuthOption]string
	// contains filtered or unexported fields
}

func NewKeyDB

func NewKeyDB(dbfile string, force bool, options map[AuthOption]string) (*KeyDB, error)

NewKeyDB creates and initializes a KeyDB backed by the sqlite3 file at dbfile. It validates that dbfile is provided, ensures the file is writable, opens the sqlite3 database, and sets up required tables. If force is true, existing default tables are dropped before setup. On success it returns a KeyDB with caches, an update channel, and Options set to the provided map; on failure it returns an error describing the problem.

func (*KeyDB) APIkeystore

func (kdb *KeyDB) APIkeystore() func(w http.ResponseWriter, r *http.Request)

func (*KeyDB) APItruststore

func (kdb *KeyDB) APItruststore() func(w http.ResponseWriter, r *http.Request)

func (*KeyDB) ApplyChildUpdateToDB

func (kdb *KeyDB) ApplyChildUpdateToDB(ur UpdateRequest) error

func (*KeyDB) ApplyZoneUpdateToDB

func (kdb *KeyDB) ApplyZoneUpdateToDB(ur UpdateRequest) error

func (*KeyDB) Begin

func (db *KeyDB) Begin(context string) (*Tx, error)

func (*KeyDB) Close

func (db *KeyDB) Close() error

func (*KeyDB) CreateAutoZone

func (kdb *KeyDB) CreateAutoZone(zonename string, addrs []string) (*ZoneData, error)

func (*KeyDB) DeferredUpdaterEngine

func (kdb *KeyDB) DeferredUpdaterEngine(ctx context.Context) error

func (*KeyDB) DelegationSyncher

func (kdb *KeyDB) DelegationSyncher(ctx context.Context, delsyncq chan DelegationSyncRequest, notifyq chan NotifyRequest, conf *Config) error

func (*KeyDB) DnssecKeyMgmt

func (kdb *KeyDB) DnssecKeyMgmt(tx *Tx, kp KeystorePost) (*KeystoreResponse, error)

func (*KeyDB) Exec

func (db *KeyDB) Exec(query string, args ...interface{}) (sql.Result, error)

func (*KeyDB) GenerateKeypair

func (kdb *KeyDB) GenerateKeypair(owner, creator, state string, rrtype uint16, alg uint8, keytype string, tx *Tx) (*PrivateKeyCache, string, error)

XXX: FIXME: This is not yet ready to generate DNSSEC keys, because in the DNSSEC case we also need the

flags field, which is not yet set here.

func (*KeyDB) GetDnssecKeys

func (kdb *KeyDB) GetDnssecKeys(zonename, state string) (*DnssecKeys, error)

func (*KeyDB) GetKeyStatus

func (kdb *KeyDB) GetKeyStatus(zonename string, keyID uint16) (*edns0.KeyStateOption, error)

func (*KeyDB) GetSig0Keys

func (kdb *KeyDB) GetSig0Keys(zonename, state string) (*Sig0ActiveKeys, error)

func (*KeyDB) HandleKeyStateOption

func (kdb *KeyDB) HandleKeyStateOption(opt *dns.OPT, zonename string) (*dns.EDNS0_LOCAL, error)

func (*KeyDB) KeyBootstrapper

func (kdb *KeyDB) KeyBootstrapper(ctx context.Context) error

func (*KeyDB) LoadDnskeyTrustAnchors

func (kdb *KeyDB) LoadDnskeyTrustAnchors() error

XXX: This should die now that we have a real IMR

func (*KeyDB) LoadSig0ChildKeys

func (kdb *KeyDB) LoadSig0ChildKeys() error

func (*KeyDB) Prepare

func (db *KeyDB) Prepare(q string) (*sql.Stmt, error)

func (*KeyDB) ProcessKeyState

func (kdb *KeyDB) ProcessKeyState(ks *edns0.KeyStateOption, zonename string) (*edns0.KeyStateOption, error)

func (*KeyDB) PromoteDnssecKey

func (kdb *KeyDB) PromoteDnssecKey(zonename string, keyid uint16, oldstate, newstate string) error

func (*KeyDB) Query

func (db *KeyDB) Query(query string, args ...interface{}) (*sql.Rows, error)

func (*KeyDB) QueryRow

func (db *KeyDB) QueryRow(query string, args ...interface{}) *sql.Row

func (*KeyDB) SendSig0KeyUpdate

func (kdb *KeyDB) SendSig0KeyUpdate(ctx context.Context, childpri, parpri string, gennewkey bool) error

XXX: FIXME: This is only used from the CLI. It should change into code used by TDNS-SERVER and

accessed via API. The code should store the newly generated key in the keystore.

func (*KeyDB) Sig0KeyMgmt

func (kdb *KeyDB) Sig0KeyMgmt(tx *Tx, kp KeystorePost) (*KeystoreResponse, error)

func (*KeyDB) Sig0TrustMgmt

func (kdb *KeyDB) Sig0TrustMgmt(tx *Tx, tp TruststorePost) (*TruststoreResponse, error)

func (*KeyDB) UpdateKeyState

func (kdb *KeyDB) UpdateKeyState(ctx context.Context, KeyName string, keyid uint16, kkeybootstrapperq chan<- KeyBootstrapperRequest, algorithm uint8) error

func (*KeyDB) ZoneUpdaterEngine

func (kdb *KeyDB) ZoneUpdaterEngine(ctx context.Context) error

type KeyLifetime

type KeyLifetime struct {
	Lifetime    uint32
	SigValidity uint32
}

func GenKeyLifetime

func GenKeyLifetime(lifetime, sigvalidity string) KeyLifetime

type KeystorePost

type KeystorePost struct {
	Command         string // "sig0"
	SubCommand      string // "list" | "add" | "delete" | ...
	Zone            string
	Keyname         string
	Keyid           uint16
	Flags           uint16
	KeyType         string
	Algorithm       uint8 // RSASHA256 | ED25519 | etc.
	PrivateKey      string
	KeyRR           string
	DnskeyRR        string
	PrivateKeyCache *PrivateKeyCache
	State           string
	ParentState     uint8
	Creator         string
}

type KeystoreResponse

type KeystoreResponse struct {
	AppName  string
	Time     time.Time
	Status   string
	Zone     string
	Dnskeys  map[string]DnssecKey // TrustAnchor
	Sig0keys map[string]Sig0Key
	Msg      string
	Error    bool
	ErrorMsg string
}

type LocalAgentApiConf

type LocalAgentApiConf struct {
	Addresses struct {
		Publish []string
		Listen  []string
	}
	BaseUrl  string
	Port     uint16
	CertFile string
	KeyFile  string
	CertData string
	KeyData  string
}

type LocalAgentConf

type LocalAgentConf struct {
	Identity string `validate:"required,hostname"`
	Local    struct {
		Notify []string // secondaries to notify for an agent autozone
	}
	Remote struct {
		LocateInterval int    // time in seconds
		BeatInterval   uint32 // time between outgoing heartbeats to same destination
	}
	Api LocalAgentApiConf
	Dns LocalAgentDnsConf
	Xfr struct {
		Outgoing struct {
			Addresses []string `yaml:"addresses,omitempty"`
			Auth      []string `yaml:"auth,omitempty"`
		}
		Incoming struct {
			Addresses []string `yaml:"addresses,omitempty"`
			Auth      []string `yaml:"auth,omitempty"`
		}
	}
}

type LocalAgentDnsConf

type LocalAgentDnsConf struct {
	Addresses struct {
		Publish []string
		Listen  []string
	}
	BaseUrl string
	Port    uint16
}

type MSCAPIConf

type MSCAPIConf struct {
	BaseURL    string `validate:"required,url"`
	ApiKey     string `validate:"required_if=AuthMethod apikey"`
	AuthMethod string `validate:"required,oneof=none apikey"`
	UseTLS     bool   `validate:"required"`
}

type MSCNotifyConf

type MSCNotifyConf struct {
	Addresses []string `validate:"required"` // XXX: must not be in addr:port format
	Port      string   `validate:"required"`
	Targets   []string
}

type MemberZone

type MemberZone struct {
	ZoneName      string    `json:"zone_name"`
	Hash          string    `json:"hash"`
	ServiceGroups []string  `json:"service_groups"` // Groups associated with this zone (RFC 9432 terminology)
	SigningGroup  string    `json:"signing_group"`  // Signing group for this zone
	MetaGroup     string    `json:"meta_group"`     // Meta group for this zone
	DiscoveredAt  time.Time `json:"discovered_at"`
}

MemberZone represents a zone discovered in a catalog zone

type MetaGroupConfig

type MetaGroupConfig = ConfigGroupConfig

MetaGroupConfig is deprecated, use ConfigGroupConfig instead

type MultiSignerConf

type MultiSignerConf struct {
	Name       string
	Controller MultiSignerController
}

type MultiSignerController

type MultiSignerController struct {
	Name   string
	Notify MSCNotifyConf
	API    MSCAPIConf
}

type MultiSignerPost

type MultiSignerPost struct {
	Command string // "fetch-rrset" | "update" | "remove-rrset"
	Zone    string
	Name    string
	Type    uint16
}

type MultiSignerResponse

type MultiSignerResponse struct {
	AppName  string
	Time     time.Time
	RRset    core.RRset
	Msg      string
	Error    bool
	ErrorMsg string
}

type MusicSyncRequest

type MusicSyncRequest struct {
	Command         string
	ZoneName        string
	ZoneData        *ZoneData
	OldDnskeys      *core.RRset
	NewDnskeys      *core.RRset
	MusicSyncStatus *MusicSyncStatus
	Response        chan MusicSyncStatus // used for API-based requests
}

type MusicSyncStatus

type MusicSyncStatus struct {
	ZoneName       string
	MsignerAdds    []dns.RR
	MsignerRemoves []dns.RR
	DnskeyAdds     []dns.RR
	DnskeyRemoves  []dns.RR
	Msg            string
	Error          bool
	ErrorMsg       string
	Status         bool
}

type NotifyHandlerFunc

type NotifyHandlerFunc func(ctx context.Context, req *DnsNotifyRequest) error

NotifyHandlerFunc is the function signature for registered NOTIFY handlers. Returns ErrNotHandled if the handler doesn't handle this NOTIFY (allows fallthrough). Returns nil if the handler successfully handled the NOTIFY. Returns other error if handler attempted to handle but encountered an error.

type NotifyRequest

type NotifyRequest struct {
	ZoneName string
	ZoneData *ZoneData
	RRtype   uint16
	Targets  []string // []addr:port
	Urgent   bool
	Response chan NotifyResponse
}

type NotifyResponse

type NotifyResponse struct {
	Msg      string
	Rcode    int
	Error    bool
	ErrorMsg string
}

type NotifyStatus

type NotifyStatus struct {
	Zone          string // zone that the update applies to
	ChildZone     string // zone that the update applies to
	Type          uint16 // CDS | CSYNC | DNSKEY | DELEG
	ScanStatus    string // "ok" | "changed" | "failed"
	SafetyChecked bool   // true if the update has been safety checked
	PolicyChecked bool   // true if the update has been policy checked
	Approved      bool   // true if the update has been approved
	Msg           string
	Error         bool
	ErrorMsg      string
	Status        bool
}

type OwnerData

type OwnerData struct {
	Name    string
	RRtypes *RRTypeStore
}

func NewOwnerData

func NewOwnerData(name string) *OwnerData

type Owners

type Owners []OwnerData

func (Owners) Len

func (owners Owners) Len() int

func (Owners) Less

func (owners Owners) Less(i, j int) bool

func (Owners) Swap

func (owners Owners) Swap(i, j int)

type PingPost

type PingPost struct {
	Msg   string
	Pings int
}

type PingResponse

type PingResponse struct {
	Time       time.Time
	Client     string
	BootTime   time.Time
	Version    string
	ServerHost string // "master.dnslab"
	Daemon     string // "tdnsd"
	Msg        string
	Pings      int
	Pongs      int
}

type PrivateKeyCache

type PrivateKeyCache struct {
	K          crypto.PrivateKey
	PrivateKey string // This is only used when reading from file with ReadKeyNG()
	CS         crypto.Signer
	RR         dns.RR
	KeyType    uint16
	Algorithm  uint8
	KeyId      uint16
	KeyRR      dns.KEY
	DnskeyRR   dns.DNSKEY
}

Migrating all DB access to own interface to be able to have local receiver functions.

func LoadSig0SigningKey

func LoadSig0SigningKey(keyfile string) (*PrivateKeyCache, error)

func PrepareKeyCache

func PrepareKeyCache(privkey, pubkey string) (*PrivateKeyCache, error)

func ReadPrivateKey

func ReadPrivateKey(filename string) (*PrivateKeyCache, error)

type QueryHandlerFunc

type QueryHandlerFunc func(ctx context.Context, req *DnsQueryRequest) error

QueryHandlerFunc is the function signature for registered query handlers. Returns ErrNotHandled if the handler doesn't handle this query (allows fallthrough). Returns nil if the handler successfully handled the query. Returns other error if handler attempted to handle but encountered an error.

type RRTypeStore

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

func NewRRTypeStore

func NewRRTypeStore() *RRTypeStore

func (*RRTypeStore) Count

func (s *RRTypeStore) Count() int

func (*RRTypeStore) Delete

func (s *RRTypeStore) Delete(key uint16)

func (*RRTypeStore) Get

func (s *RRTypeStore) Get(key uint16) (core.RRset, bool)

func (*RRTypeStore) GetOnlyRRSet

func (s *RRTypeStore) GetOnlyRRSet(key uint16) core.RRset

func (*RRTypeStore) Keys

func (s *RRTypeStore) Keys() []uint16

func (*RRTypeStore) Set

func (s *RRTypeStore) Set(key uint16, value core.RRset)

type RRsetString

type RRsetString struct {
	Name   string   `json:"name"`
	RRtype uint16   `json:"rrtype"`
	RRs    []string `json:"rrs"`
	RRSIGs []string `json:"rrsigs,omitempty"`
}

String-based versions of RRset for JSON marshaling

type RefreshCounter

type RefreshCounter struct {
	Name           string
	SOARefresh     uint32
	CurRefresh     uint32
	IncomingSerial uint32
	Upstream       string
	Downstreams    []string
	Zonefile       string
}

type RefresherResponse

type RefresherResponse struct {
	Time     time.Time
	Zone     string
	Msg      string
	Error    bool
	ErrorMsg string
}

type RfiData

type RfiData struct {
	Status      string // ok | error | ...
	Time        time.Time
	Msg         string
	Error       bool
	ErrorMsg    string
	ZoneXfrSrcs []string
	ZoneXfrAuth []string
	ZoneXfrDsts []string
}

type ScanJobStatus

type ScanJobStatus struct {
	JobID           string              `json:"job_id"`
	Status          string              `json:"status"` // "queued", "processing", "completed", "failed"
	CreatedAt       time.Time           `json:"created_at"`
	StartedAt       *time.Time          `json:"started_at,omitempty"`
	CompletedAt     *time.Time          `json:"completed_at,omitempty"`
	TotalTuples     int                 `json:"total_tuples"`
	IgnoredTuples   int                 `json:"ignored_tuples"`
	ErrorTuples     int                 `json:"error_tuples"`
	ProcessedTuples int                 `json:"processed_tuples"`
	Responses       []ScanTupleResponse `json:"responses,omitempty"`
	Error           bool                `json:"error,omitempty"`
	ErrorMsg        string              `json:"error_msg,omitempty"`
}

ScanJobStatus represents the status of a scan job

type ScanRequest

type ScanRequest struct {
	Cmd              string
	ParentZone       string
	ScanZones        []string
	ScanType         ScanType // "cds" | "csync" | "dnskey"
	ScanTuples       []ScanTuple
	ChildZone        string
	CurrentChildData ChildDelegationData // Current parent-side delegation data for child
	ZoneData         *ZoneData
	RRtype           uint16
	Edns0Options     *edns0.MsgOptions
	Response         chan ScanResponse
	JobID            string // Job ID for async processing
}

type ScanResponse

type ScanResponse struct {
	Time     time.Time
	Zone     string
	RRtype   uint16
	RRset    core.RRset
	Msg      string
	Error    bool
	ErrorMsg string
}

type ScanTuple

type ScanTuple struct {
	Zone string // zone to scan	//
	// Type ScanType	// type of test to perform	// ScanRRtype | ScanCSYNC | ScanDNSKEY
	CurrentData CurrentScanData // current data for the test
	Options     []string        // "all-ns", ...
}

type ScanTupleResponse

type ScanTupleResponse struct {
	Qname       string              // The qname that was queried
	ScanType    ScanType            // The type of scan performed
	Options     []string            // Options that were used (e.g., "all-ns")
	NewData     CurrentScanDataJSON // The new data retrieved from the scan (JSON-serializable)
	DataChanged bool                // Whether the new data differs from the old data (from ScanTuple.CurrentData)
	AllNSInSync bool                // If "all-ns" option was set, whether all NS were in sync (false if not applicable)
	Error       bool                // Whether an error occurred
	ErrorMsg    string              // Error message if Error is true
}

ScanTupleResponse contains the result of scanning a single ScanTuple

type ScanType

type ScanType uint8

ScanType represents the type of test to perform during scanning

const (
	ScanRRtype ScanType = iota + 1
	ScanCDS
	ScanCSYNC
	ScanDNSKEY
)

type Scanner

type Scanner struct {
	// Conf  *Config
	// LabDB *LabDB
	// RRtype  string
	AuthQueryQ chan AuthQueryRequest
	// IMR         string
	ImrEngine   *Imr
	LogFile     string
	LogTemplate string
	Log         map[string]*log.Logger
	Verbose     bool
	Debug       bool
	// Job storage for async scan requests
	Jobs      map[string]*ScanJobStatus
	JobsMutex sync.RWMutex
}

func NewScanner

func NewScanner(authqueryq chan AuthQueryRequest, verbose, debug bool) *Scanner

func (*Scanner) AddLogger

func (scanner *Scanner) AddLogger(rrtype string) error

func (*Scanner) AuthQueryNG

func (scanner *Scanner) AuthQueryNG(qname, ns string, rrtype uint16, transport string) (*core.RRset, error)

func (*Scanner) CheckCDS

func (scanner *Scanner) CheckCDS(ctx context.Context, tuple ScanTuple, scanType ScanType, options *edns0.MsgOptions, responseCh chan<- ScanTupleResponse)

func (*Scanner) CheckCSYNC

func (scanner *Scanner) CheckCSYNC(sr ScanRequest, cdd *ChildDelegationData) (*ChildDelegationData, error)

func (*Scanner) CheckCSYNC_NG

func (scanner *Scanner) CheckCSYNC_NG(ctx context.Context, tuple ScanTuple, scanType ScanType, options *edns0.MsgOptions, responseCh chan<- ScanTupleResponse)

func (*Scanner) CheckDNSKEY

func (scanner *Scanner) CheckDNSKEY(ctx context.Context, tuple ScanTuple, scanType ScanType, options *edns0.MsgOptions, responseCh chan<- ScanTupleResponse)

func (*Scanner) CsyncAnalyzeA

func (scanner *Scanner) CsyncAnalyzeA(zone string, new_nsrrs []*dns.NS, cdd *ChildDelegationData) ([]dns.RR, bool, error)

func (*Scanner) CsyncAnalyzeAAAA

func (scanner *Scanner) CsyncAnalyzeAAAA(zone string, new_nsrrs []*dns.NS, cdd *ChildDelegationData) ([]dns.RR, bool, error)

func (*Scanner) CsyncAnalyzeNS

func (scanner *Scanner) CsyncAnalyzeNS(zone string, cdd *ChildDelegationData) ([]dns.RR, bool, error)

Returns: new_rrs, changed=true, error

func (*Scanner) UpdateCsyncStatus

func (scanner *Scanner) UpdateCsyncStatus(zone string, csyncrr *dns.CSYNC) error

func (*Scanner) ZoneCSYNCKnown

func (scanner *Scanner) ZoneCSYNCKnown(zone string, csyncrr *dns.CSYNC) bool

type ScannerPost

type ScannerPost struct {
	Command    string      // "scan" | "status"
	ParentZone string      // Legacy field
	ScanZones  []string    // Legacy field
	ScanType   ScanType    // Legacy field: "cds" | "csync" | "dnskey"
	ScanTuples []ScanTuple // New field: list of scan tuples for scan requests
}

type ScannerResponse

type ScannerResponse struct {
	AppName  string
	Time     time.Time
	Status   string
	Msg      string
	Error    bool
	ErrorMsg string
	JobID    string `json:"job_id,omitempty"` // Job ID for async scan requests
}

type ServerAddrTuple

type ServerAddrTuple struct {
	Server *cache.AuthServer
	Addr   string
	NSName string
}

ServerAddrTuple represents a (server, address) pair for prioritization

type ServiceConf

type ServiceConf struct {
	Name       string `validate:"required"`
	Debug      *bool
	Verbose    *bool
	Identities []string      // this is a strawman attempt at deciding on what name to publish the ALPN
	Transport  TransportConf `yaml:"transport"`
}

type ShowAPIresponse

type ShowAPIresponse struct {
	Status int
	Msg    string
	Data   []string
}

type Sig0ActiveKeys

type Sig0ActiveKeys struct {
	Keys []*PrivateKeyCache
}

type Sig0Key

type Sig0Key struct {
	Name            string
	State           string
	Keyid           uint16
	Algorithm       string
	Creator         string
	Validated       bool   // has this key been validated
	PublishedInDNS  bool   // is this key published in DNS (as a KEY RR)
	DnssecValidated bool   // has this key been DNSSEC validated
	Trusted         bool   // is this key trusted
	Source          string // "dns" | "file" | "keystore" | "child-update"
	PrivateKey      string //
	Key             dns.KEY
	Keystr          string
}

type Sig0StoreT

type Sig0StoreT struct {
	Map cmap.ConcurrentMap[string, Sig0Key]
}

func NewSig0StoreT

func NewSig0StoreT() *Sig0StoreT

type Sig0UpdateSigner

type Sig0UpdateSigner struct {
	Name      string   // from the SIG
	KeyId     uint16   // from the SIG
	Sig0Key   *Sig0Key // a key that matches the signer name and keyid
	Validated bool     // true if this key validated the update
}

A Signer is a struct where we keep track of the signer name and keyid for a DNS UPDATE message.

type Sig0tmp

type Sig0tmp map[string]TmpSig0Key

type SigningGroupInfo

type SigningGroupInfo struct {
	Description string `yaml:"description" mapstructure:"description"`
}

SigningGroupInfo provides documentation for signing groups (RFC 9432 terminology)

type SyncRequest

type SyncRequest struct {
	Command    string
	ZoneName   ZoneName
	ZoneData   *ZoneData
	SyncStatus *HsyncStatus
	OldDnskeys *core.RRset
	NewDnskeys *core.RRset
	Response   chan SyncResponse
}

type SyncResponse

type SyncResponse struct {
	Status   bool
	Error    bool
	ErrorMsg string
	Msg      string
}

type SyncStatus

type SyncStatus struct {
	Identity AgentId
	Agents   map[AgentId]*Agent
	Error    bool
	Response chan SyncStatus
}

type SynchedDataCmd

type SynchedDataCmd struct {
	Cmd      string
	Zone     ZoneName
	Response chan *SynchedDataCmdResponse
}

type SynchedDataCmdResponse

type SynchedDataCmdResponse struct {
	Cmd      string
	Msg      string
	Error    bool
	ErrorMsg string
	Zone     ZoneName
	// ZDR      map[ZoneName]map[AgentId]*OwnerData
	ZDR map[ZoneName]map[AgentId]map[uint16][]string
}

type SynchedDataResponse

type SynchedDataResponse struct {
	Zone    ZoneName
	AgentId AgentId
	Time    time.Time
	Msg     string
	// RfiType     string
	RfiResponse RfiData
	Error       bool
	ErrorMsg    string
}

type SynchedDataUpdate

type SynchedDataUpdate struct {
	Zone       ZoneName
	AgentId    AgentId
	UpdateType string // "local" or "remote"
	Update     *ZoneUpdate
	// Response chan *SynchedDataResponse
	Response chan *AgentMsgResponse
}

type TAtmp

type TAtmp map[string]TmpAnchor

XXX: These should die

type TargetUpdateStatus

type TargetUpdateStatus struct {
	Sender     string
	Rcode      int
	Error      bool
	ErrorMsg   string
	EDEFound   bool
	EDECode    uint16
	EDEMessage string
}

type TemplateConf

type TemplateConf struct {
	Name         string `validate:"required"`
	Zonefile     string
	Type         string
	Store        string
	Primary      string // upstream, for secondary zones
	Notify       []string
	OptionsStrs  []string `yaml:"options"`
	UpdatePolicy UpdatePolicyConf
	DnssecPolicy string
	MultiSigner  string
}

type TmpAnchor

type TmpAnchor struct {
	Name   string
	Dnskey string
}

type TmpSig0Key

type TmpSig0Key struct {
	Name string
	Key  string
}

type TransportConf

type TransportConf struct {
	Type   string `yaml:"type" validate:"omitempty,oneof=tsync svcb none"`
	Signal string `yaml:"signal"`
}

type TruststorePost

type TruststorePost struct {
	Command         string // "sig0"
	SubCommand      string // "list-child-keys" | "trust-child-key" | "untrust-child-key"
	Zone            string
	Keyname         string
	Keyid           int
	Validated       bool
	DnssecValidated bool
	Trusted         bool
	Src             string // "dns" | "file"
	KeyRR           string // RR string for key
}

type TruststoreResponse

type TruststoreResponse struct {
	AppName       string
	Time          time.Time
	Status        string
	Zone          string
	ChildDnskeys  map[string]cache.CachedDnskeyRRset
	ChildSig0keys map[string]Sig0Key
	Msg           string
	Error         bool
	ErrorMsg      string
}

type TsigDetails

type TsigDetails struct {
	Name      string `validate:"required" yaml:"name"`
	Algorithm string `validate:"required" yaml:"algorithm"`
	Secret    string `validate:"required" yaml:"secret"`
}

type Tx

type Tx struct {
	*sql.Tx
	KeyDB *KeyDB
	// contains filtered or unexported fields
}

func (*Tx) Commit

func (tx *Tx) Commit() error

func (*Tx) Exec

func (tx *Tx) Exec(query string, args ...interface{}) (sql.Result, error)

func (*Tx) Query

func (tx *Tx) Query(query string, args ...interface{}) (*sql.Rows, error)

func (*Tx) QueryRow

func (tx *Tx) QueryRow(query string, args ...interface{}) *sql.Row

func (*Tx) Rollback

func (tx *Tx) Rollback() error

type UpdateHandlerFunc

type UpdateHandlerFunc func(ctx context.Context, req *DnsUpdateRequest) error

UpdateHandlerFunc is the function signature for registered UPDATE handlers. Returns ErrNotHandled if the handler doesn't handle this UPDATE (allows fallthrough). Returns nil if the handler successfully handled the UPDATE. Returns other error if handler attempted to handle but encountered an error.

type UpdateHandlerRegistration

type UpdateHandlerRegistration struct {
	Matcher UpdateMatcherFunc
	Handler UpdateHandlerFunc
}

UpdateHandlerRegistration stores an UPDATE handler registration

type UpdateMatcherFunc

type UpdateMatcherFunc func(req *DnsUpdateRequest) bool

UpdateMatcherFunc is the function signature for matching UPDATE messages. Returns true if the UPDATE should be handled by the associated handler. The matcher receives the DnsUpdateRequest and can inspect: - req.Qname (zone name from question section) - req.Msg.Ns (update section RRs) - req.Msg.Extra (additional section, e.g., SIG(0)) - req.Options (EDNS0 options)

type UpdatePolicy

type UpdatePolicy struct {
	Child    UpdatePolicyDetail
	Zone     UpdatePolicyDetail
	Validate bool
}

type UpdatePolicyConf

type UpdatePolicyConf struct {
	Child struct {
		Type         string // selfsub | self | sub | none
		RRtypes      []string
		KeyBootstrap []string // manual | dnssec-validated | consistent-lookup
		KeyUpload    string
	}
	Zone struct {
		Type    string // "selfsub" | "self" | "sub" | ...
		RRtypes []string
	}
	Validate bool
}

type UpdatePolicyDetail

type UpdatePolicyDetail struct {
	Type         string // "selfsub" | "self"
	RRtypes      map[uint16]bool
	KeyBootstrap []string
	KeyUpload    string
}

type UpdateRequest

type UpdateRequest struct {
	Cmd            string
	UpdateType     string // "DSYNC", "KEY", ...
	ZoneName       string
	Adds           []dns.RR
	Removes        []dns.RR
	Actions        []dns.RR // The Update section from the dns.Msg
	Validated      bool     // Signature over update msg is validated
	Trusted        bool     // Content of update is trusted (via validation or policy)
	InternalUpdate bool     // Internal update, not a DNS UPDATE from the outside
	Status         *UpdateStatus
	Description    string
	PreCondition   func() bool
	Action         func() error
}

type UpdateResult

type UpdateResult struct {
	EDEFound     bool
	EDECode      uint16
	EDEMessage   string
	EDESender    string
	Rcode        int
	TargetStatus map[string]TargetUpdateStatus
}

func SendUpdate

func SendUpdate(msg *dns.Msg, zonename string, addrs []string) (int, UpdateResult, error)

Note: the target.Addresses must already be in addr:port format. func SendUpdate(msg *dns.Msg, zonename string, target *DsyncTarget) (int, error) { func SendUpdate(msg *dns.Msg, zonename string, addrs []string) (int, error, UpdateResult) {

type UpdateStatus

type UpdateStatus struct {
	Zone                  string             // zone that the update applies to
	ChildZone             string             // zone that the update applies to
	Type                  string             // auth | child
	Data                  string             // auth | delegation | key
	ValidatorKey          *Sig0Key           // key that validated the update
	Signers               []Sig0UpdateSigner // possible validators
	SignerName            string             // name of the key that signed the update
	SignatureType         string             // by-trusted | by-known | self-signed
	ValidationRcode       uint8              // Rcode from the validation process
	Validated             bool               // true if the update has passed validation
	ValidatedByTrustedKey bool               // true if the update has passed validation by a trusted key
	SafetyChecked         bool               // true if the update has been safety checked
	PolicyChecked         bool               // true if the update has been policy checked
	Approved              bool               // true if the update has been approved
	Msg                   string
	Error                 bool
	ErrorMsg              string
	Status                bool
}

func (*UpdateStatus) Log

func (us *UpdateStatus) Log(fmt string, v ...any)

type ValidatorRequest

type ValidatorRequest struct {
	Qname    string
	RRset    *core.RRset
	Response chan ValidatorResponse
}

type ValidatorResponse

type ValidatorResponse struct {
	Validated bool
	Msg       string
}

type VerificationInfo

type VerificationInfo struct {
	KeyName        string
	Key            string
	ZoneName       string
	AttemptsLeft   int
	NextCheckTime  time.Time
	ZoneData       *ZoneData
	Keyid          uint16
	FailedAttempts int
}

type ZoneAgentData

type ZoneAgentData struct {
	ZoneName      ZoneName
	Agents        []*Agent
	MyUpstream    AgentId
	MyDownstreams []AgentId
}

type ZoneConf

type ZoneConf struct {
	Name          string `validate:"required"`
	Zonefile      string
	Type          string `validate:"required"`
	Store         string // xfr | map | slice | reg (defaults to "map" if not specified)
	Primary       string // upstream, for secondary zones
	Notify        []string
	Downstreams   []string
	OptionsStrs   []string     `yaml:"options" mapstructure:"options"`
	Options       []ZoneOption `yaml:"-" mapstructure:"-"` // Ignore during both yaml and mapstructure decoding
	Frozen        bool         // true if zone is frozen; not a config param
	Dirty         bool         // true if zone has been modified; not a config param
	UpdatePolicy  UpdatePolicyConf
	DnssecPolicy  string
	Template      string
	MultiSigner   string
	Error         bool      // zone is broken and cannot be used
	ErrorType     ErrorType // "config" | "refresh" | "agent" | "DNSSEC"
	ErrorMsg      string    // reason for the error (if known)
	RefreshCount  int       // number of times the zone has been sucessfully refreshed (used to determine if we have zonedata)
	SourceCatalog string    // if auto-configured, which catalog zone created this zone
}

ZoneConf represents the external config for a zone; it contains no zone data

func ExpandTemplate

func ExpandTemplate(zconf ZoneConf, tmpl *ZoneConf, appMode AppType) (ZoneConf, error)

type ZoneData

type ZoneData struct {
	ZoneName   string
	ZoneStore  ZoneStore // 1 = "xfr", 2 = "map", 3 = "slice". An xfr zone only supports xfr related ops
	ZoneType   ZoneType
	Owners     Owners
	OwnerIndex cmap.ConcurrentMap[string, int]
	ApexLen    int
	//	RRs            RRArray
	Data         cmap.ConcurrentMap[string, OwnerData]
	CombinerData *cmap.ConcurrentMap[string, OwnerData]
	Ready        bool   // true if zd.Data has been populated (from file or upstream)
	XfrType      string // axfr | ixfr
	Logger       *log.Logger
	// ZoneFile           string // TODO: Remove this
	IncomingSerial     uint32 // SOA serial that we got from upstream
	CurrentSerial      uint32 // SOA serial after local bumping
	Verbose            bool
	Debug              bool
	IxfrChain          []Ixfr
	Upstream           string   // primary from where zone is xfrred
	Downstreams        []string // secondaries that we notify
	Zonefile           string
	DelegationSyncQ    chan DelegationSyncRequest
	MusicSyncQ         chan MusicSyncRequest // Multi-signer (communication between music-sidecars)
	Parent             string                // name of parentzone (if filled in)
	ParentNS           []string              // names of parent nameservers
	ParentServers      []string              // addresses of parent nameservers
	Children           map[string]*ChildDelegationData
	Options            map[ZoneOption]bool
	UpdatePolicy       UpdatePolicy
	DnssecPolicy       *DnssecPolicy
	MultiSigner        *MultiSignerConf
	KeyDB              *KeyDB
	AppType            AppType
	SyncQ              chan SyncRequest
	Error              bool        // zone is broken and cannot be used
	ErrorType          ErrorType   // "config" | "refresh" | "notify" | "update"
	ErrorMsg           string      // reason for the error (if known)
	LatestError        time.Time   // time of latest error
	RefreshCount       int         // number of times the zone has been sucessfully refreshed (used to determine if we have zonedata)
	LatestRefresh      time.Time   // time of latest successful refresh
	SourceCatalog      string      // if auto-configured, which catalog zone created this zone
	TransportSignal    *core.RRset // transport signal RRset (SVCB or TSYNC)
	AddTransportSignal bool        // whether to attach TransportSignal in responses
	// contains filtered or unexported fields
}

func FindZone

func FindZone(qname string) (*ZoneData, bool)

Find the closest enclosing auth zone that has qname below it (qname is either auth data in the zone or located further down in a child zone that we are not auth for). Return zone, case fold used to match

func FindZoneNG

func FindZoneNG(qname string) *ZoneData

func (*ZoneData) AddCombinerData

func (zd *ZoneData) AddCombinerData(data map[string][]core.RRset) error

AddCombinerData adds or updates local RRsets for the zone. The input map keys are owner names and values are slices of RRsets.

func (*ZoneData) AddCombinerDataNG

func (zd *ZoneData) AddCombinerDataNG(data map[string][]string) error

AddCombinerDataNG adds or updates local RRsets for the zone. The input map keys are owner names and values are slices of RR strings.

func (*ZoneData) AddOwner

func (zd *ZoneData) AddOwner(owner *OwnerData)

XXX: This MUST ONLY be called from the ZoneUpdater, due to locking issues

func (*ZoneData) AgentSig0KeyPrep

func (zd *ZoneData) AgentSig0KeyPrep(name string, kdb *KeyDB) error

func (*ZoneData) AnalyseZoneDelegation

func (zd *ZoneData) AnalyseZoneDelegation(imr *Imr) (DelegationSyncStatus, error)

Return insync (bool), adds, removes ([]dns.RR) and error

func (*ZoneData) ApplyChildUpdateToZoneData

func (zd *ZoneData) ApplyChildUpdateToZoneData(ur UpdateRequest, kdb *KeyDB) (bool, error)

func (*ZoneData) ApplyZoneUpdateToZoneData

func (zd *ZoneData) ApplyZoneUpdateToZoneData(ur UpdateRequest, kdb *KeyDB) (bool, error)

func (*ZoneData) ApproveAuthUpdate

func (zd *ZoneData) ApproveAuthUpdate(zone string, us *UpdateStatus, r *dns.Msg) (bool, bool, error)

Updates to auth data must be validated.

func (*ZoneData) ApproveChildUpdate

func (zd *ZoneData) ApproveChildUpdate(zone string, us *UpdateStatus, r *dns.Msg) (bool, bool, error)

Child updates are either validated updates for child delegation data, or unvalidated key upload requests. Returns approved, updatezone, error

func (*ZoneData) ApproveTrustUpdate

func (zd *ZoneData) ApproveTrustUpdate(zone string, us *UpdateStatus, r *dns.Msg) (bool, bool, error)

Trust updates are either validated updates (signed by already trusted key) or unvalidated (selfsigned initial uploads of key). In both cases the update section must only contain a single KEY RR. Returns approved, updatezone, error

func (*ZoneData) ApproveUpdate

func (zd *ZoneData) ApproveUpdate(zone string, us *UpdateStatus, r *dns.Msg) (bool, bool, error)

Returns approved, updatezone, error

func (*ZoneData) BestSyncScheme

func (zd *ZoneData) BestSyncScheme(ctx context.Context, imr *Imr) (string, *DsyncTarget, error)

Find the best scheme (from the POV of the child) to sync the deletation with the parent

func (*ZoneData) BootstrapSig0KeyWithParent

func (zd *ZoneData) BootstrapSig0KeyWithParent(ctx context.Context, alg uint8) (string, UpdateResult, error)

func (*ZoneData) BumpSerial

func (zd *ZoneData) BumpSerial() (BumperResponse, error)

func (*ZoneData) CollectDynamicRRs

func (zd *ZoneData) CollectDynamicRRs(conf *Config) []*core.RRset

CollectDynamicRRs collects all dynamically generated RRsets for a zone that need to be repopulated after refresh. These RRs are stored outside ZoneData (in database or generated from config) and will be lost when the zone is reloaded.

Returns a slice of RRsets that should be repopulated into the zone after refresh: - DNSKEY records (from DnssecKeyStore database, if online-signing enabled) - SIG(0) KEY records (from Sig0KeyStore database, if needed) - Transport signals (SVCB/TSYNC) - if Config provided and add-transport-signal enabled

func (*ZoneData) CombineWithLocalChanges

func (zd *ZoneData) CombineWithLocalChanges() (bool, error)

Returns true if the zone data was modified.

func (*ZoneData) ComputeIndices

func (zd *ZoneData) ComputeIndices()

func (*ZoneData) CreateTransportSignalRRs

func (zd *ZoneData) CreateTransportSignalRRs(conf *Config) error

CreateTransportSignalRRs orchestrates construction of a transport signal RRset for this zone. It delegates to the chosen mechanism (svcb|tsync) and assigns zd.TransportSignal and zd.AddTransportSignal when successful.

func (*ZoneData) DelegationData

func (zd *ZoneData) DelegationData() (*DelegationData, error)

func (*ZoneData) DelegationDataChangedNG

func (zd *ZoneData) DelegationDataChangedNG(newzd *ZoneData) (bool, DelegationSyncStatus, error)

func (*ZoneData) DelegationSyncSetup

func (zd *ZoneData) DelegationSyncSetup(ctx context.Context, kdb *KeyDB) error

func (*ZoneData) DnskeysChanged

func (zd *ZoneData) DnskeysChanged(newzd *ZoneData) (bool, DelegationSyncStatus, error)

func (*ZoneData) DnskeysChangedNG

func (zd *ZoneData) DnskeysChangedNG(newzd *ZoneData) (bool, error)

func (*ZoneData) DoTransfer

func (zd *ZoneData) DoTransfer() (bool, uint32, error)

Return shouldTransfer, new upstream serial, error

func (*ZoneData) FetchChildDelegationData

func (zd *ZoneData) FetchChildDelegationData(childname string) (*ChildDelegationData, error)

func (*ZoneData) FetchFromFile

func (zd *ZoneData) FetchFromFile(verbose, debug, force bool, dynamicRRs []*core.RRset) (bool, error)

Return updated, error

func (*ZoneData) FetchFromUpstream

func (zd *ZoneData) FetchFromUpstream(verbose, debug bool, dynamicRRs []*core.RRset) (bool, error)

Return updated, err

func (*ZoneData) FetchParentData

func (zd *ZoneData) FetchParentData(imr *Imr) error

func (*ZoneData) FindDelegation

func (zd *ZoneData) FindDelegation(qname string, dnssec_ok bool) *ChildDelegationData

XXX: This should be merged with the FetchChildDelegationData() function Returns [] NS RRs + [] v4glue RRs + [] v6glue RRs

func (*ZoneData) FindDnskey

func (zd *ZoneData) FindDnskey(signer string, keyid uint16) (*cache.CachedDnskeyRRset, error)

If key not found *CachedDnskeyRRset is returned with nil value

func (*ZoneData) FindGlue

func (zd *ZoneData) FindGlue(nsrrs core.RRset, dnssec_ok bool) (*core.RRset, *core.RRset)

Returns two RRsets with A glue and AAAA glue. Each RRset may be nil. XXX: This is wrong. The v4 (and v6) glue is not an *RRset, but a []*RRset

func (*ZoneData) FindGlueSimple

func (zd *ZoneData) FindGlueSimple(nsrrs core.RRset, dnssec_ok bool) ([]dns.RR, []dns.RR, []dns.RR, []dns.RR)

func (*ZoneData) FindSig0KeyViaDNS

func (zd *ZoneData) FindSig0KeyViaDNS(signer string, keyid uint16) (*Sig0Key, error)

func (*ZoneData) FindSig0TrustedKey

func (zd *ZoneData) FindSig0TrustedKey(signer string, keyid uint16) (*Sig0Key, error)

This is about locating a SIG(0) key that is trusted, i.e. that is present in the TrustStore. It is not about looking in the Keystore, nor looking in the DNS. If key not found *TrustAnchor is nil

func (*ZoneData) GenerateNsecChain

func (zd *ZoneData) GenerateNsecChain(kdb *KeyDB) error

func (*ZoneData) GetCombinerData

func (zd *ZoneData) GetCombinerData() (map[string][]core.RRset, error)

GetCombinerData retrieves all local combiner data for the zone

func (*ZoneData) GetCombinerDataNG

func (zd *ZoneData) GetCombinerDataNG() map[string][]RRsetString

GetCombinerDataNG returns the combiner data in string format suitable for JSON marshaling

func (*ZoneData) GetOwner

func (zd *ZoneData) GetOwner(qname string) (*OwnerData, error)

func (*ZoneData) GetOwnerNames

func (zd *ZoneData) GetOwnerNames() ([]string, error)

func (*ZoneData) GetRRset

func (zd *ZoneData) GetRRset(qname string, rrtype uint16) (*core.RRset, error)

func (*ZoneData) GetSOA

func (zd *ZoneData) GetSOA() (*dns.SOA, error)

func (*ZoneData) HsyncChanged

func (zd *ZoneData) HsyncChanged(newzd *ZoneData) (bool, *HsyncStatus, error)

func (*ZoneData) IsChildDelegation

func (zd *ZoneData) IsChildDelegation(qname string) bool

XXX: Is qname the name of a zone cut for a child zone?

func (*ZoneData) LoadDynamicZoneFile

func (zd *ZoneData) LoadDynamicZoneFile(zoneDirectory string) (bool, uint32, error)

LoadDynamicZoneFile loads a zone from a file in the dynamic zones directory Returns true if zone was updated, the serial number, and any error If the file is corrupted, creates the zone but sets an error state

func (*ZoneData) LookupAndValidateRRset

func (zd *ZoneData) LookupAndValidateRRset(qname string, qtype uint16,
	verbose bool) (*core.RRset, bool, error)

func (*ZoneData) LookupChildRRset

func (zd *ZoneData) LookupChildRRset(qname string, qtype uint16,
	v4glue, v6glue *core.RRset, verbose bool) (*core.RRset, error)

XXX: This should die in favor of LookupChildRRsetNG

func (*ZoneData) LookupChildRRsetNG

func (zd *ZoneData) LookupChildRRsetNG(qname string, qtype uint16,
	addrs []string, verbose bool) (*core.RRset, error)

func (*ZoneData) LookupRRset

func (zd *ZoneData) LookupRRset(qname string, qtype uint16, verbose bool) (*core.RRset, error)

func (*ZoneData) MusicSig0KeyPrep

func (zd *ZoneData) MusicSig0KeyPrep(name string, kdb *KeyDB) error

MusicSig0KeyPrep and ParentSig0KeyPrep are identical except for the source of the keygen algorithm which is specified in the relevant section of the configuration file.

func (*ZoneData) NameExists

func (zd *ZoneData) NameExists(qname string) bool

func (*ZoneData) NotifyDownstreams

func (zd *ZoneData) NotifyDownstreams() error

func (*ZoneData) ParentSig0KeyPrep

func (zd *ZoneData) ParentSig0KeyPrep(name string, kdb *KeyDB) error

func (*ZoneData) ParseZoneFromReader

func (zd *ZoneData) ParseZoneFromReader(r io.Reader, force bool) (bool, uint32, error)

func (*ZoneData) PrintApexRRs

func (zd *ZoneData) PrintApexRRs() error

func (*ZoneData) PrintOwnerNames

func (zd *ZoneData) PrintOwnerNames() error

func (*ZoneData) PrintOwners

func (zd *ZoneData) PrintOwners()

func (*ZoneData) PublishAddrRR

func (zd *ZoneData) PublishAddrRR(name, addr string) error

func (*ZoneData) PublishCsyncRR

func (zd *ZoneData) PublishCsyncRR() error

func (*ZoneData) PublishDnskeyRRs

func (zd *ZoneData) PublishDnskeyRRs(dak *DnssecKeys) error

func (*ZoneData) PublishDsyncRRs

func (zd *ZoneData) PublishDsyncRRs() error

func (*ZoneData) PublishKeyRRs

func (zd *ZoneData) PublishKeyRRs(sak *Sig0ActiveKeys) error

func (*ZoneData) PublishSvcbRR

func (zd *ZoneData) PublishSvcbRR(name string, port uint16, value []dns.SVCBKeyValue) error

func (*ZoneData) PublishTlsaRR

func (zd *ZoneData) PublishTlsaRR(name string, port uint16, certPEM string) error

func (*ZoneData) PublishUriRR

func (zd *ZoneData) PublishUriRR(owner, target, baseurl string, port uint16) error

Example: target: ms1.music.axfr.net baseurl: https://{TARGET}/api/v1 port: 443

func (*ZoneData) QueryResponder

func (zd *ZoneData) QueryResponder(ctx context.Context, w dns.ResponseWriter, r *dns.Msg,
	qname string, qtype uint16, msgoptions *edns0.MsgOptions, kdb *KeyDB, imr *Imr) error

func (*ZoneData) ReadZoneData

func (zd *ZoneData) ReadZoneData(zoneData string, force bool) (bool, uint32, error)

func (*ZoneData) ReadZoneFile

func (zd *ZoneData) ReadZoneFile(filename string, force bool) (bool, uint32, error)

func (*ZoneData) Refresh

func (zd *ZoneData) Refresh(verbose, debug, force bool, conf *Config) (bool, error)

func (*ZoneData) ReloadZone

func (zd *ZoneData) ReloadZone(refreshCh chan<- ZoneRefresher, force bool) (string, error)

func (*ZoneData) RepopulateDynamicRRs

func (zd *ZoneData) RepopulateDynamicRRs(dynamicRRs []*core.RRset)

RepopulateDynamicRRs repopulates dynamically generated RRsets into the zone data after refresh. The RRsets are passed in from RefreshEngine which collected them before the refresh.

func (*ZoneData) RolloverSig0KeyWithParent

func (zd *ZoneData) RolloverSig0KeyWithParent(ctx context.Context, alg uint8, action string) (string, uint16, uint16, UpdateResult, error)

Returns msg, old keyid, new keyid, error, UpdateResult

func (*ZoneData) SendNotify

func (zd *ZoneData) SendNotify(ntype uint16, targets []string) (int, error)

func (*ZoneData) SetError

func (zd *ZoneData) SetError(errtype ErrorType, errmsg string, args ...interface{})

func (*ZoneData) SetOption

func (zd *ZoneData) SetOption(option ZoneOption, value bool)

func (*ZoneData) SetupZoneSigning

func (zd *ZoneData) SetupZoneSigning(resignq chan<- *ZoneData) error

func (*ZoneData) SetupZoneSync

func (zd *ZoneData) SetupZoneSync(delsyncq chan<- DelegationSyncRequest) error

func (*ZoneData) ShowNsecChain

func (zd *ZoneData) ShowNsecChain() ([]string, error)

func (*ZoneData) Sig0KeyPreparation

func (zd *ZoneData) Sig0KeyPreparation(name string, alg uint8, kdb *KeyDB) error

func (*ZoneData) SignRRset

func (zd *ZoneData) SignRRset(rrset *core.RRset, name string, dak *DnssecKeys, force bool) (bool, error)

func (*ZoneData) SignZone

func (zd *ZoneData) SignZone(kdb *KeyDB, force bool) (int, error)

XXX: MaybesignRRset should report on whether it actually signed anything At the end, is anything hass been signed, then we must end by bumping the SOA Serial and resigning the SOA.

func (*ZoneData) SortFunc

func (zd *ZoneData) SortFunc(rr dns.RR, firstSoaSeen bool) bool

func (*ZoneData) SyncZoneDelegation

func (zd *ZoneData) SyncZoneDelegation(ctx context.Context, kdb *KeyDB, notifyq chan NotifyRequest, syncstate DelegationSyncStatus, imr *Imr) (string, uint8, UpdateResult, error)

SyncZoneDelegation() is used for delegation synchronization request via API.

func (*ZoneData) SyncZoneDelegationViaNotify

func (zd *ZoneData) SyncZoneDelegationViaNotify(kdb *KeyDB, notifyq chan NotifyRequest, syncstate DelegationSyncStatus,
	dsynctarget *DsyncTarget) (string, uint8, error)

func (*ZoneData) SyncZoneDelegationViaUpdate

func (zd *ZoneData) SyncZoneDelegationViaUpdate(kdb *KeyDB, syncstate DelegationSyncStatus,
	dsynctarget *DsyncTarget) (string, uint8, UpdateResult, error)

func (*ZoneData) TrustUpdate

func (zd *ZoneData) TrustUpdate(r *dns.Msg, us *UpdateStatus) error

BERRA TODO kolla om man kan förbättra detta, så man kan skicka en EDE Evaluate the keys that signed the update and determine the trust status of the update.

func (*ZoneData) UnpublishAddrRR

func (zd *ZoneData) UnpublishAddrRR(name, addr string) error

func (*ZoneData) UnpublishCsyncRR

func (zd *ZoneData) UnpublishCsyncRR() error

func (*ZoneData) UnpublishDsyncRRs

func (zd *ZoneData) UnpublishDsyncRRs() error

func (*ZoneData) UnpublishKeyRRs

func (zd *ZoneData) UnpublishKeyRRs() error

func (*ZoneData) UnpublishSvcbRR

func (zd *ZoneData) UnpublishSvcbRR(name string) error

func (*ZoneData) UnpublishTlsaRR

func (zd *ZoneData) UnpublishTlsaRR() error

func (*ZoneData) UnpublishUriRR

func (zd *ZoneData) UnpublishUriRR(owner, target string) error

func (*ZoneData) ValidateChildDnskeys

func (zd *ZoneData) ValidateChildDnskeys(cdd *ChildDelegationData, verbose bool) (bool, error)

ValidateChildDnskeys: we have the ChildDelegationData for the child zone, containing both the NS RRset and the DS RRset. 1. Fetch the child DNSKEY RRset from one of the child nameservers 2. Verify the child KSK against the DS that we have 3. Verify the child DNSKEY RRset against the verified KSK 4. Store the child DNSKEY RRset in the TrustAnchor store 5. Return true if the child DNSKEY RRset is validated

func (*ZoneData) ValidateHsyncRRset

func (zd *ZoneData) ValidateHsyncRRset() (bool, error)

bool=true if the HSYNC RRset exists and is valid, false otherwise error is non-nil for errors other than the HSYNC RRset not existing

func (*ZoneData) ValidateRRset

func (zd *ZoneData) ValidateRRset(rrset *core.RRset, verbose bool) (bool, error)

XXX: This should not be a method of ZoneData, but rather a function.

func (*ZoneData) ValidateUpdate

func (zd *ZoneData) ValidateUpdate(r *dns.Msg, us *UpdateStatus) error

XXX: This should perhaps not be a method of ZoneData, but rather of KeyDB.

func (*ZoneData) VerifyPublishedKeyRRs

func (zd *ZoneData) VerifyPublishedKeyRRs() error

func (*ZoneData) WriteDynamicZoneFile

func (zd *ZoneData) WriteDynamicZoneFile(zoneDirectory string) (string, error)

WriteDynamicZoneFile writes a zone file to the dynamic zones directory using atomic writes Returns the full path to the written file, or an error

func (*ZoneData) WriteFile

func (zd *ZoneData) WriteFile(filename string) (string, error)

func (*ZoneData) WriteTmpFile

func (zd *ZoneData) WriteTmpFile(lg *log.Logger) (string, error)

func (*ZoneData) WriteZone

func (zd *ZoneData) WriteZone(tosource bool, force bool) (string, error)

func (*ZoneData) WriteZoneToFile

func (zd *ZoneData) WriteZoneToFile(f *os.File) error

func (*ZoneData) XXfindServerTSYNCRRset

func (zd *ZoneData) XXfindServerTSYNCRRset() *core.RRset

findServerTSYNCRRset returns a TSYNC RRset from any owner under this zone that starts with _dns.

func (*ZoneData) ZoneFileName

func (zd *ZoneData) ZoneFileName() (string, error)

func (*ZoneData) ZoneTransferIn

func (zd *ZoneData) ZoneTransferIn(upstream string, serial uint32, ttype string) (uint32, error)

func (*ZoneData) ZoneTransferOut

func (zd *ZoneData) ZoneTransferOut(w dns.ResponseWriter, r *dns.Msg) (int, error)

func (*ZoneData) ZoneUpdateChangesDelegationData

func (zd *ZoneData) ZoneUpdateChangesDelegationData(ur UpdateRequest) (DelegationSyncStatus, error)

func (*ZoneData) ZoneUpdateChangesDelegationDataNG

func (zd *ZoneData) ZoneUpdateChangesDelegationDataNG(ur UpdateRequest) (DelegationSyncStatus, error)

type ZoneDataRepo

type ZoneDataRepo struct {
	// Repo map[ZoneName]ZoneRepo // map[zonename]ZoneRepo
	Repo core.ConcurrentMap[ZoneName, *AgentRepo] // map[zonename]ZoneRepo
}

func NewZoneDataRepo

func NewZoneDataRepo() (*ZoneDataRepo, error)

func (*ZoneDataRepo) EvaluateUpdate

func (zdr *ZoneDataRepo) EvaluateUpdate(synchedDataUpdate *SynchedDataUpdate) (bool, string, error)

func (*ZoneDataRepo) Get

func (zdr *ZoneDataRepo) Get(zone ZoneName) (*AgentRepo, bool)

func (*ZoneDataRepo) ProcessUpdate

func (zdr *ZoneDataRepo) ProcessUpdate(synchedDataUpdate *SynchedDataUpdate) (bool, string, error)

Returns change (true/false), msg (string), error (error)

func (*ZoneDataRepo) SendUpdate

func (zdr *ZoneDataRepo) SendUpdate(update *SynchedDataUpdate) error

func (*ZoneDataRepo) Set

func (zdr *ZoneDataRepo) Set(zone ZoneName, agentRepo *AgentRepo)

type ZoneDsyncPost

type ZoneDsyncPost struct {
	Command   string // status | bootstrap | ...
	Zone      string
	Algorithm uint8
	Action    string
	OldKeyID  uint16
	NewKeyID  uint16
}

type ZoneDsyncResponse

type ZoneDsyncResponse struct {
	AppName      string
	Time         time.Time
	Status       string
	Zone         string
	Functions    map[string]string
	Todo         []string
	Msg          string
	OldKeyID     uint16
	NewKeyID     uint16
	Error        bool
	ErrorMsg     string
	UpdateResult UpdateResult
}

type ZoneName

type ZoneName string

func (ZoneName) String

func (name ZoneName) String() string

type ZoneOption

type ZoneOption uint8
const (
	OptDelSyncParent ZoneOption = iota + 1
	OptDelSyncChild
	OptAllowUpdates
	OptAllowChildUpdates
	OptAllowCombine // Dynamically et if app=combiner and zone contains a HSYNC RRset
	OptFoldCase
	OptBlackLies
	OptDontPublishKey
	OptOnlineSigning
	OptMultiSigner // OBE?
	OptDirty
	OptFrozen
	OptAutomaticZone
	// OptServerSvcb
	OptAddTransportSignal
	OptCatalogZone
	OptCatalogMemberAutoCreate
	OptCatalogMemberAutoDelete
)

type ZonePost

type ZonePost struct {
	Command    string
	SubCommand string
	Zone       string
	Force      bool
}

type ZoneRefresher

type ZoneRefresher struct {
	Name         string
	ZoneType     ZoneType // primary | secondary
	Primary      string
	Notify       []string
	ZoneStore    ZoneStore // 1=xfr, 2=map, 3=slice
	Zonefile     string
	Options      map[ZoneOption]bool
	Edns0Options *edns0.MsgOptions
	UpdatePolicy UpdatePolicy
	DnssecPolicy string
	MultiSigner  string
	Force        bool // force refresh, ignoring SOA serial
	Response     chan RefresherResponse
}

type ZoneResponse

type ZoneResponse struct {
	AppName  string
	Time     time.Time
	Status   string
	Zone     string
	Names    []string
	Zones    map[string]ZoneConf
	Msg      string
	Error    bool
	ErrorMsg string
}

type ZoneStore

type ZoneStore uint8
const (
	XfrZone ZoneStore = iota + 1
	MapZone
	SliceZone
)

type ZoneType

type ZoneType uint8
const (
	Primary ZoneType = iota + 1
	Secondary
)

type ZoneUpdate

type ZoneUpdate struct {
	Zone    ZoneName
	AgentId AgentId
	RRsets  map[uint16]core.RRset // remote updates are only per RRset (i.e. full replace)
	RRs     []dns.RR              // local updates can be per RR
}

Directories

Path Synopsis
crypto module
hpke module

Jump to

Keyboard shortcuts

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