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) 2026 Johan Stenstam, [email protected] * * Agent distribution management API endpoints
* Copyright (c) 2025 Johan Stenstam, [email protected] * * API handlers for tdns-auth peer management (multi-provider DNSSEC). * /auth/peer: peer-ping, status commands. * /auth/distrib: peer listing (same pattern as agent/combiner distrib).
* Copyright (c) 2024 Johan Stenstam, [email protected]
* Copyright (c) 2026 Johan Stenstam, [email protected] * * Combiner distribution management API endpoints
* Copyright (c) 2024 Johan Stenstam, [email protected]
* Copyright (c) 2024 Johan Stenstam, [email protected]
* Copyright (c) 2026 Johan Stenstam, [email protected] * * Transaction diagnostic API endpoints for agents and combiners. * Provides visibility into open outgoing/incoming transactions and error history.
* 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) 2026 Johan Stenstam, [email protected]
* Copyright (c) 2026 Johan Stenstam, [email protected] * * DBDelegationBackend stores child delegation data in the ChildDelegationData * SQLite table. Extracts and replaces the existing ApplyChildUpdateToDB logic.
* Copyright (c) 2026 Johan Stenstam, [email protected] * * DirectDelegationBackend applies child UPDATEs directly to in-memory zone data. * This is the original behavior for Primary zones.
* Copyright (c) 2026 Johan Stenstam, [email protected] * * ZonefileDelegationBackend writes per-child delegation data as DNS zone file * fragments. Each child zone gets its own file that can be $INCLUDEd into the * parent zone file. Files are written atomically (write-to-temp + rename).
* 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) 2026 Johan Stenstam, [email protected] * * In-memory error journal for the combiner/receiver. Records errors that occur * during HandleChunkNotify processing, indexed by distribution ID for targeted * diagnostic queries.
* 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) 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) 2026 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) 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]
* 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) 2026 Johan Stenstam, [email protected] * * Wrappers for unexported functions/methods needed by tdns-mp. * These export functionality that tdns-mp cannot access directly * because it is a different package.
* Copyright (c) 2024 Johan Stenstam, [email protected]
Index ¶
- Constants
- Variables
- func APICatalog(app *AppDetails) func(w http.ResponseWriter, r *http.Request)
- func APIauthDistrib(conf *Config) func(w http.ResponseWriter, r *http.Request)
- func APIauthPeer(conf *Config) func(w http.ResponseWriter, r *http.Request)
- func APIcombiner(app *AppDetails, refreshZoneCh chan<- ZoneRefresher, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)
- func APIcombinerDebug(conf *Config) func(w http.ResponseWriter, r *http.Request)
- func APIcombinerEdits(conf *Config) func(w http.ResponseWriter, r *http.Request)
- func APIcommand(conf *Config, rtr *mux.Router) func(w http.ResponseWriter, r *http.Request)
- func APIconfig(conf *Config) func(w http.ResponseWriter, r *http.Request)
- func APIdebug(conf *Config) func(w http.ResponseWriter, r *http.Request)
- func APIdelegation(delsyncq chan DelegationSyncRequest) func(w http.ResponseWriter, r *http.Request)
- func APIdispatcher(conf *Config, router *mux.Router, done <-chan struct{}) error
- func APIdispatcherNG(conf *Config, router *mux.Router, addrs []string, certFile string, ...) error
- func APImultisigner(kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)
- func APIping(conf *Config) func(w http.ResponseWriter, r *http.Request)
- func APIscanner(conf *Config, app *AppDetails, scannerq chan ScanRequest, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)
- func APIscannerDelete(conf *Config) func(w http.ResponseWriter, r *http.Request)
- func APIscannerStatus(conf *Config) func(w http.ResponseWriter, r *http.Request)
- func APIzone(app *AppDetails, refreshq chan ZoneRefresher, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)
- func APIzoneDsync(ctx context.Context, app *AppDetails, refreshq chan ZoneRefresher, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)
- func AddRouterCommandsToSwitch()
- func AgentToString(a *Agent) string
- func AuthDNSQuery(qname string, lg *log.Logger, nameservers []string, rrtype uint16, ...) (*core.RRset, int, error)
- func AuthQuery(qname, ns string, rrtype uint16) ([]dns.RR, error)
- func AuthQueryEngine(ctx context.Context, requests chan AuthQueryRequest)
- func AutoConfigureZonesFromCatalog(ctx context.Context, update *CatalogZoneUpdate, conf *Config) error
- func BailiwickNS(zonename string, nsrrs []dns.RR) ([]string, error)
- func Base32Decode(data string) ([]byte, error)
- func Base32Encode(data []byte) string
- func CaseFoldContains(slice []string, str string) bool
- func ChildDelegationDataUnsynched(zone, pzone, childpri, parpri string) (bool, []dns.RR, []dns.RR, error)
- func ChildGlueRRsToAddrs(v4glue, v6glue []dns.RR) ([]string, error)
- func ChildGlueRRsetsToAddrs(v4glue, v6glue []*core.RRset) ([]string, error)
- func Chomp(s string) string
- func ChunkBase32Data(base32Data string, cookie string) []string
- func ChunksToDomains(chunks []string, domainSuffix string) []string
- func CombinerMsgHandler(ctx context.Context, conf *Config, msgQs *MsgQs, protectedNamespaces []string, ...)
- func CombinerStateSetChunkHandler(cs *CombinerState, handler *transport.ChunkNotifyHandler)
- func ComputeBailiwickNS(childpri, parpri, owner string) ([]string, []string, error)
- func ComputeDo53Remainder(pct map[string]uint8) uint8
- func ComputeGroupHash(identities []string) string
- func ComputeRRDiff(childpri, parpri, owner string, rrtype uint16) (bool, []dns.RR, []dns.RR, error)
- func CopyFile(src, dst string) (int64, error)
- func CreateChildReplaceUpdate(parent, child string, newNS, newA, newAAAA, newDS []dns.RR) (*dns.Msg, error)
- func CreateChildUpdate(parent, child string, adds, removes []dns.RR) (*dns.Msg, error)
- func CreateUpdate(zone string, adds, removes []dns.RR) (*dns.Msg, error)
- func DefaultQueryHandler(ctx context.Context, req *DnsQueryRequest) error
- func DiscoverAgentAPI(ctx context.Context, imr *Imr, identity string, result *AgentDiscoveryResult)
- func DiscoverAgentDNS(ctx context.Context, imr *Imr, identity string, result *AgentDiscoveryResult)
- func DnsDoHEngine(ctx context.Context, conf *Config, dohaddrs []string, certFile, keyFile string, ...) error
- func DnsDoQEngine(ctx context.Context, conf *Config, doqaddrs []string, cert *tls.Certificate, ...) error
- func DnsDoTEngine(ctx context.Context, conf *Config, dotaddrs []string, cert *tls.Certificate, ...) error
- func DnsEngine(ctx context.Context, conf *Config) error
- func DomainsToBase32(domains []string, cookie string) (string, error)
- func DomainsToJson(domains []string, cookie string) ([]byte, error)
- func DomainsToStruct(domains []string, cookie string, result interface{}) error
- func DotServerQnameResponse(qname string, w dns.ResponseWriter, r *dns.Msg)
- func DsyncUpdateTargetName(zonename string) string
- func ExpirationFromTtl(addedAt time.Time, ttl uint32) time.Time
- func ExportDelegationData(backend DelegationBackend, parentZone, outfile string, defaultTTL uint32) error
- func Fatal(msg string, args ...any)
- func FetchSVCB(baseurl string, resolvers []string, timeout time.Duration, retries int) (*dns.SVCB, []string, uint16, string, error)
- func FindSoaRefresh(zd *ZoneData) (uint32, error)
- func GenerateJobID() (string, error)
- func GetAlpn(svcb *dns.SVCB) []string
- func GetDefaultConfigFile() string
- func GetDynamicZoneFilePath(zoneName, zoneDirectory string) string
- func GetNameservers(KeyName string, zd *ZoneData) ([]string, error)
- func GetProviderZoneRRtypes(zone string) map[uint16]bool
- func GetTransportParam(svcb *dns.SVCB) (map[string]uint8, bool, error)
- func HsyncEngine(ctx context.Context, conf *Config, msgQs *MsgQs)
- func InBailiwick(zone string, ns *dns.NS) bool
- func IsIxfr(rrs []dns.RR) bool
- func IsPEMFormat(keyData string) bool
- func JsonToBase32Domains(jsonData []byte, domainSuffix string, cookie string) ([]string, error)
- func KeyStateWorker(ctx context.Context, conf *Config) error
- func Logger(subsystem string) *slog.Logger
- func LookupChildKeyAtApex(ctx context.Context, childZone string, imr *Imr) ([]dns.RR, bool, error)
- func LookupChildKeyAtSignal(ctx context.Context, childZone string, imr *Imr) ([]dns.RR, bool, error)
- func LookupSVCB(name string) (*core.RRset, error)
- func LookupTlsaRR(name string) (*core.RRset, error)
- func MarshalTLSAToString(tlsa *dns.TLSA) (string, error)
- func MarshalTransport(transports map[string]uint8) string
- func MsgAcceptFunc(dh dns.Header) dns.MsgAcceptAction
- func MsgPrint(m *dns.Msg, server string, elapsed time.Duration, short bool, ...)
- func NSInBailiwick(zone string, ns *dns.NS) bool
- func NeedsResigning(rrsig *dns.RRSIG) bool
- func NewCombinerSyncHandler() transport.MessageHandlerFunc
- func NormalizeAddress(addr string) string
- func NormalizeAddresses(addresses []string) []string
- func Notifier(ctx context.Context, notifyreqQ chan NotifyRequest) error
- func NotifyCatalogZoneUpdate(update *CatalogZoneUpdate) error
- func NotifyHandler(ctx context.Context, conf *Config) error
- func NotifyHandlerWithCallback(ctx context.Context, conf *Config, ...) error
- func NotifyReporter(conf *Config, tsigSecrets map[string]string, addr string) (stop func(context.Context) error, err error)
- func NotifyResponder(ctx context.Context, dnr *DnsNotifyRequest, zonech chan ZoneRefresher, ...) error
- func PEMToPrivateKey(pemData string) (crypto.PrivateKey, error)
- func ParseLogLevel(s string) slog.Level
- func ParsePrivateKeyFromDB(privatekey, algorithm, keyrrstr string) (crypto.PrivateKey, uint8, string, error)
- func ParseTLSAFromSvcbLocal(local *dns.SVCBLocal) (*dns.TLSA, error)
- func ParseTLSAString(s string) (*dns.TLSA, error)
- func ParseTsigKeys(keyconf *KeyConf) (int, map[string]string)
- func PrintDsRR(rr dns.RR, leftpad, rightmargin int)
- func PrintGenericRR(rr dns.RR, leftpad, rightmargin int)
- func PrintJwkRR(rr dns.RR, leftpad, rightmargin int)
- func PrintKeyRR(rr dns.RR, rrtype, ktype string, keyid uint16, leftpad, rightmargin int)
- func PrintMsgFull(m *dns.Msg, width int) string
- func PrintMsgSection(header string, section []dns.RR, width int) string
- func PrintRR(rr dns.RR, leftpad int, options map[string]string) error
- func PrintRrsigRR(rr dns.RR, leftpad, rightmargin int)
- func PrintSoaRR(rr dns.RR, leftpad, rightmargin int)
- func PrintSvcbRR(rr dns.RR, leftpad, rightmargin int)
- func PrivKeyToBindFormat(privkey, algorithm string) (string, error)
- func PrivateKeyToPEM(privkey crypto.PrivateKey) (string, error)
- func PublishKeyToCombiner(zone ZoneName, keyRR dns.RR, tm *MPTransportBridge) (string, error)
- func QueryHandler(ctx context.Context, conf *Config, ...) error
- func RRsetToString(rrset *core.RRset) string
- func ReadPubKey(filename string) (dns.RR, uint16, uint8, error)
- func ReadPubKeys(keydir string) (map[string]dns.KEY, error)
- func RecursiveDNSQuery(server, qname string, qtype uint16, timeout time.Duration, retries int) (*core.RRset, error)
- func RecursiveDNSQueryWithConfig(qname string, qtype uint16, timeout time.Duration, retries int) (*core.RRset, error)
- func RecursiveDNSQueryWithResolvConf(qname string, qtype uint16, timeout time.Duration, retries int) (*core.RRset, error)
- func RecursiveDNSQueryWithServers(qname string, qtype uint16, timeout time.Duration, retries int, ...) (*core.RRset, error)
- func RefreshEngine(ctx context.Context, conf *Config)
- func RegisterAPIRoute(routeFunc APIRouteFunc) error
- func RegisterCatalogZoneCallback(callback CatalogZoneCallback)
- func RegisterChunkQueryHandler(store ChunkPayloadStore) error
- func RegisterDebugNotifyHandler() error
- func RegisterDebugQueryHandler() error
- func RegisterDefaultQueryHandlers(conf *Config) error
- func RegisterEngine(name string, engine EngineFunc) error
- func RegisterImrClientQueryHook(hook ImrClientQueryHookFunc) error
- func RegisterImrOutboundQueryHook(hook ImrOutboundQueryHookFunc) error
- func RegisterImrResponseHook(hook ImrResponseHookFunc) error
- func RegisterNotifyHandler(qtype uint16, handler NotifyHandlerFunc) error
- func RegisterProviderZoneRRtypes(pz ProviderZoneConf)
- func RegisterQueryHandler(qtype uint16, handler QueryHandlerFunc) error
- func RegisterUpdateHandler(matcher UpdateMatcherFunc, handler UpdateHandlerFunc) error
- func RegisterZoneOptionHandler(opt ZoneOption, handler ZoneOptionHandler)
- func ResignerEngine(ctx context.Context, zoneresignch chan *ZoneData)
- func RunKeysCmd(conf *Config, appType AppType, args []string) error
- func SanitizeForJSON(v interface{}) interface{}
- func ScannerEngine(ctx context.Context, conf *Config) error
- func SendUnixPing(target string, dieOnError bool) (bool, error)
- func ServerQueryHandler(ctx context.Context, req *DnsQueryRequest) error
- func SetSubsystemLevel(name string, level slog.Level)
- func SetupCliLogging()
- func SetupLogging(logfile string, logConf LogConf) error
- func ShowAPI(rtr *mux.Router) ([]string, error)
- func Shutdowner(conf *Config, msg string)
- func Sig0KeyOwnerName(zone, nameserver string) string
- func SignMsg(m dns.Msg, signer string, sak *Sig0ActiveKeys) (*dns.Msg, error)
- func SignerMsgHandler(ctx context.Context, conf *Config, msgQs *MsgQs)
- func SprintUpdates(actions []dns.RR) string
- func StartDistributionGC(cache *DistributionCache, interval time.Duration, stopCh chan struct{})
- func StartEngine(app *AppDetails, name string, engineFunc func() error)
- func StartEngineNoError(app *AppDetails, name string, engineFunc func())
- func StartRegisteredEngines(ctx context.Context)
- func StripKeyFileComments(data []byte) []byte
- func StructToBase32Domains(data interface{}, domainSuffix string, cookie string) ([]string, error)
- func TLSAToSvcbLocal(tlsa *dns.TLSA) (*dns.SVCBLocal, error)
- func TtlPrint(expiration time.Time) string
- func TtyIntQuestion(query string, oldval int, force bool) int
- func TtyQuestion(query, oldval string, force bool) string
- func TtyRadioButtonQ(query, defval string, choices []string) string
- func TtyYesNo(query, defval string) string
- func TypeBitMapToString(tbm []uint16) string
- func UpdateHandler(ctx context.Context, conf *Config) error
- func UpdateResponder(dur *DnsUpdateRequest, updateq chan UpdateRequest) error
- func ValidateAgentNameservers(config *Config) error
- func ValidateAgentSupportedMechanisms(config *Config) error
- func ValidateBySection(config *Config, configsections map[string]interface{}, cfgfile string) (string, error)
- func ValidateCertAndKeyFiles(fl validator.FieldLevel) bool
- func ValidateConfig(v *viper.Viper, cfgfile string) error
- func ValidateConfigWithCustomValidator(v *viper.Viper, cfgfile string) error
- func ValidateCryptoFiles(config *Config) error
- func ValidateDatabaseFile(config *Config) error
- func ValidateExplicitServerSVCB(svcb *dns.SVCB) error
- func ValidateZones(c *Config, cfgfile string) error
- func ValidatorEngine(ctx context.Context, conf *Config)
- func VerifyCertAgainstTlsaRR(tlsarr *dns.TLSA, rawcert []byte) error
- func VerifyChildKey(ctx context.Context, childZone string, keyRR string, imr *Imr) (verified bool, dnssecValidated bool)
- func VerifyKey(KeyName string, key string, keyid uint16, zd *ZoneData, ...)
- func WalkRoutes(router *mux.Router, address string)
- func WildcardReplace(rrs []dns.RR, qname, origqname string) []dns.RR
- func ZoneDataWeAreASigner(zd *ZoneData) (bool, error)
- func ZoneIsReady(zonename string) func() bool
- func ZoneTransferPrint(zname, upstream string, serial uint32, ttype uint16, options map[string]string) error
- type APIRouteFunc
- type APIRouteRegistration
- type Agent
- func (agent *Agent) AddDeferredAgentTask(task *DeferredAgentTask)
- func (agent *Agent) CheckState(ourBeatInterval uint32)
- func (agent *Agent) CreateAgentUpstreamRFI() *DeferredAgentTask
- func (agent *Agent) CreateOperationalAgentTask(action func() (bool, error), desc string) *DeferredAgentTask
- func (a *Agent) EffectiveState() AgentState
- func (a *Agent) IsAnyTransportOperational() bool
- func (agent *Agent) MarshalJSON() ([]byte, error)
- func (agent *Agent) NewAgentSyncApiClient(localagent *MultiProviderConf) error
- func (agent *Agent) SendApiBeat(msg *AgentBeatPost) (*AgentBeatResponse, error)
- func (agent *Agent) SendApiHello(msg *AgentHelloPost) (*AgentHelloResponse, error)
- func (agent *Agent) SendApiMsg(msg *AgentMsgPost) (*AgentMsgResponse, error)
- func (agent *Agent) SendDnsMsg(msg *AgentMsgPost) (int, []byte, error)
- type AgentApi
- type AgentBeatPost
- type AgentBeatReport
- type AgentBeatResponse
- type AgentDebugPost
- type AgentDetails
- type AgentDiscoveryResult
- type AgentDistribPost
- type AgentDistribResponse
- type AgentHelloPost
- type AgentHelloResponse
- type AgentId
- type AgentMgmtPost
- type AgentMgmtPostPlus
- type AgentMgmtResponse
- type AgentMsg
- type AgentMsgPost
- type AgentMsgPostPlus
- type AgentMsgReport
- type AgentMsgResponse
- type AgentOption
- type AgentPingPost
- type AgentPingResponse
- type AgentRegistry
- func (ar *AgentRegistry) AddRemoteAgent(zonename ZoneName, agent *Agent)
- func (ar *AgentRegistry) AddZoneToAgent(identity AgentId, zone ZoneName)
- func (ar *AgentRegistry) CleanupZoneRelationships(zonename ZoneName)
- func (ar *AgentRegistry) CommandHandler(msg *AgentMgmtPostPlus, synchedDataUpdateQ chan *SynchedDataUpdate)
- func (ar *AgentRegistry) DiscoverAgentAsync(remoteid AgentId, zonename ZoneName, deferredTask *DeferredAgentTask)
- func (ar *AgentRegistry) DiscoveryRetrierNG(ctx context.Context)
- func (ar *AgentRegistry) EvaluateHello(ahp *AgentHelloPost) (bool, string, error)
- func (ar *AgentRegistry) FastBeatAttempts(ctx context.Context, agent *Agent)
- func (ar *AgentRegistry) GetAgentInfo(identity AgentId) (*Agent, error)
- func (ar *AgentRegistry) GetAgentsForZone(zone ZoneName) []*Agent
- func (ar *AgentRegistry) GetZoneAgentData(zonename ZoneName) (*ZoneAgentData, error)
- func (ar *AgentRegistry) HandleStatusRequest(req SyncStatus)
- func (ar *AgentRegistry) HeartbeatHandler(report *AgentMsgReport)
- func (ar *AgentRegistry) HelloHandler(report *AgentMsgReport)
- func (ar *AgentRegistry) HelloRetrier()
- func (ar *AgentRegistry) HelloRetrierNG(ctx context.Context, agent *Agent)
- func (ar *AgentRegistry) InitializeCombinerAsPeer(conf *Config) error
- func (ar *AgentRegistry) InitializeSignerAsPeer(conf *Config) error
- func (ar *AgentRegistry) LocateAgent(remoteid AgentId, zonename ZoneName, deferredTask *DeferredAgentTask)
- func (ar *AgentRegistry) MarkAgentAsNeeded(remoteid AgentId, zonename ZoneName, deferredTask *DeferredAgentTask)
- func (ar *AgentRegistry) MsgHandler(ampp *AgentMsgPostPlus, synchedDataUpdateQ chan *SynchedDataUpdate, ...)
- func (ar *AgentRegistry) RecomputeSharedZonesAndSyncState(agent *Agent)
- func (ar *AgentRegistry) RemoveRemoteAgent(zonename ZoneName, identity AgentId)
- func (ar *AgentRegistry) SendHeartbeats()
- func (ar *AgentRegistry) SingleHello(agent *Agent, zone ZoneName)
- func (ar *AgentRegistry) StartInfraBeatLoop(ctx context.Context)
- func (ar *AgentRegistry) SyncRequestHandler(ourId AgentId, req SyncRequest, synchedDataUpdateQ chan *SynchedDataUpdate)
- func (ar *AgentRegistry) UpdateAgents(ourId AgentId, req SyncRequest, zonename ZoneName, ...) error
- type AgentRepo
- type AgentState
- type ApiClient
- func (api *ApiClient) Delete(endpoint string) (int, []byte, error)
- func (api *ApiClient) Get(endpoint string) (int, []byte, error)
- func (api *ApiClient) Post(endpoint string, data []byte) (int, []byte, error)
- func (api *ApiClient) Put(endpoint string, data []byte) (int, []byte, error)
- func (api *ApiClient) RequestNG(method, endpoint string, data interface{}, dieOnError bool) (int, []byte, error)
- func (api *ApiClient) RequestNGWithContext(ctx context.Context, method, endpoint string, data interface{}, ...) (int, []byte, error)
- func (api *ApiClient) SendPing(pingcount int, dieOnError bool) (PingResponse, error)
- func (api *ApiClient) ShowApi()
- func (api *ApiClient) StartDaemon(maxwait int, slurp bool, command string, daemonFlags []string)
- func (api *ApiClient) StopDaemon()
- func (api *ApiClient) UpdateDaemon(data CommandPost, dieOnError bool) (int, CommandResponse, error)
- func (api *ApiClient) UrlReport(method, endpoint string, data []byte)
- func (api *ApiClient) UrlReportNG(method, fullurl string, data []byte)
- type ApiServerAppConf
- type ApiServerConf
- type AppDetails
- type AppType
- type ApprovedEditRecord
- type AuditResponseMsg
- type AuthDistribPost
- type AuthOption
- type AuthPeerPost
- type AuthPeerResponse
- type AuthQueryRequest
- type AuthQueryResponse
- type BindPrivateKey
- type BumperData
- type BumperResponse
- type CatalogConf
- type CatalogMemberZone
- type CatalogMembership
- func (cm *CatalogMembership) AddGroup(group string) error
- func (cm *CatalogMembership) AddMemberZone(zoneName string) error
- func (cm *CatalogMembership) AddZoneGroup(zoneName, group string) error
- func (cm *CatalogMembership) GetGroups() []string
- func (cm *CatalogMembership) GetMemberZones() map[string]*MemberZone
- func (cm *CatalogMembership) RemoveGroup(group string) error
- func (cm *CatalogMembership) RemoveMemberZone(zoneName string) error
- func (cm *CatalogMembership) RemoveZoneGroup(zoneName, group string) error
- type CatalogPolicy
- type CatalogPost
- type CatalogResponse
- type CatalogZoneCallback
- type CatalogZoneUpdate
- type ChildDelegationData
- type ChunkPayloadStore
- type CombinerDebugPost
- type CombinerDebugResponse
- type CombinerDistribPost
- type CombinerDistribResponse
- type CombinerEditPost
- type CombinerEditResponse
- type CombinerOption
- type CombinerPost
- type CombinerResponse
- type CombinerState
- func (cs *CombinerState) ChunkHandler() *transport.ChunkNotifyHandler
- func (cs *CombinerState) ProcessUpdate(req *CombinerSyncRequest, localAgents map[string]bool, kdb *KeyDB, ...) *CombinerSyncResponse
- func (cs *CombinerState) SetGetPeerAddress(fn func(senderID string) (address string, ok bool))
- func (cs *CombinerState) SetRouter(router *transport.DNSMessageRouter)
- func (cs *CombinerState) SetSecureWrapper(sw *transport.SecurePayloadWrapper)
- type CombinerSyncRequest
- type CombinerSyncRequestPlus
- type CombinerSyncResponse
- type CommandPost
- type CommandResponse
- type Config
- func (conf *Config) APIagent(refreshZoneCh chan<- ZoneRefresher, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)
- func (conf *Config) APIagentDebug() func(w http.ResponseWriter, r *http.Request)
- func (conf *Config) APIagentDistrib(cache *DistributionCache) func(w http.ResponseWriter, r *http.Request)
- func (conf *Config) APIagentTransaction(cache *DistributionCache) func(w http.ResponseWriter, r *http.Request)
- func (conf *Config) APIbeat() func(w http.ResponseWriter, r *http.Request)
- func (conf *Config) APIcombinerDistrib(cache *DistributionCache) func(w http.ResponseWriter, r *http.Request)
- func (conf *Config) APIcombinerTransaction() func(w http.ResponseWriter, r *http.Request)
- func (conf *Config) APIhello() func(w http.ResponseWriter, r *http.Request)
- func (conf *Config) APImsg() func(w http.ResponseWriter, r *http.Request)
- func (conf *Config) APIsyncPing() func(w http.ResponseWriter, r *http.Request)
- func (conf *Config) AddDynamicZoneToConfig(zd *ZoneData) error
- func (conf *Config) CheckDynamicConfigFileIncluded(includedFiles []string) bool
- func (conf *Config) FindDnsEngineAddrs() ([]string, error)
- func (conf *Config) ImrEngine(ctx context.Context, quiet bool) error
- func (conf *Config) InitializeKeyDB() error
- func (conf *Config) LoadDynamicZoneFiles(ctx context.Context) error
- func (conf *Config) LocalIdentity() string
- func (conf *Config) MainInit(ctx context.Context, defaultcfg string) error
- func (conf *Config) MainLoop(ctx context.Context, cancel context.CancelFunc)
- func (conf *Config) NewAgentRegistry() *AgentRegistry
- func (conf *Config) ParseConfig(reload bool) error
- func (conf *Config) ParseZones(ctx context.Context, reload bool) ([]string, error)
- func (conf *Config) ReloadConfig() (string, error)
- func (conf *Config) ReloadZoneConfig(ctx context.Context) (string, error)
- func (conf *Config) RemoveDynamicZoneFromConfig(zoneName string) error
- func (conf *Config) SetupAPIRouter(ctx context.Context) (*mux.Router, error)
- func (conf *Config) SetupAgent(all_zones []string) error
- func (conf *Config) SetupAgentAutoZone(zonename string) (*ZoneData, error)
- func (conf *Config) SetupAgentSyncRouter(ctx context.Context) (*mux.Router, error)
- func (conf *Config) SetupCombinerSyncRouter(ctx context.Context) (*mux.Router, error)
- func (conf *Config) SetupSignerSyncRouter(ctx context.Context) (*mux.Router, error)
- func (conf *Config) SetupSimpleAPIRouter(ctx context.Context) (*mux.Router, error)
- func (conf *Config) ShouldPersistZone(zd *ZoneData) bool
- func (conf *Config) StartAgent(ctx context.Context, apirouter *mux.Router) error
- func (conf *Config) StartAuth(ctx context.Context, apirouter *mux.Router) error
- func (conf *Config) StartCombiner(ctx context.Context, apirouter *mux.Router) error
- func (conf *Config) StartImr(ctx context.Context, apirouter *mux.Router) error
- func (conf *Config) StartScanner(ctx context.Context, apirouter *mux.Router) error
- func (conf *Config) SynchedDataEngine(ctx context.Context, msgQs *MsgQs)
- func (conf *Config) WriteDynamicConfigFile() error
- type ConfigEntry
- type ConfigGroupConfig
- type ConfigPost
- type ConfigResponse
- type ConfigResponseMsg
- type ConfirmationDetail
- type ConfirmationItem
- type CurrentScanData
- type CurrentScanDataJSON
- type CustomValidator
- type DBDelegationBackend
- func (b *DBDelegationBackend) ApplyChildUpdate(parentZone string, ur UpdateRequest) error
- func (b *DBDelegationBackend) GetDelegationData(parentZone, childZone string) (map[string]map[uint16][]dns.RR, error)
- func (b *DBDelegationBackend) ListChildren(parentZone string) ([]string, error)
- func (b *DBDelegationBackend) Name() string
- type DbConf
- type DebugPost
- type DebugResponse
- type DeferredAgentTask
- type DeferredTask
- type DeferredUpdate
- type DelegationBackend
- type DelegationBackendConf
- type DelegationData
- type DelegationPost
- type DelegationResponse
- type DelegationSyncRequest
- type DelegationSyncStatus
- type DirectDelegationBackend
- func (b *DirectDelegationBackend) ApplyChildUpdate(parentZone string, ur UpdateRequest) error
- func (b *DirectDelegationBackend) GetDelegationData(parentZone, childZone string) (map[string]map[uint16][]dns.RR, error)
- func (b *DirectDelegationBackend) ListChildren(parentZone string) ([]string, error)
- func (b *DirectDelegationBackend) Name() string
- type DistributionCache
- func (dc *DistributionCache) Add(qname string, info *DistributionInfo)
- func (dc *DistributionCache) Get(qname string) (*DistributionInfo, bool)
- func (dc *DistributionCache) List(senderID string) []*DistributionInfo
- func (dc *DistributionCache) MarkCompleted(qname string)
- func (dc *DistributionCache) PurgeAll() int
- func (dc *DistributionCache) PurgeCompleted(olderThan time.Duration) int
- func (dc *DistributionCache) PurgeExpired() int
- func (dc *DistributionCache) StartCleanupGoroutine(ctx context.Context)
- type DistributionInfo
- type DistributionSummary
- type DnsEngineConf
- type DnsHandlerRequest
- type DnsNotifyRequest
- type DnsQueryRequest
- type DnsUpdateRequest
- type DnskeyStatus
- type DnssecKey
- type DnssecKeyWithTimestamps
- type DnssecKeys
- type DnssecPolicy
- type DnssecPolicyConf
- type DsyncResult
- type DsyncSchemeInfo
- type DsyncTarget
- type DynamicCatalogMemberConf
- type DynamicConfigFile
- type DynamicZoneTypeConf
- type DynamicZonesConf
- type EditsResponseMsg
- type EngineFunc
- type EngineRegistration
- type ErrorJournal
- type ErrorJournalEntry
- type ErrorType
- type GlobalStuff
- type GossipMessage
- type GossipStateTable
- func (gst *GossipStateTable) BuildGossipForPeer(peerID string, pgm *ProviderGroupManager, lem ...*LeaderElectionManager) []GossipMessage
- func (gst *GossipStateTable) CheckGroupState(groupHash string, expectedMembers []string)
- func (gst *GossipStateTable) GetGroupState(groupHash string) (map[string]*MemberState, *GroupElectionState, *GroupNameProposal)
- func (gst *GossipStateTable) MergeGossip(msg *GossipMessage)
- func (gst *GossipStateTable) RefreshLocalStates(ar *AgentRegistry, pgm *ProviderGroupManager)
- func (gst *GossipStateTable) SetOnElectionUpdate(fn func(groupHash string, state GroupElectionState))
- func (gst *GossipStateTable) SetOnGroupDegraded(fn func(groupHash string))
- func (gst *GossipStateTable) SetOnGroupOperational(fn func(groupHash string))
- func (gst *GossipStateTable) UpdateLocalState(groupHash string, peerStates map[string]string, zones []string)
- type GroupElectionState
- type GroupNameProposal
- type GroupPrefixesConf
- type HsyncAgentStatus
- type HsyncConfirmationInfo
- type HsyncMetricsInfo
- type HsyncPeerInfo
- type HsyncStatus
- type HsyncSyncOpInfo
- type HsyncTransportEvent
- type Imr
- func (imr *Imr) AuthDNSQuery(ctx context.Context, qname string, qtype uint16, nameservers []string, ...) (*core.RRset, int, cache.CacheContext, error)
- func (imr *Imr) CollectNSAddresses(ctx context.Context, rrset *core.RRset, respch chan *ImrResponse) error
- func (imr *Imr) DefaultDNSKEYFetcher(ctx context.Context, name string) (*core.RRset, error)
- func (imr *Imr) DefaultRRsetFetcher(ctx context.Context, qname string, qtype uint16) (*core.RRset, error)
- func (imr *Imr) DsyncDiscovery(ctx context.Context, child string, verbose bool) (DsyncResult, error)
- func (imr *Imr) ImrQuery(ctx context.Context, qname string, qtype uint16, qclass uint16, ...) (*ImrResponse, error)
- func (imr *Imr) ImrResponder(ctx context.Context, w dns.ResponseWriter, r *dns.Msg, qname string, ...)
- func (imr *Imr) IterativeDNSQuery(ctx context.Context, qname string, qtype uint16, ...) (*core.RRset, int, cache.CacheContext, core.Transport, error)
- func (imr *Imr) IterativeDNSQueryFetcher() cache.RRsetFetcher
- func (imr *Imr) IterativeDNSQueryWithLoopDetection(ctx context.Context, qname string, qtype uint16, ...) (*core.RRset, int, cache.CacheContext, core.Transport, error)
- func (imr *Imr) LookupDSYNCTarget(ctx context.Context, childzone string, dtype uint16, scheme core.DsyncScheme) (*DsyncTarget, error)
- func (imr *Imr) ParentZone(z string) (string, error)
- func (imr *Imr) ParseAdditionalForNSAddrs(ctx context.Context, src string, nsrrset *core.RRset, zonename string, ...) (map[string]*cache.AuthServer, error)
- func (imr *Imr) ProcessAuthDNSResponse(ctx context.Context, qname string, qtype uint16, rrset *core.RRset, rcode int, ...) (bool, error)
- func (imr *Imr) SendRfc9567ErrorReport(ctx context.Context, qname string, qtype uint16, ede_code uint16, ...) error
- func (imr *Imr) StartImrEngineListeners(ctx context.Context, conf *Config) error
- func (imr *Imr) TransportSignalCached(owner string) bool
- func (imr *Imr) TransportSignalRRType() uint16
- type ImrClientQueryHookFunc
- type ImrEngineConf
- type ImrLoggingConf
- type ImrOption
- type ImrOutboundQueryHookFunc
- type ImrRequest
- type ImrResponse
- type ImrResponseHookFunc
- type ImrStubConf
- type InternalConf
- type InternalDnsConf
- type InternalMpConf
- type Ixfr
- type KaspConf
- type KeyBootstrapperRequest
- type KeyConf
- type KeyDB
- func (kdb *KeyDB) APIkeystore(conf *Config) func(w http.ResponseWriter, r *http.Request)
- func (kdb *KeyDB) APItruststore() func(w http.ResponseWriter, r *http.Request)
- func (kdb *KeyDB) ApplyChildUpdateToDB(ur UpdateRequest) error
- func (kdb *KeyDB) ApplyZoneUpdateToDB(ur UpdateRequest) error
- func (kdb *KeyDB) ApprovePendingEdit(editID int) (*PendingEditRecord, error)
- func (db *KeyDB) Begin(context string) (*Tx, error)
- func (kdb *KeyDB) CleanupExpiredHsyncData() error
- func (kdb *KeyDB) ClearApprovedEdits(zone string) (int64, error)
- func (kdb *KeyDB) ClearContributions(zone string) (int64, error)
- func (kdb *KeyDB) ClearPendingEdits(zone string) (int64, error)
- func (kdb *KeyDB) ClearRejectedEdits(zone string) (int64, error)
- func (db *KeyDB) Close() error
- func (kdb *KeyDB) CreateAutoZone(zonename string, addrs []string, nsNames []string) (*ZoneData, error)
- func (kdb *KeyDB) DeferredUpdaterEngine(ctx context.Context) error
- func (kdb *KeyDB) DelegationSyncher(ctx context.Context, delsyncq chan DelegationSyncRequest, ...) error
- func (kdb *KeyDB) DeleteContributions(zone, senderID string) error
- func (kdb *KeyDB) DeletePublishInstruction(zone, senderID string) error
- func (kdb *KeyDB) DnssecKeyMgmt(tx *Tx, kp KeystorePost) (*KeystoreResponse, error)
- func (db *KeyDB) Exec(query string, args ...interface{}) (sql.Result, error)
- func (kdb *KeyDB) GenerateAndStageKey(zone, creator string, alg uint8, keytype string, isMultiProvider bool) (uint16, error)
- func (kdb *KeyDB) GenerateKeypair(owner, creator, state string, rrtype uint16, alg uint8, keytype string, tx *Tx) (*PrivateKeyCache, string, error)
- func (kdb *KeyDB) GetAggregatedMetrics() (*HsyncMetricsInfo, error)
- func (kdb *KeyDB) GetDnssecKeyPropagation(zonename string, keyid uint16) (bool, time.Time, error)
- func (kdb *KeyDB) GetDnssecKeys(zonename, state string) (*DnssecKeys, error)
- func (kdb *KeyDB) GetDnssecKeysByState(zone string, state string) ([]DnssecKeyWithTimestamps, error)
- func (kdb *KeyDB) GetKeyInventory(zonename string) ([]KeyInventoryItem, error)
- func (kdb *KeyDB) GetKeyStatus(zonename string, keyID uint16) (*edns0.KeyStateOption, error)
- func (kdb *KeyDB) GetPeer(peerID string) (*PeerRecord, error)
- func (kdb *KeyDB) GetPendingEdit(editID int) (*PendingEditRecord, error)
- func (kdb *KeyDB) GetPublishInstruction(zone, senderID string) (*StoredPublishInstruction, error)
- func (kdb *KeyDB) GetSig0KeyRaw(zonename, state string) (algorithm, privatekey, keyrr string, found bool, err error)
- func (kdb *KeyDB) GetSig0Keys(zonename, state string) (*Sig0ActiveKeys, error)
- func (kdb *KeyDB) GetSyncOperation(distributionID string) (*SyncOperationRecord, error)
- func (kdb *KeyDB) HandleKeyStateOption(opt *dns.OPT, zonename string) (*edns0.KeyStateOption, error)
- func (kdb *KeyDB) IncrementPeerFailedContacts(peerID string) error
- func (kdb *KeyDB) InitCombinerEditTables() error
- func (kdb *KeyDB) InitHsyncTables() error
- func (kdb *KeyDB) KeyBootstrapper(ctx context.Context) error
- func (kdb *KeyDB) ListApprovedEdits(zone string) ([]*ApprovedEditRecord, error)
- func (kdb *KeyDB) ListPeers(state string) ([]*PeerRecord, error)
- func (kdb *KeyDB) ListPendingEdits(zone string) ([]*PendingEditRecord, error)
- func (kdb *KeyDB) ListRejectedEdits(zone string) ([]*RejectedEditRecord, error)
- func (kdb *KeyDB) ListSyncConfirmations(distributionID string, limit int) ([]*SyncConfirmationRecord, error)
- func (kdb *KeyDB) ListSyncOperations(zoneName string, limit int) ([]*SyncOperationRecord, error)
- func (kdb *KeyDB) ListTransportEvents(peerID string, limit int) ([]*HsyncTransportEvent, error)
- func (kdb *KeyDB) LoadAllContributions() (map[string]map[string]map[string]map[uint16]core.RRset, error)
- func (kdb *KeyDB) LoadAllPublishInstructions() (map[string]map[string]*StoredPublishInstruction, error)
- func (kdb *KeyDB) LoadDnskeyTrustAnchors() error
- func (kdb *KeyDB) LoadOutgoingSerial(zone string) (uint32, error)
- func (kdb *KeyDB) LoadSig0ChildKeys() error
- func (kdb *KeyDB) Lock()
- func (kdb *KeyDB) LogTransportEvent(peerID, zoneName, eventType, transportType, direction string, success bool, ...) error
- func (kdb *KeyDB) MarkSyncOperationConfirmed(distributionID string) error
- func (kdb *KeyDB) NextEditID() (int, error)
- func (db *KeyDB) Prepare(q string) (*sql.Stmt, error)
- func (kdb *KeyDB) ProcessKeyState(ks *edns0.KeyStateOption, zonename string) (*edns0.KeyStateOption, error)
- func (kdb *KeyDB) PromoteDnssecKey(zonename string, keyid uint16, oldstate, newstate string) error
- func (db *KeyDB) Query(query string, args ...interface{}) (*sql.Rows, error)
- func (db *KeyDB) QueryRow(query string, args ...interface{}) *sql.Row
- func (kdb *KeyDB) RecordMetrics(peerID, zoneName string, metrics *HsyncMetricsInfo) error
- func (kdb *KeyDB) RejectPendingEdit(editID int, reason string) (*PendingEditRecord, error)
- func (kdb *KeyDB) ResolvePendingEdit(editID int, approvedRecords, rejectedRecords map[string][]string, ...) error
- func (kdb *KeyDB) RolloverKey(zonename string, keytype string, tx *Tx) (uint16, uint16, error)
- func (kdb *KeyDB) SaveContributions(zone, senderID string, contributions map[string]map[uint16]core.RRset) error
- func (kdb *KeyDB) SaveOutgoingSerial(zone string, serial uint32) error
- func (kdb *KeyDB) SavePeer(peer *PeerRecord) error
- func (kdb *KeyDB) SavePendingEdit(rec *PendingEditRecord) error
- func (kdb *KeyDB) SavePublishInstruction(zone, senderID string, instr *core.PublishInstruction, publishedNS []string) error
- func (kdb *KeyDB) SaveSyncConfirmation(conf *SyncConfirmationRecord) error
- func (kdb *KeyDB) SaveSyncOperation(op *SyncOperationRecord) error
- func (kdb *KeyDB) SendSig0KeyUpdate(ctx context.Context, childpri, parpri string, gennewkey bool) error
- func (kdb *KeyDB) SetPropagationConfirmed(zonename string, keyid uint16) error
- func (kdb *KeyDB) Sig0KeyMgmt(tx *Tx, kp KeystorePost) (*KeystoreResponse, error)
- func (kdb *KeyDB) Sig0TrustMgmt(tx *Tx, tp TruststorePost) (*TruststoreResponse, error)
- func (kdb *KeyDB) TransitionMpdistToPublished(zonename string, keyid uint16) error
- func (kdb *KeyDB) TransitionMpremoveToRemoved(zonename string, keyid uint16) error
- func (kdb *KeyDB) TriggerChildKeyVerification(childZone string, keyid uint16, keyRR string)
- func (kdb *KeyDB) Unlock()
- func (kdb *KeyDB) UpdateDnssecKeyState(zonename string, keyid uint16, newstate string) error
- func (kdb *KeyDB) UpdateKeyState(ctx context.Context, keyName string, keyid uint16, imr *Imr, algorithm uint8) error
- func (kdb *KeyDB) UpdatePeerContact(peerID string) error
- func (kdb *KeyDB) UpdatePeerState(peerID, state, reason string) error
- func (kdb *KeyDB) UpdateSyncOperationStatus(distributionID, status, message string) error
- func (kdb *KeyDB) ZoneUpdaterEngine(ctx context.Context) error
- type KeyInventoryItem
- type KeyInventorySnapshot
- type KeyLifetime
- type KeystateInfo
- type KeystateInventoryMsg
- type KeystateSignalMsg
- type KeystorePost
- type KeystoreResponse
- type LeaderElection
- type LeaderElectionManager
- func (lem *LeaderElectionManager) ApplyGossipElection(groupHash string, state GroupElectionState)
- func (lem *LeaderElectionManager) DeferElection(zone ZoneName)
- func (lem *LeaderElectionManager) DeferGroupElection(groupHash string)
- func (lem *LeaderElectionManager) GetAllLeaders() []LeaderStatus
- func (lem *LeaderElectionManager) GetGroupElectionState(groupHash string) GroupElectionState
- func (lem *LeaderElectionManager) GetGroupLeader(groupHash string) (AgentId, bool)
- func (lem *LeaderElectionManager) GetLeader(zone ZoneName) (AgentId, bool)
- func (lem *LeaderElectionManager) GetParentSyncStatus(zone ZoneName, zd *ZoneData, kdb *KeyDB, imr *Imr, ar *AgentRegistry) ParentSyncStatus
- func (lem *LeaderElectionManager) GetPendingElections() []ZoneName
- func (lem *LeaderElectionManager) HandleGroupMessage(groupHash string, senderID AgentId, rfiType string, ...)
- func (lem *LeaderElectionManager) HandleMessage(zone ZoneName, senderID AgentId, rfiType string, records map[string][]string)
- func (lem *LeaderElectionManager) InvalidateGroupLeader(groupHash string)
- func (lem *LeaderElectionManager) IsLeader(zone ZoneName) bool
- func (lem *LeaderElectionManager) NotifyPeerOperational(peerZones map[ZoneName]bool)
- func (lem *LeaderElectionManager) SetConfiguredPeersFunc(f func(zone ZoneName) int)
- func (lem *LeaderElectionManager) SetOnLeaderElected(f func(zone ZoneName) error)
- func (lem *LeaderElectionManager) SetOperationalPeersFunc(f func(zone ZoneName) int)
- func (lem *LeaderElectionManager) SetProviderGroupManager(pgm *ProviderGroupManager)
- func (lem *LeaderElectionManager) StartElection(zone ZoneName, expectedPeers int)
- func (lem *LeaderElectionManager) StartGroupElection(groupHash string, members []string, zones []ZoneName)
- type LeaderStatus
- type LocalAgentApiConf
- type LocalAgentDnsConf
- type LogConf
- type MPTransportBridge
- func (tm *MPTransportBridge) DiscoverAndRegisterAgent(ctx context.Context, identity string) error
- func (tm *MPTransportBridge) EnqueueForCombiner(zone ZoneName, update *ZoneUpdate, distID string) (string, error)
- func (tm *MPTransportBridge) EnqueueForSpecificAgent(zone ZoneName, agentID AgentId, update *ZoneUpdate, distID string) error
- func (tm *MPTransportBridge) EnqueueForZoneAgents(zone ZoneName, update *ZoneUpdate, distID string) error
- func (tm *MPTransportBridge) GetDistributionRecipients(zone ZoneName, skipCombiner bool) []string
- func (tm *MPTransportBridge) GetPreferredTransportName(agent *Agent) string
- func (tm *MPTransportBridge) GetQueuePendingMessages() []transport.PendingMessageInfo
- func (tm *MPTransportBridge) GetQueueStats() transport.QueueStats
- func (tm *MPTransportBridge) HasAPITransport(agent *Agent) bool
- func (tm *MPTransportBridge) HasDNSTransport(agent *Agent) bool
- func (tm *MPTransportBridge) IsPeerAuthorized(senderID string, zone string) (bool, string)
- func (tm *MPTransportBridge) MarkDeliveryConfirmed(distributionID string, senderID string) bool
- func (tm *MPTransportBridge) OnAgentDiscoveryComplete(agent *Agent)
- func (tm *MPTransportBridge) ProcessDnskeyConfirmation(distID string, source string, status string, rejectedItems []RejectedItemInfo) bool
- func (tm *MPTransportBridge) RegisterChunkNotifyHandler() error
- func (tm *MPTransportBridge) RegisterDiscoveredAgent(result *AgentDiscoveryResult) error
- func (tm *MPTransportBridge) SelectTransport(peer *transport.Peer) transport.Transport
- func (tm *MPTransportBridge) SendBeatWithFallback(ctx context.Context, agent *Agent, sequence uint64) (*transport.BeatResponse, error)
- func (tm *MPTransportBridge) SendHelloWithFallback(ctx context.Context, agent *Agent, sharedZones []string) (*transport.HelloResponse, error)
- func (tm *MPTransportBridge) SendPing(ctx context.Context, peer *transport.Peer) (*transport.PingResponse, error)
- func (tm *MPTransportBridge) SendSyncWithFallback(ctx context.Context, peer *transport.Peer, req *transport.SyncRequest) (*transport.SyncResponse, error)
- func (tm *MPTransportBridge) StartIncomingMessageRouter(ctx context.Context)
- func (tm *MPTransportBridge) StartReliableQueue(ctx context.Context)
- func (tm *MPTransportBridge) SyncPeerFromAgent(agent *Agent) *transport.Peer
- func (tm *MPTransportBridge) TrackDnskeyPropagation(zone ZoneName, distID string, keyTags []uint16, agents []AgentId)
- type MPTransportBridgeConfig
- type MPZoneInfo
- type MPdata
- type MSCAPIConf
- type MSCNotifyConf
- type MemChunkPayloadStore
- func (s *MemChunkPayloadStore) Get(qname string) ([]byte, uint8, bool)
- func (s *MemChunkPayloadStore) GetChunk(qname string, sequence uint16) (*core.CHUNK, bool)
- func (s *MemChunkPayloadStore) Set(qname string, payload []byte, format uint8)
- func (s *MemChunkPayloadStore) SetChunks(qname string, chunks []*core.CHUNK)
- type MemberState
- type MemberZone
- type MessageRetentionConf
- type MetaGroupConfig
- type MsgQs
- type MultiProviderConf
- type MultiSignerConf
- type MultiSignerController
- type MultiSignerPost
- type MultiSignerResponse
- type MusicSyncRequest
- type MusicSyncStatus
- type NotifyHandlerFunc
- type NotifyRequest
- type NotifyResponse
- type NotifyStatus
- type OwnerData
- type Owners
- type ParentSyncStatus
- type PeerConf
- type PeerInfo
- type PeerRecord
- type PeerSyncInfo
- type PendingDnskeyPropagation
- type PendingEditRecord
- type PendingRemoteConfirmation
- type PingPost
- type PingResponse
- type PrivateKeyCache
- type ProviderGroup
- type ProviderGroupManager
- func (pgm *ProviderGroupManager) GetGroup(groupHash string) *ProviderGroup
- func (pgm *ProviderGroupManager) GetGroupByName(name string) *ProviderGroup
- func (pgm *ProviderGroupManager) GetGroupForZone(zone ZoneName) *ProviderGroup
- func (pgm *ProviderGroupManager) GetGroups() []*ProviderGroup
- func (pgm *ProviderGroupManager) GetGroupsForIdentity(identity string) []*ProviderGroup
- func (pgm *ProviderGroupManager) ProposeGroupName(groupHash, name string)
- func (pgm *ProviderGroupManager) RecomputeGroups()
- type ProviderZoneConf
- type QueryHandlerFunc
- type RRConfirmation
- type RRState
- type RRTypeStore
- type RRsetString
- type RefreshCounter
- type RefresherResponse
- type RejectedEditRecord
- type RejectedItem
- type RejectedItemInfo
- type RemoteConfirmationDetail
- type RfiData
- type ScanJobStatus
- type ScanRequest
- type ScanResponse
- type ScanTuple
- type ScanTupleResponse
- type ScanType
- type Scanner
- func (scanner *Scanner) AddLogger(rrtype string) error
- func (scanner *Scanner) AuthQueryNG(qname, ns string, rrtype uint16, transport string) (*core.RRset, error)
- func (scanner *Scanner) CheckCDS(ctx context.Context, tuple ScanTuple, scanType ScanType, ...)
- func (scanner *Scanner) CheckCSYNC(sr ScanRequest, cdd *ChildDelegationData) (*ChildDelegationData, error)
- func (scanner *Scanner) CheckDNSKEY(ctx context.Context, tuple ScanTuple, scanType ScanType, ...)
- func (scanner *Scanner) CsyncAnalyzeA(zone string, new_nsrrs []*dns.NS, cdd *ChildDelegationData) ([]dns.RR, bool, error)
- func (scanner *Scanner) CsyncAnalyzeAAAA(zone string, new_nsrrs []*dns.NS, cdd *ChildDelegationData) ([]dns.RR, bool, error)
- func (scanner *Scanner) CsyncAnalyzeNS(zone string, cdd *ChildDelegationData) ([]dns.RR, bool, error)
- func (scanner *Scanner) HasOption(name string) bool
- func (scanner *Scanner) ProcessCDSNotify(ctx context.Context, tuple ScanTuple, parentZD *ZoneData, scanType ScanType, ...)
- func (scanner *Scanner) ProcessCSYNCNotify(ctx context.Context, tuple ScanTuple, parentZD *ZoneData, scanType ScanType, ...)
- func (scanner *Scanner) UpdateCsyncStatus(zone string, csyncrr *dns.CSYNC) error
- func (scanner *Scanner) ZoneCSYNCKnown(zone string, csyncrr *dns.CSYNC) bool
- type ScannerPost
- type ScannerResponse
- type SensitiveString
- type ServerAddrTuple
- type ServiceConf
- type ShowAPIresponse
- type Sig0ActiveKeys
- type Sig0Key
- type Sig0StoreT
- type Sig0UpdateSigner
- type Sig0tmp
- type SignerOption
- type SigningGroupInfo
- type StatusUpdateMsg
- type StoredPublishInstruction
- type SyncConfirmationRecord
- type SyncOperationRecord
- type SyncRequest
- type SyncResponse
- type SyncStatus
- type SynchedDataCmd
- type SynchedDataCmdResponse
- type SynchedDataResponse
- type SynchedDataUpdate
- type TAtmp
- type TargetUpdateStatus
- type TemplateConf
- type TmpAnchor
- type TmpSig0Key
- type TrackedRR
- type TrackedRRInfo
- type TrackedRRset
- type TransactionErrorSummary
- type TransactionPost
- type TransactionResponse
- type TransactionSummary
- type TransportConf
- type TruststorePost
- type TruststoreResponse
- type TsigDetails
- type Tx
- type UpdateHandlerFunc
- type UpdateHandlerRegistration
- type UpdateMatcherFunc
- type UpdatePolicy
- type UpdatePolicyConf
- type UpdatePolicyDetail
- type UpdateRequest
- type UpdateResult
- type UpdateStatus
- type ValidatorRequest
- type ValidatorResponse
- type VerificationInfo
- type ZoneAgentData
- type ZoneConf
- type ZoneData
- func (zd *ZoneData) AddCombinerData(senderID string, data map[string][]core.RRset) (bool, error)
- func (zd *ZoneData) AddCombinerDataNG(senderID string, data map[string][]string) (bool, error)
- func (zd *ZoneData) AddOwner(owner *OwnerData)
- func (zd *ZoneData) AgentJWKKeyPrep(publishname string, kdb *KeyDB) error
- func (zd *ZoneData) AgentSig0KeyPrep(name string, kdb *KeyDB) error
- func (zd *ZoneData) AnalyseZoneDelegation(imr *Imr) (DelegationSyncStatus, error)
- func (zd *ZoneData) ApplyChildUpdateToZoneData(ur UpdateRequest, kdb *KeyDB) (bool, error)
- func (zd *ZoneData) ApplyZoneUpdateToZoneData(ur UpdateRequest, kdb *KeyDB) (bool, error)
- func (zd *ZoneData) ApproveAuthUpdate(zone string, us *UpdateStatus, r *dns.Msg) (bool, bool, error)
- func (zd *ZoneData) ApproveChildUpdate(zone string, us *UpdateStatus, r *dns.Msg) (bool, bool, error)
- func (zd *ZoneData) ApproveTrustUpdate(zone string, us *UpdateStatus, r *dns.Msg) (bool, bool, error)
- func (zd *ZoneData) ApproveUpdate(zone string, us *UpdateStatus, r *dns.Msg) (bool, bool, error)
- func (zd *ZoneData) BestSyncScheme(ctx context.Context, imr *Imr) (string, *DsyncTarget, error)
- func (zd *ZoneData) BootstrapSig0KeyWithParent(ctx context.Context, alg uint8) (string, UpdateResult, error)
- func (zd *ZoneData) BumpSerial() (BumperResponse, error)
- func (zd *ZoneData) BumpSerialOnly() (BumperResponse, error)
- func (zd *ZoneData) CollectDynamicRRs(conf *Config) []*core.RRset
- func (zd *ZoneData) CombineWithLocalChanges() (bool, error)
- func (zd *ZoneData) ComputeIndices()
- func (zd *ZoneData) CreateTransportSignalRRs(conf *Config) error
- func (zd *ZoneData) DelegationData() (*DelegationData, error)
- func (zd *ZoneData) DelegationDataChangedNG(newzd *ZoneData) (bool, DelegationSyncStatus, error)
- func (zd *ZoneData) DelegationSyncSetup(ctx context.Context, kdb *KeyDB) error
- func (zd *ZoneData) DnskeysChanged(newzd *ZoneData) (bool, DelegationSyncStatus, error)
- func (zd *ZoneData) DnskeysChangedNG(newzd *ZoneData) (bool, error)
- func (zd *ZoneData) DoTransfer() (bool, uint32, error)
- func (zd *ZoneData) EnsureMP()
- func (zd *ZoneData) FetchChildDelegationData(childname string) (*ChildDelegationData, error)
- func (zd *ZoneData) FetchFromFile(verbose, debug, force bool, dynamicRRs []*core.RRset) (bool, error)
- func (zd *ZoneData) FetchFromUpstream(verbose, debug bool, dynamicRRs []*core.RRset) (bool, error)
- func (zd *ZoneData) FetchParentData(imr *Imr) error
- func (zd *ZoneData) FindDelegation(qname string, dnssec_ok bool) *ChildDelegationData
- func (zd *ZoneData) FindDnskey(signer string, keyid uint16) (*cache.CachedDnskeyRRset, error)
- func (zd *ZoneData) FindGlue(nsrrs core.RRset, dnssec_ok bool) (*core.RRset, *core.RRset)
- func (zd *ZoneData) FindGlueSimple(nsrrs core.RRset, dnssec_ok bool) ([]dns.RR, []dns.RR, []dns.RR, []dns.RR)
- func (zd *ZoneData) FindSig0KeyViaDNS(signer string, keyid uint16) (*Sig0Key, error)
- func (zd *ZoneData) FindSig0TrustedKey(signer string, keyid uint16) (*Sig0Key, error)
- func (zd *ZoneData) GenerateNsecChain(kdb *KeyDB) error
- func (zd *ZoneData) GetCombinerData() (map[string][]core.RRset, error)
- func (zd *ZoneData) GetCombinerDataNG() map[string][]RRsetString
- func (zd *ZoneData) GetKeystateError() string
- func (zd *ZoneData) GetKeystateOK() bool
- func (zd *ZoneData) GetKeystateTime() time.Time
- func (zd *ZoneData) GetLastKeyInventory() *KeyInventorySnapshot
- func (zd *ZoneData) GetOwner(qname string) (*OwnerData, error)
- func (zd *ZoneData) GetOwnerNames() ([]string, error)
- func (zd *ZoneData) GetRRset(qname string, rrtype uint16) (*core.RRset, error)
- func (zd *ZoneData) GetRemoteDNSKEYs() []dns.RR
- func (zd *ZoneData) GetSOA() (*dns.SOA, error)
- func (zd *ZoneData) HsyncChanged(newzd *ZoneData) (bool, *HsyncStatus, error)
- func (zd *ZoneData) InjectSignatureTXT(conf *MultiProviderConf) bool
- func (zd *ZoneData) IsChildDelegation(qname string) bool
- func (zd *ZoneData) LoadDynamicZoneFile(zoneDirectory string) (bool, uint32, error)
- func (zd *ZoneData) LocalDnskeysChanged(newzd *ZoneData) (bool, *DnskeyStatus, error)
- func (zd *ZoneData) LocalDnskeysFromKeystate() (bool, *DnskeyStatus, error)
- func (zd *ZoneData) Lock()
- func (zd *ZoneData) LookupAndValidateRRset(qname string, qtype uint16, verbose bool) (*core.RRset, bool, error)
- func (zd *ZoneData) LookupChildRRset(qname string, qtype uint16, v4glue, v6glue *core.RRset, verbose bool) (*core.RRset, error)
- func (zd *ZoneData) LookupChildRRsetNG(qname string, qtype uint16, addrs []string, verbose bool) (*core.RRset, error)
- func (zd *ZoneData) LookupRRset(qname string, qtype uint16, verbose bool) (*core.RRset, error)
- func (zd *ZoneData) MusicSig0KeyPrep(name string, kdb *KeyDB) error
- func (zd *ZoneData) NameExists(qname string) bool
- func (zd *ZoneData) NotifyDownstreams() error
- func (zd *ZoneData) ParentSig0KeyPrep(name string, kdb *KeyDB) error
- func (zd *ZoneData) ParseZoneFromReader(r io.Reader, force bool, filename string) (bool, uint32, error)
- func (zd *ZoneData) PrintApexRRs() error
- func (zd *ZoneData) PrintOwnerNames() error
- func (zd *ZoneData) PrintOwners()
- func (zd *ZoneData) PublishAddrRR(name, addr string) error
- func (zd *ZoneData) PublishCdsRRs() error
- func (zd *ZoneData) PublishCsyncRR() error
- func (zd *ZoneData) PublishDnskeyRRs(dak *DnssecKeys) error
- func (zd *ZoneData) PublishDsyncRRs() error
- func (zd *ZoneData) PublishJWKFromKeyRR(owner string, keyRR *dns.KEY) error
- func (zd *ZoneData) PublishJWKRR(owner string, publicKey crypto.PublicKey, use string) error
- func (zd *ZoneData) PublishKeyRRs(sak *Sig0ActiveKeys) error
- func (zd *ZoneData) PublishSvcbRR(name string, port uint16, value []dns.SVCBKeyValue) error
- func (zd *ZoneData) PublishTlsaRR(name string, port uint16, certPEM string) error
- func (zd *ZoneData) PublishUriRR(owner, target, baseurl string, port uint16) error
- func (zd *ZoneData) QueryResponder(ctx context.Context, w dns.ResponseWriter, r *dns.Msg, qname string, ...) error
- func (zd *ZoneData) ReadZoneData(zoneData string, force bool) (bool, uint32, error)
- func (zd *ZoneData) ReadZoneFile(filename string, force bool) (bool, uint32, error)
- func (zd *ZoneData) Refresh(verbose, debug, force bool, conf *Config) (bool, error)
- func (zd *ZoneData) ReloadZone(refreshCh chan<- ZoneRefresher, force bool, wait bool, timeoutStr string) (string, error)
- func (zd *ZoneData) RemoveCombinerDataByRRtype(senderID string, owner string, rrtype uint16) ([]string, error)
- func (zd *ZoneData) RemoveCombinerDataNG(senderID string, data map[string][]string) ([]string, error)
- func (zd *ZoneData) ReplaceCombinerDataByRRtype(senderID, owner string, rrtype uint16, newRRs []dns.RR) (applied []string, removed []string, changed bool, err error)
- func (zd *ZoneData) RepopulateDynamicRRs(dynamicRRs []*core.RRset)
- func (zd *ZoneData) RequestAndWaitForEdits(ctx context.Context)
- func (zd *ZoneData) RequestAndWaitForKeyInventory(ctx context.Context)
- func (zd *ZoneData) RolloverSig0KeyWithParent(ctx context.Context, alg uint8, action string) (string, uint16, uint16, UpdateResult, error)
- func (zd *ZoneData) SendNotify(ntype uint16, targets []string) (int, error)
- func (zd *ZoneData) SetError(errtype ErrorType, errmsg string, args ...interface{})
- func (zd *ZoneData) SetKeystateError(err string)
- func (zd *ZoneData) SetKeystateOK(ok bool)
- func (zd *ZoneData) SetKeystateTime(t time.Time)
- func (zd *ZoneData) SetLastKeyInventory(inv *KeyInventorySnapshot)
- func (zd *ZoneData) SetOption(option ZoneOption, value bool)
- func (zd *ZoneData) SetRemoteDNSKEYs(keys []dns.RR)
- func (zd *ZoneData) SetupZoneSigning(resignq chan<- *ZoneData) error
- func (zd *ZoneData) SetupZoneSync(delsyncq chan<- DelegationSyncRequest) error
- func (zd *ZoneData) ShowNsecChain() ([]string, error)
- func (zd *ZoneData) Sig0KeyPreparation(name string, alg uint8, kdb *KeyDB) error
- func (zd *ZoneData) SignRRset(rrset *core.RRset, name string, dak *DnssecKeys, force bool) (bool, error)
- func (zd *ZoneData) SignZone(kdb *KeyDB, force bool) (int, error)
- func (zd *ZoneData) SortFunc(rr dns.RR, firstSoaSeen bool) bool
- func (zd *ZoneData) SyncZoneDelegation(ctx context.Context, kdb *KeyDB, notifyq chan NotifyRequest, ...) (string, uint8, UpdateResult, error)
- func (zd *ZoneData) SyncZoneDelegationViaNotify(kdb *KeyDB, notifyq chan NotifyRequest, syncstate DelegationSyncStatus, ...) (string, uint8, error)
- func (zd *ZoneData) SyncZoneDelegationViaUpdate(kdb *KeyDB, syncstate DelegationSyncStatus, dsynctarget *DsyncTarget) (string, uint8, UpdateResult, error)
- func (zd *ZoneData) TrustUpdate(r *dns.Msg, us *UpdateStatus) error
- func (zd *ZoneData) Unlock()
- func (zd *ZoneData) UnpublishAddrRR(name, addr string) error
- func (zd *ZoneData) UnpublishCdsRRs() error
- func (zd *ZoneData) UnpublishCsyncRR() error
- func (zd *ZoneData) UnpublishDsyncRRs() error
- func (zd *ZoneData) UnpublishKeyRRs() error
- func (zd *ZoneData) UnpublishSvcbRR(name string) error
- func (zd *ZoneData) UnpublishTlsaRR(port uint16) error
- func (zd *ZoneData) UnpublishUriRR(owner, target string) error
- func (zd *ZoneData) ValidateChildDnskeys(cdd *ChildDelegationData, verbose bool) (bool, error)
- func (zd *ZoneData) ValidateHsyncRRset() (bool, error)
- func (zd *ZoneData) ValidateRRset(rrset *core.RRset, verbose bool) (bool, error)
- func (zd *ZoneData) ValidateUpdate(r *dns.Msg, us *UpdateStatus) error
- func (zd *ZoneData) VerifyPublishedKeyRRs() error
- func (zd *ZoneData) WriteDynamicZoneFile(zoneDirectory string) (string, error)
- func (zd *ZoneData) WriteFile(filename string) (string, error)
- func (zd *ZoneData) WriteTmpFile(lg *log.Logger) (string, error)
- func (zd *ZoneData) WriteZone(tosource bool, force bool) (string, error)
- func (zd *ZoneData) WriteZoneToFile(f *os.File) error
- func (zd *ZoneData) XXfindServerTSYNCRRset() *core.RRset
- func (zd *ZoneData) ZoneFileName() (string, error)
- func (zd *ZoneData) ZoneTransferIn(upstream string, serial uint32, ttype string) (uint32, error)
- func (zd *ZoneData) ZoneTransferOut(w dns.ResponseWriter, r *dns.Msg) (int, error)
- func (zd *ZoneData) ZoneUpdateChangesDelegationDataNG(ur UpdateRequest) (DelegationSyncStatus, error)
- type ZoneDataRepo
- func (zdr *ZoneDataRepo) AddConfirmedRR(zone ZoneName, agentID AgentId, rr dns.RR)
- func (zdr *ZoneDataRepo) EvaluateUpdate(synchedDataUpdate *SynchedDataUpdate) (bool, string, error)
- func (zdr *ZoneDataRepo) Get(zone ZoneName) (*AgentRepo, bool)
- func (zdr *ZoneDataRepo) MarkRRsPending(zone ZoneName, agent AgentId, update *ZoneUpdate, distID string, ...)
- func (zdr *ZoneDataRepo) ProcessConfirmation(detail *ConfirmationDetail, msgQs *MsgQs)
- func (zdr *ZoneDataRepo) ProcessUpdate(synchedDataUpdate *SynchedDataUpdate) (bool, string, error)
- func (zdr *ZoneDataRepo) SendUpdate(update *SynchedDataUpdate) error
- func (zdr *ZoneDataRepo) Set(zone ZoneName, agentRepo *AgentRepo)
- type ZoneDsyncPost
- type ZoneDsyncResponse
- type ZoneMPExtension
- type ZoneName
- type ZoneOption
- type ZoneOptionHandler
- type ZonePost
- type ZoneRefresher
- type ZoneResponse
- type ZoneStore
- type ZoneType
- type ZoneUpdate
- type ZonefileDelegationBackend
- func (b *ZonefileDelegationBackend) ApplyChildUpdate(parentZone string, ur UpdateRequest) error
- func (b *ZonefileDelegationBackend) GetDelegationData(parentZone, childZone string) (map[string]map[uint16][]dns.RR, error)
- func (b *ZonefileDelegationBackend) ListChildren(parentZone string) ([]string, error)
- func (b *ZonefileDelegationBackend) Name() string
Constants ¶
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.
const ( MaxOperationsPerUpdate = 1000 // Maximum operations in a single update MaxRecordsPerOwner = 500 // Maximum records per owner per RRtype in a single operation )
Resource limits to prevent abuse via oversized updates
const ( AgentMsgHello = core.AgentMsgHello AgentMsgBeat = core.AgentMsgBeat AgentMsgNotify = core.AgentMsgNotify AgentMsgRfi = core.AgentMsgRfi AgentMsgStatus = core.AgentMsgStatus AgentMsgPing = core.AgentMsgPing AgentMsgEdits = core.AgentMsgEdits )
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 )
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" )
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
const ( Sig0StateCreated string = "created" Sig0StatePublished string = "published" Sig0StateActive string = "active" Sig0StateRetired string = "retired" DnskeyStateCreated string = "created" DnskeyStateMpdist string = "mpdist" // multi-provider distribution: awaiting confirmation from all providers DnskeyStateMpremove string = "mpremove" // multi-provider removal: awaiting confirmation from all providers DnskeyStatePublished string = "published" DnskeyStateStandby string = "standby" DnskeyStateActive string = "active" DnskeyStateRetired string = "retired" DnskeyStateRemoved string = "removed" DnskeyStateForeign string = "foreign" )
const ( SvcbTransportKey uint16 = 65280 SvcbTLSAKey uint16 = 65281 SvcbBootstrapKey uint16 = 65282 // "bootstrap" SvcParamKey per draft-ietf-dnsop-delegation-mgmt-via-ddns-01 )
Private-use SVCB key codes for TDNS. RFC 9460 reserves 65280–65534 for local assignments.
const DefaultDnskeyTTL = 3600 * time.Second
DefaultDnskeyTTL is the assumed DNSKEY RRset TTL for multi-provider gating. Used when the actual TTL is not readily available. 3600 seconds (1 hour) is a common DNSKEY RRset TTL.
const (
TimeLayout = "2006-01-02 15:04:05"
)
Variables ¶
var AgentMsgToString = core.AgentMsgToString
var AgentOptionToString = map[AgentOption]string{}
var AgentStateToString = map[AgentState]string{ AgentStateNeeded: "NEEDED", AgentStateKnown: "KNOWN", AgentStateIntroduced: "INTRODUCED", AgentStateOperational: "OPERATIONAL", AgentStateLegacy: "LEGACY", AgentStateDegraded: "DEGRADED", AgentStateInterrupted: "INTERRUPTED", AgentStateError: "ERROR", }
var AllowedLocalRRtypes = AllowedRRtypePresets["apex-combiner"]
AllowedLocalRRtypes is the active preset. Default: "apex-combiner".
var AllowedRRtypePresets = map[string]map[uint16]bool{ "apex-combiner": { dns.TypeDNSKEY: true, dns.TypeCDS: true, dns.TypeCSYNC: true, dns.TypeNS: true, dns.TypeKEY: true, }, }
Named presets for allowed RRtypes. Hardcoded for safety. "apex-combiner": manages DNSKEY, CDS, CSYNC, NS, KEY at the zone apex. "delegation-combiner": (future) manages NS, DS, GLUE at delegation points.
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", AppTypeMPSigner: "mpsigner", AppTypeMPAgent: "mpagent", AppTypeMPCombiner: "mpcombiner", }
var AuthOptionToString = map[AuthOption]string{ AuthOptParentUpdate: "parent-update", AuthOptPersistOutboundSerial: "persist-outbound-serial", }
var CombinerOptionToString = map[CombinerOption]string{ CombinerOptAddSignature: "add-signature", }
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,
parent_state INTEGER DEFAULT 0,
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,
propagation_confirmed INTEGER DEFAULT 0,
propagation_confirmed_at TEXT DEFAULT '',
published_at TEXT DEFAULT '',
retired_at TEXT DEFAULT '',
UNIQUE (zonename, keyid)
)`,
}
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.
var ErrZoneNotReady = errors.New("zone data is not yet ready")
ErrZoneNotReady is returned by GetOwner/GetRRset when the zone data has not been loaded yet (zd.Ready == false). Callers that need to handle initial-load gracefully can check with errors.Is.
var ErrorTypeToString = map[ErrorType]string{ ConfigError: "config", RefreshError: "refresh", AgentError: "agent", DnssecError: "DNSSEC", }
var Globals = GlobalStuff{ Verbose: false, Debug: false, ApiClients: map[string]*ApiClient{}, }
var HsyncIndexes = []string{
`CREATE INDEX IF NOT EXISTS idx_peer_registry_state ON PeerRegistry(state)`,
`CREATE INDEX IF NOT EXISTS idx_peer_registry_last_contact ON PeerRegistry(last_contact_at)`,
`CREATE INDEX IF NOT EXISTS idx_peer_zones_zone ON PeerZones(zone_name)`,
`CREATE INDEX IF NOT EXISTS idx_peer_zones_peer ON PeerZones(peer_id)`,
`CREATE INDEX IF NOT EXISTS idx_sync_ops_zone ON SyncOperations(zone_name)`,
`CREATE INDEX IF NOT EXISTS idx_sync_ops_status ON SyncOperations(status)`,
`CREATE INDEX IF NOT EXISTS idx_sync_ops_created ON SyncOperations(created_at)`,
`CREATE INDEX IF NOT EXISTS idx_sync_ops_sender ON SyncOperations(sender_id)`,
`CREATE INDEX IF NOT EXISTS idx_sync_ops_receiver ON SyncOperations(receiver_id)`,
`CREATE INDEX IF NOT EXISTS idx_sync_confirm_distribution ON SyncConfirmations(distribution_id)`,
`CREATE INDEX IF NOT EXISTS idx_sync_confirm_status ON SyncConfirmations(status)`,
`CREATE INDEX IF NOT EXISTS idx_metrics_time ON OperationalMetrics(metric_time)`,
`CREATE INDEX IF NOT EXISTS idx_metrics_peer ON OperationalMetrics(peer_id)`,
`CREATE INDEX IF NOT EXISTS idx_events_time ON TransportEvents(event_time)`,
`CREATE INDEX IF NOT EXISTS idx_events_peer ON TransportEvents(peer_id)`,
`CREATE INDEX IF NOT EXISTS idx_events_type ON TransportEvents(event_type)`,
`CREATE INDEX IF NOT EXISTS idx_events_expires ON TransportEvents(expires_at)`,
`CREATE INDEX IF NOT EXISTS idx_pending_edits_zone ON CombinerPendingEdits(zone)`,
`CREATE INDEX IF NOT EXISTS idx_approved_edits_zone ON CombinerApprovedEdits(zone)`,
`CREATE INDEX IF NOT EXISTS idx_rejected_edits_zone ON CombinerRejectedEdits(zone)`,
`CREATE INDEX IF NOT EXISTS idx_publish_instr_zone ON CombinerPublishInstructions(zone)`,
`CREATE INDEX IF NOT EXISTS idx_contributions_zone ON CombinerContributions(zone)`,
`CREATE INDEX IF NOT EXISTS idx_contributions_zone_sender ON CombinerContributions(zone, sender_id)`,
}
HsyncIndexes defines indexes for the HSYNC tables.
var HsyncTables = map[string]string{
"PeerRegistry": `CREATE TABLE IF NOT EXISTS 'PeerRegistry' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
peer_id TEXT NOT NULL UNIQUE,
-- Discovery information
discovery_time INTEGER NOT NULL, -- Unix timestamp when first discovered
discovery_source TEXT, -- "hsync", "manual", "dns"
-- API transport details
api_endpoint TEXT, -- Full URL for API transport
api_host TEXT, -- Hostname for API transport
api_port INTEGER, -- Port for API transport
api_tlsa_record TEXT, -- TLSA record (wire format, base64)
api_available INTEGER DEFAULT 0, -- 1 if API transport is available
-- DNS transport details
dns_host TEXT, -- Hostname for DNS transport
dns_port INTEGER DEFAULT 53, -- Port for DNS transport
dns_key_record TEXT, -- KEY record (wire format, base64)
dns_available INTEGER DEFAULT 0, -- 1 if DNS transport is available
-- Operational address (may differ from discovery address for DDoS mitigation)
operational_host TEXT,
operational_port INTEGER,
operational_transport TEXT, -- "udp", "tcp", "https"
-- Public keys for encryption/verification
encryption_pubkey TEXT, -- JWK format public key for encryption
verification_pubkey TEXT, -- JWK format public key for signature verification
-- State and preferences
state TEXT DEFAULT 'needed', -- needed, known, introducing, operational, degraded, interrupted, error
state_reason TEXT, -- Reason for current state
state_changed_at INTEGER, -- Unix timestamp of last state change
preferred_transport TEXT DEFAULT 'api', -- api, dns
-- Metrics
last_contact_at INTEGER, -- Unix timestamp of last successful contact
last_hello_at INTEGER, -- Unix timestamp of last hello handshake
last_beat_at INTEGER, -- Unix timestamp of last heartbeat received
beat_interval INTEGER DEFAULT 30, -- Expected heartbeat interval in seconds
beats_sent INTEGER DEFAULT 0, -- Total heartbeats sent
beats_received INTEGER DEFAULT 0, -- Total heartbeats received
failed_contacts INTEGER DEFAULT 0, -- Consecutive failed contact attempts
-- Metadata
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE(peer_id)
)`,
"PeerZones": `CREATE TABLE IF NOT EXISTS 'PeerZones' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
peer_id TEXT NOT NULL,
zone_name TEXT NOT NULL,
-- Relationship details
relationship TEXT DEFAULT 'peer', -- peer, upstream, downstream
role TEXT, -- provider, owner, backup
hsync_identity TEXT, -- Identity from HSYNC record
-- Sync state per zone
last_sync_at INTEGER, -- Unix timestamp of last successful sync
sync_serial INTEGER, -- Last synced SOA serial
sync_state TEXT DEFAULT 'pending', -- pending, synced, conflict, error
-- Metadata
added_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE(peer_id, zone_name),
FOREIGN KEY(peer_id) REFERENCES PeerRegistry(peer_id) ON DELETE CASCADE
)`,
"SyncOperations": `CREATE TABLE IF NOT EXISTS 'SyncOperations' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
distribution_id TEXT NOT NULL UNIQUE,
-- Operation details
zone_name TEXT NOT NULL,
sync_type TEXT NOT NULL, -- NS, DNSKEY, GLUE, CDS, CSYNC
direction TEXT NOT NULL, -- outbound, inbound
-- Participants
sender_id TEXT NOT NULL,
receiver_id TEXT NOT NULL,
-- Payload
records TEXT, -- JSON array of RR strings
serial INTEGER, -- SOA serial at time of sync
-- Transport used
transport TEXT, -- api, dns
encrypted INTEGER DEFAULT 0, -- 1 if payload was encrypted
-- Status tracking
status TEXT DEFAULT 'pending', -- pending, sent, received, confirmed, failed, rejected
status_message TEXT,
-- Timestamps
created_at INTEGER NOT NULL,
sent_at INTEGER,
received_at INTEGER,
confirmed_at INTEGER,
expires_at INTEGER, -- For replay protection
-- Error tracking
retry_count INTEGER DEFAULT 0,
last_error TEXT,
last_error_at INTEGER
)`,
"SyncConfirmations": `CREATE TABLE IF NOT EXISTS 'SyncConfirmations' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
distribution_id TEXT NOT NULL,
-- Confirmation source
confirmer_id TEXT NOT NULL, -- Peer that sent the confirmation
-- Status
status TEXT NOT NULL, -- success, partial, failed, rejected
message TEXT,
-- Detailed results (JSON)
items_processed TEXT, -- JSON: [{record_type, zone, status, details}]
-- Proof (optional)
signed_proof TEXT, -- DNSSEC signatures from signer
confirmer_signature TEXT, -- JWS signature from confirmer
-- Timestamps
confirmed_at INTEGER NOT NULL,
received_at INTEGER NOT NULL,
FOREIGN KEY(distribution_id) REFERENCES SyncOperations(distribution_id) ON DELETE CASCADE
)`,
"OperationalMetrics": `CREATE TABLE IF NOT EXISTS 'OperationalMetrics' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
metric_time INTEGER NOT NULL, -- Unix timestamp (rounded to minute)
peer_id TEXT, -- NULL for aggregate metrics
zone_name TEXT, -- NULL for aggregate metrics
-- Communication metrics
syncs_sent INTEGER DEFAULT 0,
syncs_received INTEGER DEFAULT 0,
syncs_confirmed INTEGER DEFAULT 0,
syncs_failed INTEGER DEFAULT 0,
-- Heartbeat metrics
beats_sent INTEGER DEFAULT 0,
beats_received INTEGER DEFAULT 0,
beats_missed INTEGER DEFAULT 0,
-- Latency (milliseconds)
avg_latency INTEGER,
max_latency INTEGER,
-- Transport breakdown
api_operations INTEGER DEFAULT 0,
dns_operations INTEGER DEFAULT 0,
UNIQUE(metric_time, peer_id, zone_name)
)`,
"TransportEvents": `CREATE TABLE IF NOT EXISTS 'TransportEvents' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_time INTEGER NOT NULL,
peer_id TEXT,
zone_name TEXT,
-- Event details
event_type TEXT NOT NULL, -- hello, beat, sync, relocate, confirm, error, state_change
transport TEXT, -- api, dns
direction TEXT, -- outbound, inbound
-- Result
success INTEGER, -- 1 for success, 0 for failure
error_code TEXT,
error_message TEXT,
-- Additional context (JSON)
context TEXT,
-- Auto-cleanup: events older than 7 days can be purged
expires_at INTEGER
)`,
"CombinerPendingEdits": `CREATE TABLE IF NOT EXISTS 'CombinerPendingEdits' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
edit_id INTEGER NOT NULL UNIQUE,
zone TEXT NOT NULL,
sender_id TEXT NOT NULL,
delivered_by TEXT NOT NULL DEFAULT '',
distribution_id TEXT NOT NULL,
records_json TEXT NOT NULL,
received_at INTEGER NOT NULL
)`,
"CombinerApprovedEdits": `CREATE TABLE IF NOT EXISTS 'CombinerApprovedEdits' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
edit_id INTEGER NOT NULL UNIQUE,
zone TEXT NOT NULL,
sender_id TEXT NOT NULL,
distribution_id TEXT NOT NULL,
records_json TEXT NOT NULL,
received_at INTEGER NOT NULL,
approved_at INTEGER NOT NULL
)`,
"CombinerRejectedEdits": `CREATE TABLE IF NOT EXISTS 'CombinerRejectedEdits' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
edit_id INTEGER NOT NULL UNIQUE,
zone TEXT NOT NULL,
sender_id TEXT NOT NULL,
distribution_id TEXT NOT NULL,
records_json TEXT NOT NULL,
received_at INTEGER NOT NULL,
rejected_at INTEGER NOT NULL,
reason TEXT NOT NULL
)`,
"CombinerPublishInstructions": `CREATE TABLE IF NOT EXISTS 'CombinerPublishInstructions' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
zone TEXT NOT NULL,
sender_id TEXT NOT NULL,
key_rrs_json TEXT NOT NULL DEFAULT '[]',
cds_rrs_json TEXT NOT NULL DEFAULT '[]',
locations_json TEXT NOT NULL DEFAULT '[]',
published_ns_json TEXT NOT NULL DEFAULT '[]',
updated_at INTEGER NOT NULL,
UNIQUE(zone, sender_id)
)`,
"CombinerContributions": `CREATE TABLE IF NOT EXISTS 'CombinerContributions' (
id INTEGER PRIMARY KEY AUTOINCREMENT,
zone TEXT NOT NULL,
sender_id TEXT NOT NULL,
owner TEXT NOT NULL,
rrtype INTEGER NOT NULL,
rr TEXT NOT NULL,
updated_at INTEGER NOT NULL,
UNIQUE(zone, sender_id, owner, rrtype, rr)
)`,
"OutgoingSerials": `CREATE TABLE IF NOT EXISTS 'OutgoingSerials' (
zone TEXT NOT NULL PRIMARY KEY,
serial INTEGER NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`,
}
HsyncTables defines the database tables for HSYNC functionality. These are added to the KeyDB during initialization.
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", }
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.
var ScanTypeToString = map[ScanType]string{ ScanRRtype: "rrtype", ScanCDS: "cds", ScanCSYNC: "csync", ScanDNSKEY: "dnskey", }
var ServerName string = "PLACEHOLDER"
var SignerOptionToString = map[SignerOption]string{}
var StringToAgentOption = map[string]AgentOption{}
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, "mpsigner": AppTypeMPSigner, "mpagent": AppTypeMPAgent, "mpcombiner": AppTypeMPCombiner, }
var StringToAuthOption = map[string]AuthOption{ "parent-update": AuthOptParentUpdate, "persist-outbound-serial": AuthOptPersistOutboundSerial, }
var StringToCombinerOption = map[string]CombinerOption{ "add-signature": CombinerOptAddSignature, }
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, }
var StringToScanType = map[string]ScanType{ "rrtype": ScanRRtype, "cds": ScanCDS, "csync": ScanCSYNC, "dnskey": ScanDNSKEY, }
var StringToSignerOption = map[string]SignerOption{}
var StringToZoneOption = map[string]ZoneOption{ "delegation-sync-parent": OptDelSyncParent, "delegation-sync-child": OptDelSyncChild, "allow-updates": OptAllowUpdates, "allow-child-updates": OptAllowChildUpdates, "allow-edits": OptAllowEdits, "fold-case": OptFoldCase, "black-lies": OptBlackLies, "dont-publish-key": OptDontPublishKey, "dont-publish-jwk": OptDontPublishJWK, "online-signing": OptOnlineSigning, "inline-signing": OptInlineSigning, "multi-provider": OptMultiProvider, "dirty": OptDirty, "frozen": OptFrozen, "automatic-zone": OptAutomaticZone, "add-transport-signal": OptAddTransportSignal, "catalog-zone": OptCatalogZone, "catalog-member-auto-create": OptCatalogMemberAutoCreate, "catalog-member-auto-delete": OptCatalogMemberAutoDelete, "mp-manual-approval": OptMPManualApproval, "multi-signer": OptMultiSigner, "mp-not-listed-error": OptMPNotListedErr, "mp-disallow-edits": OptMPDisallowEdits, }
var Templates = make(map[string]ZoneConf)
Add near the top of the file with other vars
var ZoneOptionToString = map[ZoneOption]string{ OptDelSyncParent: "delegation-sync-parent", OptDelSyncChild: "delegation-sync-child", OptAllowUpdates: "allow-updates", OptAllowChildUpdates: "allow-child-updates", OptAllowEdits: "allow-edits", OptFoldCase: "fold-case", OptBlackLies: "black-lies", OptDontPublishKey: "dont-publish-key", OptDontPublishJWK: "dont-publish-jwk", OptOnlineSigning: "online-signing", OptInlineSigning: "inline-signing", OptMultiProvider: "multi-provider", OptDirty: "dirty", OptFrozen: "frozen", OptAutomaticZone: "automatic-zone", OptAddTransportSignal: "add-transport-signal", OptCatalogZone: "catalog-zone", OptCatalogMemberAutoCreate: "catalog-member-auto-create", OptCatalogMemberAutoDelete: "catalog-member-auto-delete", OptMPManualApproval: "mp-manual-approval", OptMultiSigner: "multi-signer", OptMPNotListedErr: "mp-not-listed-error", OptMPDisallowEdits: "mp-disallow-edits", }
var ZoneStoreToString = map[ZoneStore]string{ XfrZone: "XfrZone", MapZone: "MapZone", SliceZone: "SliceZone", }
var ZoneTypeToString = map[ZoneType]string{ Primary: "primary", Secondary: "secondary", }
var Zones = core.NewCmap[*ZoneData]()
Functions ¶
func APICatalog ¶
func APICatalog(app *AppDetails) func(w http.ResponseWriter, r *http.Request)
APICatalog handles catalog zone management operations
func APIauthDistrib ¶
func APIauthDistrib(conf *Config) func(w http.ResponseWriter, r *http.Request)
APIauthDistrib handles /auth/distrib requests — peer listing for the signer. Uses the same JSON response format as agent/combiner distrib so that listDistribPeers/displayPeers works identically.
func APIauthPeer ¶
func APIauthPeer(conf *Config) func(w http.ResponseWriter, r *http.Request)
APIauthPeer handles /auth/peer requests for multi-provider peer management.
func APIcombiner ¶
func APIcombiner(app *AppDetails, refreshZoneCh chan<- ZoneRefresher, kdb *KeyDB) func(w http.ResponseWriter, r *http.Request)
func APIcombinerDebug ¶
func APIcombinerDebug(conf *Config) func(w http.ResponseWriter, r *http.Request)
func APIcombinerEdits ¶
func APIcombinerEdits(conf *Config) func(w http.ResponseWriter, r *http.Request)
APIcombinerEdits handles /combiner/edits requests for managing pending, approved and rejected edits.
func APIcommand ¶
func APIcommand(stopCh chan struct{}) func(w http.ResponseWriter, r *http.Request) {
func APIdelegation ¶
func APIdelegation(delsyncq chan DelegationSyncRequest) func(w http.ResponseWriter, r *http.Request)
func APIdispatcher ¶
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 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 AddRouterCommandsToSwitch ¶
func AddRouterCommandsToSwitch()
AddRouterCommandsToSwitch adds router command handling to the agent API switch statement. This should be called from APIagent handler to add the router command cases.
Example usage in apihandler_agent.go:
switch amp.Command {
// ... existing cases ...
case "router-list":
if conf.Internal.TransportManager == nil || conf.Internal.TransportManager.Router == nil {
resp.Error = true
resp.ErrorMsg = "Router not available (DNS transport not configured)"
return
}
routerResp := handleRouterList(conf.Internal.TransportManager.Router)
resp = *routerResp
// ... add other router cases ...
}
func AgentToString ¶
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 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 ¶
Return the names of NS RRs that are in bailiwick for the zone.
func CaseFoldContains ¶
func ChildGlueRRsetsToAddrs ¶
func ChunkBase32Data ¶
ChunkBase32Data splits base32 data into chunks of maximum size and adds cookie and sequence prefixes
func ChunksToDomains ¶
ChunksToDomains combines chunks into domain names It dynamically calculates how many chunks can fit in each domain
func CombinerMsgHandler ¶
func CombinerMsgHandler(ctx context.Context, conf *Config, msgQs *MsgQs, protectedNamespaces []string, errorJournal *ErrorJournal)
CombinerMsgHandler consumes beat, hello, ping, and sync messages from MsgQs. Updates PeerRegistry liveness on beats and logs hello/ping messages. Processes sync messages asynchronously: applies zone updates via CombinerProcessUpdate and sends detailed confirmation back to the agent via DNSTransport.Confirm().
func CombinerStateSetChunkHandler ¶
func CombinerStateSetChunkHandler(cs *CombinerState, handler *transport.ChunkNotifyHandler)
CombinerStateSetChunkHandler wraps setting the unexported chunkHandler field on CombinerState.
func ComputeBailiwickNS ¶
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 ¶
ComputeDo53Remainder returns the implicit remainder for do53 (clip at 0).
func ComputeGroupHash ¶
ComputeGroupHash computes a deterministic hash from a sorted, deduplicated list of provider identities. Uses length-prefixed encoding to prevent collisions (e.g., ["a","bb"] vs ["ab","b"]).
func ComputeRRDiff ¶
Only used in the CLI version
func CreateChildReplaceUpdate ¶
func CreateChildReplaceUpdate(parent, child string, newNS, newA, newAAAA, newDS []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 ¶
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 ¶
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 DiscoverAgentAPI ¶
func DiscoverAgentAPI(ctx context.Context, imr *Imr, identity string, result *AgentDiscoveryResult)
DiscoverAgentAPI performs DNS-based discovery of an agent's API transport.
- URI record at _https._tcp.<identity> → get API endpoint URI and port
- SVCB record at api.<identity> → get ipv4hint/ipv6hint addresses
- TLSA record at _<port>._tcp.api.<identity> → get TLS certificate for verification
func DiscoverAgentDNS ¶
func DiscoverAgentDNS(ctx context.Context, imr *Imr, identity string, result *AgentDiscoveryResult)
DiscoverAgentDNS performs DNS-based discovery of an agent's DNS transport.
- URI record at _dns._tcp.<identity> → get DNS endpoint URI and port
- SVCB record at dns.<identity> → get ipv4hint/ipv6hint addresses
- JWK record at dns.<identity> → get JOSE/HPKE public key (preferred)
- KEY record at dns.<identity> → get SIG(0) public key (legacy fallback if no JWK)
func DnsDoHEngine ¶
func DnsDoQEngine ¶
func DnsDoTEngine ¶
func DomainsToBase32 ¶
DomainsToBase32 extracts and combines base32 data from domain names
func DomainsToJson ¶
DomainsToJson converts domain names back to JSON
func DomainsToStruct ¶
DomainsToStruct converts domain names back to a struct
func DotServerQnameResponse ¶
func DotServerQnameResponse(qname string, w dns.ResponseWriter, r *dns.Msg)
func DsyncUpdateTargetName ¶
DsyncUpdateTargetName computes the DSYNC UPDATE target name for a parent zone from the global config. Returns empty string if not configured.
func ExpirationFromTtl ¶
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 ExportDelegationData ¶
func ExportDelegationData(backend DelegationBackend, parentZone, outfile string, defaultTTL uint32) error
ExportDelegationData writes all delegation data for a parent zone to a file in DNS zone file format. Called from the /delegation API handler. defaultTTL is applied to any RR with TTL=0.
func FindSoaRefresh ¶
func GenerateJobID ¶
GenerateJobID generates a unique job ID using crypto/rand.
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 ¶
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 GetProviderZoneRRtypes ¶
GetProviderZoneRRtypes returns the allowed RRtype map for a provider zone, or nil if the zone is not configured as a provider zone.
func GetTransportParam ¶
GetTransportParam fetches and parses the transport parameter from the SVCB RR, if present.
func IsPEMFormat ¶
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 ¶
JsonToBase32Domains converts JSON data to a set of domain names Each domain name contains chunks of base32-encoded data with maximized label sizes
func KeyStateWorker ¶
KeyStateWorker runs periodic checks on DNSSEC key states and performs automatic transitions and standby key maintenance.
func Logger ¶
Logger returns a *slog.Logger for the given subsystem. The subsystem gets its own level (defaulting to the global level). Call it freely — if the subsystem doesn't exist yet, it's created on first use.
func LookupChildKeyAtApex ¶
LookupChildKeyAtApex queries the child zone apex for KEY records via the IMR engine. Returns the KEY RRs found, whether the response was DNSSEC- validated, and any error.
func LookupChildKeyAtSignal ¶
func LookupChildKeyAtSignal(ctx context.Context, childZone string, imr *Imr) ([]dns.RR, bool, error)
LookupChildKeyAtSignal queries _sig0key.<childzone>._signal.<ns>. for KEY records for each NS serving the child zone. Returns the union of KEY RRs found, whether all responses were DNSSEC-validated, and any error.
func MarshalTLSAToString ¶
MarshalTLSAToString renders a TLSA record to the "usage selector matching data" representation.
func MarshalTransport ¶
MarshalTransport converts a transport map back to a canonical string (sorted by key).
func MsgAcceptFunc ¶
func MsgAcceptFunc(dh dns.Header) dns.MsgAcceptAction
func NeedsResigning ¶
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 NewCombinerSyncHandler ¶
func NewCombinerSyncHandler() transport.MessageHandlerFunc
NewCombinerSyncHandler creates a transport.MessageHandlerFunc for combiner UPDATE processing. The handler returns an immediate "pending" ACK in the DNS response and routes the update to MsgQs for async processing by CombinerMsgHandler. The actual CombinerProcessUpdate() runs asynchronously, and the detailed confirmation is sent back as a separate CONFIRM NOTIFY.
func NormalizeAddress ¶
NormalizeAddress ensures an address has a port number. If the address doesn't have a port, ":53" is appended. This allows users to specify addresses as either "IP" or "IP:port" in config. Returns empty string if input is empty.
func NormalizeAddresses ¶
NormalizeAddresses ensures all addresses have a port number. If an address doesn't have a port, ":53" is appended. This allows users to specify addresses as either "IP" or "IP:port" in config.
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 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 NotifyResponder ¶
func NotifyResponder(ctx context.Context, dnr *DnsNotifyRequest, zonech chan ZoneRefresher, scannerq chan ScanRequest) error
TODO: Add per-source rate limiting for NOTIFY messages. An attacker could flood the server with NOTIFY messages to trigger excessive zone refreshes and scanner scans. Consider a token bucket or sliding window rate limiter keyed by source IP.
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 ParseLogLevel ¶
ParseLogLevel converts a string like "debug", "info", "warn", "error" to an slog.Level. Defaults to Info for unrecognized strings.
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 ¶
ParseTLSAFromSvcbLocal parses a private SVCB TLSA key into a dns.TLSA.
func ParseTLSAString ¶
ParseTLSAString parses a TLSA RDATA string of the form "usage selector matching data".
func ParseTsigKeys ¶
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 PrintGenericRR ¶
func PrintJwkRR ¶
func PrintKeyRR ¶
leftpad = amount of white space instead of the domain name on continuation lines during multiline output
func PrintRrsigRR ¶
func PrintSoaRR ¶
func PrintSvcbRR ¶
func PrivKeyToBindFormat ¶
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 PublishKeyToCombiner ¶
PublishKeyToCombiner sends a KEY RR to the combiner as a REPLACE operation. Used by MP zones where the combiner manages the zone apex.
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 ReadPubKeys ¶
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 RefreshEngine ¶
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 RegisterChunkQueryHandler ¶
func RegisterChunkQueryHandler(store ChunkPayloadStore) error
RegisterChunkQueryHandler registers a query handler for CHUNK that serves payloads from the store. Should be called when running as agent with chunk_mode "query". store must not be nil.
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 ¶
RegisterDefaultQueryHandlers registers the default zone-based query handler. This is called automatically during TDNS initialization. The default handler is registered if (a) zones are configured in the config, or (b) app type is Agent (agent gets an autozone from SetupAgent, needed for SOA/AXFR). 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 RegisterImrClientQueryHook ¶
func RegisterImrClientQueryHook(hook ImrClientQueryHookFunc) error
RegisterImrClientQueryHook registers a hook that is called when an external client query arrives at the IMR listener. Multiple hooks can be registered and are called in registration order.
func RegisterImrOutboundQueryHook ¶
func RegisterImrOutboundQueryHook(hook ImrOutboundQueryHookFunc) error
RegisterImrOutboundQueryHook registers a hook that is called before the IMR sends an iterative query to an authoritative server. Multiple hooks can be registered and are called in registration order.
func RegisterImrResponseHook ¶
func RegisterImrResponseHook(hook ImrResponseHookFunc) error
RegisterImrResponseHook registers a hook that is called after the IMR receives a response from an authoritative server. Multiple hooks can be registered and are called in registration order.
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 RegisterProviderZoneRRtypes ¶
func RegisterProviderZoneRRtypes(pz ProviderZoneConf)
RegisterProviderZoneRRtypes parses a ProviderZoneConf and registers its allowed RRtype map for use by the combiner policy engine.
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 RegisterZoneOptionHandler ¶
func RegisterZoneOptionHandler(opt ZoneOption, handler ZoneOptionHandler)
RegisterZoneOptionHandler registers a callback for a zone option. Multiple handlers can be registered for the same option. Handlers fire synchronously during ParseZones, in registration order.
func ResignerEngine ¶
func ResignerEngine(zoneresignch chan ZoneRefresher, stopch chan struct{}) {
func RunKeysCmd ¶
RunKeysCmd runs the "keys" subcommand (generate | show). Used by tdns-cli agent keys / tdns-cli combiner keys. conf must be loaded from the server's config file.
func SanitizeForJSON ¶
func SanitizeForJSON(v interface{}) interface{}
SanitizeForJSON is a wrapper function that sanitizes a struct for JSON serialization
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 SetSubsystemLevel ¶
SetSubsystemLevel sets or updates the log level for a subsystem. Goroutine-safe (uses atomic LevelVar).
func SetupCliLogging ¶
func SetupCliLogging()
SetupCliLogging sets up logging for CLI commands. Default: no source info, no timestamps. Verbose/Debug: adds source info.
func SetupLogging ¶
SetupLogging configures the slog-based logging system with lumberjack rotation. It also bridges the old log package so that existing log.Printf calls flow through slog to the same output.
func Shutdowner ¶
func Sig0KeyOwnerName ¶
Sig0KeyOwnerName computes the RFC 9615-style owner name for a child SIG(0) KEY RR. Format: _sig0key.<zone>._signal.<nameserver>
func SignerMsgHandler ¶
SignerMsgHandler consumes beat, hello, ping, and RFI messages from MsgQs. Updates PeerRegistry liveness on beats and logs hello/ping messages. Processes RFI KEYSTATE requests by querying KeyDB and pushing inventory.
func SprintUpdates ¶
func StartDistributionGC ¶
func StartDistributionGC(cache *DistributionCache, interval time.Duration, stopCh chan struct{})
StartDistributionGC starts a background goroutine that periodically purges: 1. Completed distributions older than 5 minutes 2. Expired distributions past their ExpiresAt time (based on message type retention) Incomplete distributions are never purged by GC (only "purge --force" removes them).
func StartEngine ¶
func StartEngine(app *AppDetails, name string, engineFunc func() error)
startEngine wraps engine functions in a goroutine with error handling. It logs errors if the engine function returns an error, preventing silent failures.
func StartEngineNoError ¶
func StartEngineNoError(app *AppDetails, name string, engineFunc func())
startEngineNoError wraps engine functions that don't return errors. This is for engines that handle errors internally or never fail during startup.
func StartRegisteredEngines ¶
StartRegisteredEngines starts all registered engines as goroutines. This should be called after TDNS initialization is complete. Engines run until the context is cancelled.
func StripKeyFileComments ¶
StripKeyFileComments removes lines that are empty or start with '#' (after trim), so JWK/key files with comment headers (e.g. KDC/KRS-style) parse as valid JSON. Preserves line breaks and indentation of kept lines.
func StructToBase32Domains ¶
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 ¶
TLSAToSvcbLocal marshals a TLSA record into a private SVCB key/value pair.
func TtlPrint ¶
TtlPrint returns a human-friendly TTL remaining until expiration. If the expiration time has passed, it returns "expired".
func TtyQuestion ¶
func TtyRadioButtonQ ¶
func TypeBitMapToString ¶
func UpdateResponder ¶
func UpdateResponder(dur *DnsUpdateRequest, updateq chan UpdateRequest) error
func ValidateAgentNameservers ¶
ValidateAgentNameservers ensures agent.local.nameservers are non-empty and outside the agent autozone (no glue). Each entry is normalized to FQDN (dns.Fqdn) in place so the config never carries non-FQDN names.
func ValidateAgentSupportedMechanisms ¶
ValidateAgentSupportedMechanisms validates agent.supported_mechanisms configuration. Requirements: - Must be non-empty (agent needs at least one communication mechanism) - Can only contain "api" and/or "dns" (case-insensitive) - Default if omitted: ["api", "dns"]
func ValidateBySection ¶
func ValidateCertAndKeyFiles ¶
func ValidateCertAndKeyFiles(fl validator.FieldLevel) bool
validateCertAndKeyFiles is the custom validation function
func ValidateConfigWithCustomValidator ¶
ValidateConfigWithCustomValidator validates the config using the custom validator XXX: Not used at the moment.
func ValidateCryptoFiles ¶
ValidateCryptoFiles validates that configured crypto key files exist and are readable. This is called during config validation to provide early feedback about missing files.
func ValidateDatabaseFile ¶
ValidateDatabaseFile validates that the database file path is set for apps that require it. If db.file is unset or empty, this function returns an error (hard fail).
func ValidateExplicitServerSVCB ¶
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 ValidatorEngine ¶
func VerifyChildKey ¶
func VerifyChildKey(ctx context.Context, childZone string, keyRR string, imr *Imr) (verified bool, dnssecValidated bool)
VerifyChildKey checks whether a child's KEY (identified by keyRR string) can be found via the configured verification mechanisms (at-apex, at-ns). Returns true if any mechanism succeeds (key found + optionally DNSSEC-validated).
func VerifyKey ¶
func VerifyKey(KeyName string, key string, keyid uint16, zd *ZoneData, updatetrustq chan<- KeyBootstrapperRequest)
func WalkRoutes ¶
func ZoneDataWeAreASigner ¶
ZoneDataWeAreASigner wraps the unexported weAreASigner method.
func ZoneIsReady ¶
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.
Types ¶
type APIRouteFunc ¶
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
IsInfraPeer bool // true for combiner/signer — handled by StartInfraBeatLoop, not SendHeartbeats
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) CreateAgentUpstreamRFI ¶
func (agent *Agent) CreateAgentUpstreamRFI() *DeferredAgentTask
func (*Agent) CreateOperationalAgentTask ¶
func (agent *Agent) CreateOperationalAgentTask(action func() (bool, error), desc string) *DeferredAgentTask
func (*Agent) EffectiveState ¶
func (a *Agent) EffectiveState() AgentState
EffectiveState returns the most relevant transport-layer state. DNS is checked first as it is the primary transport. Falls back to the top-level aggregate state if no transport is operational.
func (*Agent) IsAnyTransportOperational ¶
IsAnyTransportOperational returns true if at least one transport layer (DNS or API) is in the OPERATIONAL state. DNS is checked first as it is the primary (and currently only fully implemented) transport.
func (*Agent) MarshalJSON ¶
func (*Agent) NewAgentSyncApiClient ¶
func (agent *Agent) NewAgentSyncApiClient(localagent *MultiProviderConf) 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 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
Gossip []GossipMessage `json:"Gossip,omitempty"`
}
AgentBeatPost is defined in core package to avoid circular dependencies. We keep a wrapper type here that uses AgentId instead of string for backward compatibility.
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
}
AgentBeatResponse is defined in core package to avoid circular dependencies. We keep a wrapper type here that uses AgentId instead of string for backward compatibility.
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 (legacy)
JWKData string // JWK data (preferred for DNS transport)
KeyAlgorithm string // Key algorithm (e.g., "ES256")
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
DiscoveryFailures uint32 // consecutive discovery failures (for IMR cache flush)
HelloTime time.Time
LastContactTime time.Time // Last contact of any type (Hello, Beat, Ping, Sync, etc.)
BeatInterval uint32
SentBeats uint32
ReceivedBeats uint32
LatestSBeat time.Time
LatestRBeat time.Time
}
type AgentDiscoveryResult ¶
type AgentDiscoveryResult struct {
Identity string
APIUri string // Base URI from URI record (e.g., https://agent.example.com:8443/api)
DNSUri string // DNS endpoint if discovered
JWKData string // Base64url-encoded JWK (preferred)
PublicKey crypto.PublicKey // Decoded public key from JWK
KeyAlgorithm string // Algorithm from JWK (e.g., "ES256")
LegacyKeyRR *dns.KEY // Legacy KEY record (fallback if no JWK)
TLSA *dns.TLSA // TLSA record for TLS verification
APIAddresses []string // IP addresses for API service from SVCB
DNSAddresses []string // IP addresses for DNS service from SVCB
Port uint16 // Port from URI record
Error error // Any error during discovery
Partial bool // True if some records were found but discovery incomplete
}
AgentDiscoveryResult holds the result of discovering an agent.
func DiscoverAgent ¶
func DiscoverAgent(ctx context.Context, imr *Imr, identity string) *AgentDiscoveryResult
DiscoverAgent performs full DNS-based discovery of an agent's contact information for both API and DNS transports. Convenience wrapper around DiscoverAgentAPI + DiscoverAgentDNS.
type AgentDistribPost ¶
type AgentDistribPost struct {
Command string `json:"command"` // "list", "purge", "peer-list", "peer-zones", "zone-agents", "op", "discover"
Force bool `json:"force,omitempty"` // for purge
Op string `json:"op,omitempty"` // for op: operation name (e.g. "ping")
To string `json:"to,omitempty"` // for op: recipient identity (e.g. "combiner", "agent.delta.dnslab.")
PingTransport string `json:"ping_transport,omitempty"` // for op ping: "dns" (default) or "api"
AgentId string `json:"agent_id,omitempty"` // for discover: agent identity to discover
Zone string `json:"zone,omitempty"` // for zone-agents: zone name to list agents for
}
AgentDistribPost represents a request to the agent distrib API
type AgentDistribResponse ¶
type AgentDistribResponse struct {
Time time.Time `json:"time"`
Error bool `json:"error,omitempty"`
ErrorMsg string `json:"error_msg,omitempty"`
Msg string `json:"msg,omitempty"`
Summaries []*DistributionSummary `json:"summaries,omitempty"`
Distributions []string `json:"distributions,omitempty"` // For backward compatibility
Data []interface{} `json:"data,omitempty"` // For peer-zones command
Agents []string `json:"agents,omitempty"` // For zone-agents command
}
AgentDistribResponse represents a response from the agent distrib API
type AgentHelloPost ¶
type AgentHelloPost struct {
MessageType AgentMsg
Name string `json:"name,omitempty"` // DEPRECATED: Unused field
MyIdentity AgentId
YourIdentity AgentId
Addresses []string `json:"addresses,omitempty"` // DEPRECATED: Use DNS discovery (SVCB records) instead
Port uint16 `json:"port,omitempty"` // DEPRECATED: Use DNS discovery (URI scheme) instead
TLSA dns.TLSA `json:"tlsa,omitempty"` // DEPRECATED: Use DNS discovery (TLSA query) instead
Zone ZoneName // in the /hello we only send one zone, the one that triggered the /hello
Time time.Time // message timestamp
}
AgentHelloPost is defined in core package to avoid circular dependencies. We keep a wrapper type here that uses AgentId/ZoneName instead of string for backward compatibility.
type AgentHelloResponse ¶
type AgentHelloResponse struct {
Status string // ok | error | ...
MyIdentity AgentId
YourIdentity AgentId
Time time.Time
// Client string
Msg string
Error bool
ErrorMsg string
}
AgentHelloResponse is defined in core package to avoid circular dependencies. We keep a wrapper type here that uses AgentId instead of string for backward compatibility.
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
RfiSubtype string
Data map[string]interface{} `json:"data,omitempty"` // Generic data field for custom parameters
}
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 MultiProviderConf
RfiType string
RfiResponse map[AgentId]*RfiData
AgentRegistry *AgentRegistry
ZoneDataRepo map[ZoneName]map[AgentId]map[uint16][]TrackedRRInfo
KeystateStatus map[ZoneName]KeystateInfo `json:"keystate_status,omitempty"`
Msg string
Error bool
ErrorMsg string
Data interface{} `json:"data,omitempty"` // Generic data field for custom responses
// HSYNC debug data (Phase 5)
HsyncPeers []*HsyncPeerInfo `json:"hsync_peers,omitempty"`
HsyncSyncOps []*HsyncSyncOpInfo `json:"hsync_sync_ops,omitempty"`
HsyncConfirmations []*HsyncConfirmationInfo `json:"hsync_confirmations,omitempty"`
HsyncEvents []*HsyncTransportEvent `json:"hsync_events,omitempty"`
HsyncMetrics *HsyncMetricsInfo `json:"hsync_metrics,omitempty"`
}
type AgentMsg ¶
AgentMsg and related constants are defined in core package to avoid circular dependencies
type AgentMsgPost ¶
type AgentMsgPost struct {
MessageType AgentMsg // "sync", "update", "rfi", "status"
OriginatorID AgentId // Original author of the update
DeliveredBy AgentId // Transport-level sender (who delivered this message to us)
YourIdentity AgentId
Addresses []string `json:"addresses,omitempty"` // DEPRECATED: Use DNS discovery (SVCB records) instead
Port uint16 `json:"port,omitempty"` // DEPRECATED: Use DNS discovery (URI scheme) instead
TLSA dns.TLSA `json:"tlsa,omitempty"` // DEPRECATED: Use DNS discovery (TLSA query) instead
Zone ZoneName // An AgentMsgPost should always only refer to one zone.
Records map[string][]string // Resource records grouped by owner name (legacy: Class-overloaded)
Operations []core.RROperation // Explicit operations (takes precedence over Records)
Time time.Time
RfiType string
RfiSubtype string
DistributionID string // Originating distribution ID from the sending agent
Nonce string // Nonce from the incoming sync/update message (for confirmation echo)
ZoneClass string // "mp" (default) or "provider"
Publish *core.PublishInstruction // KEY/CDS publication instruction for combiner
}
AgentMsgPost is defined in core package to avoid circular dependencies. We keep a wrapper type here that uses AgentId/ZoneName instead of string for backward compatibility. AgentMsg{Post,Response} are intended for agent-to-agent messaging
type AgentMsgPostPlus ¶
type AgentMsgPostPlus struct {
AgentMsgPost
Response chan *AgentMsgResponse
}
type AgentMsgReport ¶
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
}
AgentMsgResponse is defined in core package to avoid circular dependencies. We keep a wrapper type here that uses AgentId/ZoneName instead of string for backward compatibility.
type AgentOption ¶
type AgentOption uint8
type AgentPingPost ¶
type AgentPingPost struct {
MessageType AgentMsg // AgentMsgPing
MyIdentity AgentId // sender's identity
YourIdentity AgentId // recipient's identity
Nonce string // for round-trip verification
Time time.Time // message timestamp
}
AgentPingPost is defined in core package to avoid circular dependencies. We keep a wrapper type here that uses AgentId instead of string for backward compatibility. AgentPingPost is used for ping operations (connectivity testing)
type AgentPingResponse ¶
type AgentPingResponse struct {
Status string // "ok" | "error"
MyIdentity AgentId // responder's identity
YourIdentity AgentId // original sender
Nonce string // echo from request
Time time.Time
Msg string
Error bool
ErrorMsg string
}
AgentPingResponse is defined in core package to avoid circular dependencies. We keep a wrapper type here that uses AgentId instead of string for backward compatibility. AgentPingResponse is the response to a ping operation
type AgentRegistry ¶
type AgentRegistry struct {
S core.ConcurrentMap[AgentId, *Agent]
RegularS map[AgentId]*Agent
RemoteAgents map[ZoneName][]AgentId
LocalAgent *MultiProviderConf // our own identity
LocateInterval int // seconds to wait between locating agents (until success)
TransportManager *transport.TransportManager // Generic transport (Router, PeerRegistry, etc.)
MPTransport *MPTransportBridge // MP transport bridge (authorization, discovery, enqueue, beats, hellos)
LeaderElectionManager *LeaderElectionManager // optional; when set, election messages are processed
ProviderGroupManager *ProviderGroupManager // optional; manages provider group computation
GossipStateTable *GossipStateTable // optional; gossip protocol state
// 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) DiscoverAgentAsync ¶
func (ar *AgentRegistry) DiscoverAgentAsync(remoteid AgentId, zonename ZoneName, deferredTask *DeferredAgentTask)
DiscoverAgentAsync marks an agent as NEEDED for discovery by DiscoveryRetrierNG.
DEPRECATED: This function is now a thin wrapper around MarkAgentAsNeeded() for backward compatibility. New code should call MarkAgentAsNeeded() directly instead.
The old immediate discovery behavior has been replaced with a retry-based approach: - Agents are marked as NEEDED - DiscoveryRetrierNG continuously retries discovery until success - Eliminates IMR race conditions and handles transient failures - Provides infinite retry with backoff (consistent with Hello/Beat mechanisms)
Parameters:
- remoteid: The agent identity to discover
- zonename: Optional zone name to associate with the agent
- deferredTask: Optional task to execute when agent becomes operational
func (*AgentRegistry) DiscoveryRetrierNG ¶
func (ar *AgentRegistry) DiscoveryRetrierNG(ctx context.Context)
DiscoveryRetrierNG continuously attempts to discover agents in NEEDED state. It runs in its own goroutine with a configurable retry interval and only attempts discovery when the IMR engine is available.
func (*AgentRegistry) EvaluateHello ¶
func (ar *AgentRegistry) EvaluateHello(ahp *AgentHelloPost) (bool, string, error)
func (*AgentRegistry) FastBeatAttempts ¶
func (ar *AgentRegistry) FastBeatAttempts(ctx context.Context, agent *Agent)
FastBeatAttempts sends up to 3 beats with 5s spacing after HELLO succeeds. If any beat succeeds (agent becomes OPERATIONAL), returns immediately. If all 3 fail, returns — the normal heartbeat ticker will take over.
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)
HelloRetrierNG manages Hello retries for an agent. Handles both API and DNS transports independently. Continues retrying while EITHER transport is in KNOWN state.
Fast-start: configurable number of immediate attempts with configurable spacing. If all fail, falls back to the normal helloretry ticker. On HELLO success (INTRODUCED), triggers fast beat attempts.
func (*AgentRegistry) InitializeCombinerAsPeer ¶
func (ar *AgentRegistry) InitializeCombinerAsPeer(conf *Config) error
InitializeCombinerAsPeer registers the combiner as a virtual peer in the AgentRegistry so that the HsyncEngine's Beat mechanism will automatically send heartbeats to it. This ensures we verify combiner connectivity and get early warning of communication issues.
func (*AgentRegistry) InitializeSignerAsPeer ¶
func (ar *AgentRegistry) InitializeSignerAsPeer(conf *Config) error
InitializeSignerAsPeer registers the signer as a virtual peer in the AgentRegistry so that it shows up in "agent peer list" and can be pinged via "agent peer ping". Mirrors InitializeCombinerAsPeer for the signer role.
func (*AgentRegistry) LocateAgent ¶
func (ar *AgentRegistry) LocateAgent(remoteid AgentId, zonename ZoneName, deferredTask *DeferredAgentTask)
LocateAgent is completely asynchronous with no return values
DEPRECATED: This function has critical concurrency issues (see docs/locateagent-review-findings.md). It will be replaced by the refactored discovery mechanism using common helpers from agent_discovery_common.go. Keep this implementation for backward compatibility until the migration is complete.
func (*AgentRegistry) MarkAgentAsNeeded ¶
func (ar *AgentRegistry) MarkAgentAsNeeded(remoteid AgentId, zonename ZoneName, deferredTask *DeferredAgentTask)
MarkAgentAsNeeded creates a placeholder agent in NEEDED state. The agent will be discovered asynchronously by DiscoveryRetrierNG in HsyncEngine. This is the new recommended pattern for agent discovery triggered by HSYNC updates.
Parameters:
- remoteid: The agent identity to mark as needed
- zonename: Optional zone name to associate with the agent
- deferredTask: Optional task to execute when agent becomes OPERATIONAL
func (*AgentRegistry) MsgHandler ¶
func (ar *AgentRegistry) MsgHandler(ampp *AgentMsgPostPlus, synchedDataUpdateQ chan *SynchedDataUpdate, synchedDataCmdQ chan *SynchedDataCmd)
Handler for messages received from other agents
func (*AgentRegistry) RecomputeSharedZonesAndSyncState ¶
func (ar *AgentRegistry) RecomputeSharedZonesAndSyncState(agent *Agent)
RecomputeSharedZonesAndSyncState updates an agent's shared zones and transitions between OPERATIONAL and LEGACY states based on zone count. This should be called after HSYNC changes to keep agent state synchronized with zone membership.
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) StartInfraBeatLoop ¶
func (ar *AgentRegistry) StartInfraBeatLoop(ctx context.Context)
StartInfraBeatLoop sends periodic beats from the agent to infrastructure peers (combiner and signer). Runs at a lower frequency than the agent↔agent beat loop (default 10 minutes, vs 15–1800s for agent peers).
Combiner and signer are excluded from SendHeartbeats() via IsInfraPeer=true. This loop handles them exclusively.
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 HSYNC3 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 ¶
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 AgentStateLegacy // Established relationship but no shared zones (previously OPERATIONAL) 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 (*ApiClient) RequestNGWithContext ¶
func (*ApiClient) SendPing ¶
func (api *ApiClient) SendPing(pingcount int, dieOnError bool) (PingResponse, error)
func (*ApiClient) StartDaemon ¶
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. daemonFlags are additional command-line flags to pass to the daemon (e.g., --config, --debug, -v)
func (*ApiClient) StopDaemon ¶
func (api *ApiClient) StopDaemon()
func (*ApiClient) UpdateDaemon ¶
func (api *ApiClient) UpdateDaemon(data CommandPost, dieOnError bool) (int, CommandResponse, error)
func (*ApiClient) UrlReportNG ¶
type ApiServerAppConf ¶
type ApiServerAppConf struct {
Addresses []string
ApiKey SensitiveString
}
type ApiServerConf ¶
type ApiServerConf struct {
Addresses []string `validate:"required"` // Must be in addr:port format
ApiKey SensitiveString `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 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 AppTypeMPSigner // MP signer (tdns-mp): DNS infra from tdns, MP wiring from tdns-mp AppTypeMPAgent // MP agent (tdns-mp): DNS infra from tdns, MP wiring from tdns-mp AppTypeMPCombiner // MP combiner (tdns-mp): DNS infra from tdns, MP wiring from tdns-mp )
type ApprovedEditRecord ¶
type ApprovedEditRecord struct {
EditID int `json:"edit_id"`
Zone string `json:"zone"`
SenderID string `json:"sender_id"`
DistributionID string `json:"distribution_id"`
Records map[string][]string `json:"records"`
ReceivedAt time.Time `json:"received_at"`
ApprovedAt time.Time `json:"approved_at"`
}
ApprovedEditRecord represents a row in the CombinerApprovedEdits table.
type AuditResponseMsg ¶
type AuditResponseMsg struct {
SenderID string
Zone string
AuditData interface{} // Zone data repo snapshot (placeholder)
}
AuditResponseMsg carries audit data from a peer agent back to the requester. Delivered via MsgQs.AuditResponse channel.
func RequestAndWaitForAudit ¶
func RequestAndWaitForAudit(ar *AgentRegistry, agent *Agent, zone string) *AuditResponseMsg
RequestAndWaitForAudit sends an RFI AUDIT to a peer agent and waits for the audit response on MsgQs.AuditResponse. Returns the audit data or nil on timeout/error.
type AuthDistribPost ¶
type AuthDistribPost struct {
Command string `json:"command"`
}
AuthDistribPost is the request body for /auth/distrib.
type AuthOption ¶
type AuthOption uint8
const ( AuthOptParentUpdate AuthOption = iota + 1 AuthOptPersistOutboundSerial )
type AuthPeerPost ¶
type AuthPeerPost struct {
Command string `json:"command"`
PeerID string `json:"peer_id,omitempty"` // Target peer for ping (default: configured agent)
}
AuthPeerPost is the request body for /auth/peer.
type AuthPeerResponse ¶
type AuthPeerResponse struct {
Time time.Time `json:"time"`
Error bool `json:"error"`
ErrorMsg string `json:"error_msg,omitempty"`
Msg string `json:"msg,omitempty"`
}
AuthPeerResponse is the response body for /auth/peer.
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 BumperData ¶
type BumperData struct {
Zone string
Result chan BumperResponse
}
type BumperResponse ¶
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 ChunkPayloadStore ¶
type ChunkPayloadStore interface {
Get(qname string) (payload []byte, format uint8, ok bool)
Set(qname string, payload []byte, format uint8)
GetChunk(qname string, sequence uint16) (chunk *core.CHUNK, ok bool)
SetChunks(qname string, chunks []*core.CHUNK)
}
ChunkPayloadStore stores payloads keyed by NOTIFY qname for query-mode CHUNK. Agent: Set before sending NOTIFY; CHUNK query handler Get() returns payload. Entries expire after TTL to avoid unbounded growth. Format is stored alongside payload (FormatJSON=1, FormatJWT=2).
type CombinerDebugPost ¶
type CombinerDebugResponse ¶
type CombinerDebugResponse struct {
Time time.Time `json:"time"`
Error bool `json:"error"`
ErrorMsg string `json:"error_msg,omitempty"`
Msg string `json:"msg,omitempty"`
CombinerData map[string]map[string]map[string][]string `json:"combiner_data,omitempty"` // zone → owner → rrtype → []rr
AgentContributions map[string]map[string]map[string]map[string][]string `json:"agent_contributions,omitempty"` // zone → agent → owner → rrtype → []rr
}
CombinerDebugResponse returns both the merged CombinerData and the per-agent AgentContributions breakdown.
type CombinerDistribPost ¶
type CombinerDistribPost struct {
Command string `json:"command"` // "list", "purge"
Force bool `json:"force,omitempty"`
}
CombinerDistribPost represents a request to the combiner distrib API
type CombinerDistribResponse ¶
type CombinerDistribResponse struct {
Time time.Time `json:"time"`
Error bool `json:"error,omitempty"`
ErrorMsg string `json:"error_msg,omitempty"`
Msg string `json:"msg,omitempty"`
Summaries []*DistributionSummary `json:"summaries,omitempty"`
Distributions []string `json:"distributions,omitempty"` // For backward compatibility
}
CombinerDistribResponse represents a response from the combiner distrib API
type CombinerEditPost ¶
type CombinerEditPost struct {
Command string `json:"command"` // "list", "list-approved", "list-rejected", "approve", "reject", "clear"
Zone string `json:"zone"`
EditID int `json:"edit_id,omitempty"`
Reason string `json:"reason,omitempty"`
Tables []string `json:"tables,omitempty"` // for "clear": which tables to clear; empty = all
}
CombinerEditPost represents a CLI request for managing pending/rejected edits.
type CombinerEditResponse ¶
type CombinerEditResponse struct {
Time time.Time `json:"time"`
Error bool `json:"error"`
ErrorMsg string `json:"error_msg,omitempty"`
Msg string `json:"msg,omitempty"`
Pending []*PendingEditRecord `json:"pending,omitempty"`
Approved []*ApprovedEditRecord `json:"approved,omitempty"`
Rejected []*RejectedEditRecord `json:"rejected,omitempty"`
Current map[string]map[string][]string `json:"current,omitempty"` // agent → rrtype → []rr
}
CombinerEditResponse is the response for edit management commands.
type CombinerOption ¶
type CombinerOption uint8
const (
CombinerOptAddSignature CombinerOption = iota + 1
)
type CombinerPost ¶
type CombinerResponse ¶
type CombinerState ¶
type CombinerState struct {
// ErrorJournal records errors during CHUNK NOTIFY processing for operational diagnostics.
// Queried via "transaction errors" CLI commands. If nil, errors are only logged.
ErrorJournal *ErrorJournal
// ProtectedNamespaces: domain suffixes belonging to this provider.
// NS records from remote agents whose targets fall within these namespaces are rejected.
ProtectedNamespaces []string
// contains filtered or unexported fields
}
CombinerState holds combiner-specific state that outlives individual CHUNK messages. Used by CLI commands (error journal queries) and in-process SendToCombiner. Transport routing is handled by the unified ChunkNotifyHandler.
func RegisterCombinerChunkHandler ¶
func RegisterCombinerChunkHandler(localID string, secureWrapper *transport.SecurePayloadWrapper) (*CombinerState, error)
RegisterCombinerChunkHandler registers the combiner's CHUNK handler using ChunkNotifyHandler. Creates a ChunkNotifyHandler with combiner-appropriate settings and registers it as a NotifyHandlerFunc. Returns CombinerState for error journal access and in-process updates.
func RegisterSignerChunkHandler ¶
func RegisterSignerChunkHandler(localID string, secureWrapper *transport.SecurePayloadWrapper) (*CombinerState, error)
RegisterSignerChunkHandler registers a CHUNK NOTIFY handler for the signer (tdns-auth). Uses ChunkNotifyHandler — the signer only routes messages through the signer router which handles ping and KEYSTATE.
func (*CombinerState) ChunkHandler ¶
func (cs *CombinerState) ChunkHandler() *transport.ChunkNotifyHandler
ChunkHandler returns the underlying ChunkNotifyHandler for wiring into TransportManager.
func (*CombinerState) ProcessUpdate ¶
func (cs *CombinerState) ProcessUpdate(req *CombinerSyncRequest, localAgents map[string]bool, kdb *KeyDB, tm *MPTransportBridge) *CombinerSyncResponse
ProcessUpdate delegates to the standalone CombinerProcessUpdate.
func (*CombinerState) SetGetPeerAddress ¶
func (cs *CombinerState) SetGetPeerAddress(fn func(senderID string) (address string, ok bool))
SetGetPeerAddress sets the GetPeerAddress callback on the underlying ChunkNotifyHandler.
func (*CombinerState) SetRouter ¶
func (cs *CombinerState) SetRouter(router *transport.DNSMessageRouter)
SetRouter sets the router on the underlying ChunkNotifyHandler. Called from main_initfuncs.go after the router is initialized.
func (*CombinerState) SetSecureWrapper ¶
func (cs *CombinerState) SetSecureWrapper(sw *transport.SecurePayloadWrapper)
SetSecureWrapper sets the secure wrapper on the underlying ChunkNotifyHandler.
type CombinerSyncRequest ¶
type CombinerSyncRequest struct {
SenderID string // Identity of the sending agent
DeliveredBy string // Identity of the agent that delivered this to the combiner
Zone string // Zone being updated
ZoneClass string // "mp" (default) or "provider"
SyncType string // Type of sync: "NS", "DNSKEY", "CDS", "CSYNC", "GLUE"
Records map[string][]string // RR strings grouped by owner name (same as CombinerPost.Data)
Operations []core.RROperation // Explicit operations (takes precedence over Records)
Publish *core.PublishInstruction // KEY/CDS publication instruction
Serial uint32 // Zone serial (optional)
DistributionID string // Distribution ID for tracking
Timestamp time.Time // When the request was created
}
CombinerSyncRequest represents a sync request to the combiner. Uses the same data structure as CombinerPost.Data for transport neutrality.
func ConvertZoneUpdateToSyncRequest ¶
func ConvertZoneUpdateToSyncRequest(update *ZoneUpdate, senderID string, distributionID string) *CombinerSyncRequest
ConvertZoneUpdateToSyncRequest converts a ZoneUpdate to a CombinerSyncRequest. Groups records by owner for transport neutrality (same structure as CombinerPost).
func ParseAgentMsgNotify ¶
func ParseAgentMsgNotify(data []byte, distributionID string) (*CombinerSyncRequest, error)
ParseAgentMsgNotify parses a sync payload into a CombinerSyncRequest. Expects the standard AgentMsgPost format (OriginatorID/Zone/Records).
type CombinerSyncRequestPlus ¶
type CombinerSyncRequestPlus struct {
Request *CombinerSyncRequest
Response chan *CombinerSyncResponse
}
CombinerSyncRequestPlus includes a response channel for async processing.
type CombinerSyncResponse ¶
type CombinerSyncResponse struct {
DistributionID string // Echoed from request
Zone string // Zone that was updated
Nonce string // Echoed nonce from the incoming sync/update message
Status string // "ok", "partial", "error"
Message string // Human-readable message
AppliedRecords []string // RRs that were successfully applied (additions)
RemovedRecords []string // RRs that were successfully removed (deletions)
RejectedItems []RejectedItem // Items that were rejected with reasons
Timestamp time.Time // When the response was created
DataChanged bool // True when zone data was actually mutated (not idempotent re-apply)
}
CombinerSyncResponse represents a confirmation from the combiner.
func CombinerProcessUpdate ¶
func CombinerProcessUpdate(req *CombinerSyncRequest, protectedNamespaces []string, localAgents map[string]bool, kdb *KeyDB, tm *MPTransportBridge) *CombinerSyncResponse
func SendToCombiner ¶
func SendToCombiner(state *CombinerState, req *CombinerSyncRequest) *CombinerSyncResponse
SendToCombiner is a helper function that sends a sync request to the combiner and waits for a response. This is called from SynchedDataEngine. For in-process communication, this calls CombinerProcessUpdate directly.
type CommandPost ¶
type CommandResponse ¶
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"`
MultiProvider *MultiProviderConf `yaml:"multi-provider" mapstructure:"multi-provider"`
Catalog *CatalogConf `yaml:"catalog" mapstructure:"catalog"`
DynamicZones DynamicZonesConf `yaml:"dynamiczones" mapstructure:"dynamiczones"`
Zones []ZoneConf `yaml:"zones"`
Templates []ZoneConf `yaml:"templates"`
Kasp KaspConf `yaml:"kasp" mapstructure:"kasp"`
Keys KeyConf
Db DbConf
Registrars map[string][]string
Log LogConf
Internal InternalConf
}
var Conf Config
func LoadConfigForKeys ¶
LoadConfigForKeys reads the given YAML config file and decodes it into Config. Used by tdns-cli agent/combiner keys to get long_term_jose_priv_key path. Does not process includes or run full ParseConfig.
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) APIagentDistrib ¶
func (conf *Config) APIagentDistrib(cache *DistributionCache) func(w http.ResponseWriter, r *http.Request)
func (*Config) APIagentTransaction ¶
func (conf *Config) APIagentTransaction(cache *DistributionCache) func(w http.ResponseWriter, r *http.Request)
APIagentTransaction handles transaction diagnostic requests for agents
func (*Config) APIcombinerDistrib ¶
func (conf *Config) APIcombinerDistrib(cache *DistributionCache) func(w http.ResponseWriter, r *http.Request)
func (*Config) APIcombinerTransaction ¶
func (conf *Config) APIcombinerTransaction() func(w http.ResponseWriter, r *http.Request)
APIcombinerTransaction handles transaction diagnostic requests for combiners
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) APIsyncPing ¶
func (conf *Config) APIsyncPing() func(w http.ResponseWriter, r *http.Request)
APIsyncPing is the HSYNC peer ping handler on the sync API router (/sync/ping). This is separate from the management /ping (APIping in api_utils.go) which returns boot time and version info. This handler echoes the nonce for round-trip verification and routes the ping to MsgQs.Ping for state tracking.
func (*Config) AddDynamicZoneToConfig ¶
AddDynamicZoneToConfig adds or updates a zone in the dynamic config file
func (*Config) CheckDynamicConfigFileIncluded ¶
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 ¶
Extract the addresses we listen on from the dnsengine configuration. Exclude localhost and non-standard ports.
func (*Config) InitializeKeyDB ¶
func (*Config) LoadDynamicZoneFiles ¶
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) LocalIdentity ¶
LocalIdentity returns the local node's identity string, regardless of role. Used by sync API handlers (APIhello, APIbeat, APIsyncPing) so they work on agent, combiner, and signer without referencing conf.Agent.Identity directly.
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 (*Config) ParseZones ¶
func ParseZones(zones map[string]tdns.ZoneConf, zrch chan tdns.ZoneRefresher) error {
func (*Config) ReloadConfig ¶
func (*Config) ReloadZoneConfig ¶
func (*Config) RemoveDynamicZoneFromConfig ¶
RemoveDynamicZoneFromConfig removes a zone from the dynamic config file
func (*Config) SetupAPIRouter ¶
func (*Config) SetupAgent ¶
func (*Config) SetupAgentAutoZone ¶
func (*Config) SetupAgentSyncRouter ¶
This is the agent-to-agent sync API router.
func (*Config) SetupCombinerSyncRouter ¶
SetupCombinerSyncRouter sets up the HTTPS sync API for the combiner role. Agents can send HELLO, BEAT, PING, and MSG to the combiner over this router. Runs on a dedicated port (combiner.api.addresses.listen) separate from the management API, using mutual TLS with client cert verification against AgentRegistry.
func (*Config) SetupSignerSyncRouter ¶
SetupSignerSyncRouter sets up the HTTPS sync API for the signer (tdns-auth) role. Agents can send HELLO, BEAT, PING, and MSG to the signer over this router.
func (*Config) SetupSimpleAPIRouter ¶
The simple API router is sufficient for tdns-imr, tdns-scanner and tdns-reporter.
func (*Config) ShouldPersistZone ¶
ShouldPersistZone checks if a zone should be persisted based on configuration Returns true if the zone should be written to disk
func (*Config) StartAgent ¶
StartAgent starts subsystems for tdns-agent
func (*Config) StartCombiner ¶
StartCombiner starts subsystems for tdns-combiner
func (*Config) StartScanner ¶
StartScanner starts subsystems for tdns-scanner
func (*Config) SynchedDataEngine ¶
SynchedDataEngine is a component that updates the combiner with new information received from the agents that are sharing zones with us.
func (*Config) WriteDynamicConfigFile ¶
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
CombinerOptions map[CombinerOption]bool
Msg string
Error bool
ErrorMsg string
}
type ConfigResponseMsg ¶
type ConfigResponseMsg struct {
SenderID string
Zone string
Subtype string // "upstream", "downstream", "sig0key"
ConfigData map[string]string // Key-value config data
}
ConfigResponseMsg carries config data from a peer agent back to the requester. Delivered via MsgQs.ConfigResponse channel.
func RequestAndWaitForConfig ¶
func RequestAndWaitForConfig(ar *AgentRegistry, agent *Agent, zone string, subtype string) *ConfigResponseMsg
RequestAndWaitForConfig sends an RFI CONFIG to a peer agent and waits for the config response on MsgQs.ConfigResponse. Returns the config data or nil on timeout/error.
type ConfirmationDetail ¶
type ConfirmationDetail struct {
DistributionID string
Zone ZoneName
Source string // Identifies the confirming peer (combiner ID or agent ID)
Status string // "ok", "partial", "error"
Message string
AppliedRecords []string
RemovedRecords []string // RR strings confirmed as removed by combiner
RejectedItems []RejectedItemInfo
Truncated bool
Timestamp time.Time
}
ConfirmationDetail carries per-RR confirmation feedback from the combiner through to the SynchedDataEngine.
type ConfirmationItem ¶
type ConfirmationItem struct {
RecordType string `json:"record_type"`
Zone string `json:"zone"`
Status string `json:"status"`
Details string `json:"details,omitempty"`
}
ConfirmationItem represents a single item in a confirmation.
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)
DS *core.RRset `json:"-"` // Current DS RRset from delegation backend (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"`
DS *core.RRsetString `json:"ds,omitempty"`
CSYNC *core.RRsetString `json:"csync,omitempty"`
DNSKEY *core.RRsetString `json:"dnskey,omitempty"`
}
CurrentScanDataJSON is the JSON-serializable version of CurrentScanData
type CustomValidator ¶
CustomValidator is a struct that embeds the validator.Validate type
func NewCustomValidator ¶
func NewCustomValidator() (*CustomValidator, error)
NewCustomValidator creates a new instance of CustomValidator
type DBDelegationBackend ¶
type DBDelegationBackend struct {
// contains filtered or unexported fields
}
func (*DBDelegationBackend) ApplyChildUpdate ¶
func (b *DBDelegationBackend) ApplyChildUpdate(parentZone string, ur UpdateRequest) error
func (*DBDelegationBackend) GetDelegationData ¶
func (*DBDelegationBackend) ListChildren ¶
func (b *DBDelegationBackend) ListChildren(parentZone string) ([]string, error)
func (*DBDelegationBackend) Name ¶
func (b *DBDelegationBackend) Name() string
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 ¶
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 DelegationBackend ¶
type DelegationBackend interface {
// ApplyChildUpdate processes an approved child UPDATE.
// Actions are ClassINET (add), ClassNONE (delete-RR), ClassANY (delete-RRset).
ApplyChildUpdate(parentZone string, ur UpdateRequest) error
// GetDelegationData returns current delegation RRs for a child zone,
// grouped by owner name and RR type.
GetDelegationData(parentZone, childZone string) (map[string]map[uint16][]dns.RR, error)
// ListChildren returns all child zones with stored delegation data.
ListChildren(parentZone string) ([]string, error)
// Name returns the backend name for logging.
Name() string
}
DelegationBackend is the interface for storing delegation data received from child zones via DNS UPDATE. Implementations persist the data in different ways (in-memory zone, database, zone files, etc.).
func LookupDelegationBackend ¶
func LookupDelegationBackend(name string, kdb *KeyDB, zd *ZoneData) (DelegationBackend, error)
LookupDelegationBackend resolves a backend name to a DelegationBackend.
Predefined names:
- "db" → DBDelegationBackend (uses the zone's existing KeyDB)
- "direct" → DirectDelegationBackend (modifies in-memory zone data)
Any other name is looked up in the "delegation-backends" config list.
type DelegationBackendConf ¶
type DelegationBackendConf struct {
Name string `yaml:"name"`
Type string `yaml:"type"`
Directory string `yaml:"directory"` // zonefile backend
NotifyCommand string `yaml:"notify-command"` // zonefile backend
}
DelegationBackendConf is a named backend definition from the config file. Predefined backends ("db", "direct") need no config entry. Named backends are only needed for types that require parameters (e.g. "zonefile").
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 DelegationResponse ¶
type DelegationSyncRequest ¶
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 `json:"-"`
Removes []dns.RR `json:"-"`
NsAdds []dns.RR `json:"-"`
NsRemoves []dns.RR `json:"-"`
AAdds []dns.RR `json:"-"`
ARemoves []dns.RR `json:"-"`
AAAAAdds []dns.RR `json:"-"`
AAAARemoves []dns.RR `json:"-"`
DNSKEYAdds []dns.RR `json:"-"`
DNSKEYRemoves []dns.RR `json:"-"`
DSAdds []dns.RR `json:"-"`
DSRemoves []dns.RR `json:"-"`
Error bool
ErrorMsg string
UpdateResult UpdateResult // Experimental
// Complete new delegation data for replace mode
NewNS []dns.RR `json:"-"`
NewA []dns.RR `json:"-"`
NewAAAA []dns.RR `json:"-"`
NewDS []dns.RR `json:"-"`
// String representations for JSON serialization (populated by ToStrings())
NsAddsStr []string `json:"NsAdds,omitempty"`
NsRemovesStr []string `json:"NsRemoves,omitempty"`
AAddsStr []string `json:"AAdds,omitempty"`
ARemovesStr []string `json:"ARemoves,omitempty"`
AAAAAddsStr []string `json:"AAAAAdds,omitempty"`
AAAARemovesStr []string `json:"AAAARemoves,omitempty"`
DSAddsStr []string `json:"DSAdds,omitempty"`
DSRemovesStr []string `json:"DSRemoves,omitempty"`
}
func (*DelegationSyncStatus) ToStrings ¶
func (dss *DelegationSyncStatus) ToStrings()
type DirectDelegationBackend ¶
type DirectDelegationBackend struct {
// contains filtered or unexported fields
}
func (*DirectDelegationBackend) ApplyChildUpdate ¶
func (b *DirectDelegationBackend) ApplyChildUpdate(parentZone string, ur UpdateRequest) error
func (*DirectDelegationBackend) GetDelegationData ¶
func (*DirectDelegationBackend) ListChildren ¶
func (b *DirectDelegationBackend) ListChildren(parentZone string) ([]string, error)
func (*DirectDelegationBackend) Name ¶
func (b *DirectDelegationBackend) Name() string
type DistributionCache ¶
type DistributionCache struct {
// contains filtered or unexported fields
}
DistributionCache is an in-memory cache of distributions keyed by QNAME
func NewDistributionCache ¶
func NewDistributionCache() *DistributionCache
NewDistributionCache creates a new distribution cache
func (*DistributionCache) Add ¶
func (dc *DistributionCache) Add(qname string, info *DistributionInfo)
Add adds a distribution to the cache
func (*DistributionCache) Get ¶
func (dc *DistributionCache) Get(qname string) (*DistributionInfo, bool)
Get retrieves a distribution by QNAME
func (*DistributionCache) List ¶
func (dc *DistributionCache) List(senderID string) []*DistributionInfo
List returns all distributions for a given sender
func (*DistributionCache) MarkCompleted ¶
func (dc *DistributionCache) MarkCompleted(qname string)
MarkCompleted marks a distribution as completed
func (*DistributionCache) PurgeAll ¶
func (dc *DistributionCache) PurgeAll() int
PurgeAll removes all distributions
func (*DistributionCache) PurgeCompleted ¶
func (dc *DistributionCache) PurgeCompleted(olderThan time.Duration) int
PurgeCompleted removes completed distributions older than the given duration. Incomplete distributions (CompletedAt == nil) are never purged; only explicit "purge --force" removes them.
func (*DistributionCache) PurgeExpired ¶
func (dc *DistributionCache) PurgeExpired() int
PurgeExpired removes distributions that have passed their ExpiresAt time. This implements fast expiration for beat/ping messages to reduce clutter. Returns the number of distributions removed.
func (*DistributionCache) StartCleanupGoroutine ¶
func (dc *DistributionCache) StartCleanupGoroutine(ctx context.Context)
StartCleanupGoroutine starts a background goroutine that periodically removes expired distributions. The cleanup runs every minute to keep the distribution list clean without excessive overhead.
type DistributionInfo ¶
type DistributionInfo struct {
DistributionID string
SenderID string
ReceiverID string
Operation string
ContentType string
State string
PayloadSize int // Size of the final payload in bytes (after encryption, before chunking)
CreatedAt time.Time
CompletedAt *time.Time
ExpiresAt *time.Time // When this distribution should be cleaned up (nil = no expiration)
QNAME string // The DNS QNAME used to retrieve this distribution
}
DistributionInfo holds information about a distribution
type DistributionSummary ¶
type DistributionSummary struct {
DistributionID string `json:"distribution_id"`
SenderID string `json:"sender_id"`
ReceiverID string `json:"receiver_id"`
Operation string `json:"operation"`
ContentType string `json:"content_type"`
State string `json:"state"`
PayloadSize int `json:"payload_size"`
CreatedAt string `json:"created_at"`
CompletedAt string `json:"completed_at,omitempty"`
}
DistributionSummary contains summary information about a distribution
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
}
type DnskeyStatus ¶
type DnskeyStatus struct {
Time time.Time
ZoneName string
LocalAdds []dns.RR // Local DNSKEYs added since last check
LocalRemoves []dns.RR // Local DNSKEYs removed since last check
CurrentLocalKeys []dns.RR // Complete current set of local DNSKEYs (for replace operations)
}
DnskeyStatus holds the result of DNSKEY change detection (local keys only).
type DnssecKey ¶
type DnssecKey struct {
Name string
State string
Keyid uint16
Flags uint16
Algorithm string
Creator string
PrivateKey string //
Key dns.DNSKEY
Keystr string
PropagationConfirmed bool // True when all remote providers confirmed this key
PropagationConfirmedAt time.Time // When propagation was confirmed (zero if not confirmed)
}
type DnssecKeyWithTimestamps ¶
type DnssecKeyWithTimestamps struct {
ZoneName string
KeyTag uint16
Algorithm uint8
Flags uint16
State string
KeyRR string
PublishedAt *time.Time
RetiredAt *time.Time
}
DnssecKeyWithTimestamps extends KeyInventoryItem with lifecycle timestamps. Used by the KeyStateWorker for time-based state transitions.
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 DsyncSchemeInfo ¶
type DsyncSchemeInfo struct {
Scheme string `json:"scheme"` // "UPDATE", "NOTIFY", etc.
Type string `json:"type"` // "CDS", "CSYNC", "ANY", etc.
Target string `json:"target"` // target host
Port uint16 `json:"port"`
}
DsyncSchemeInfo describes a parent DSYNC sync scheme.
type DsyncTarget ¶
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 EditsResponseMsg ¶
type EditsResponseMsg struct {
SenderID string
Zone string
AgentRecords map[string]map[string][]string // agentID → owner → []RR strings
}
EditsResponseMsg carries an agent's contributions from combiner back to the agent. Delivered via MsgQs.EditsResponse channel. Modeled on KeystateInventoryMsg.
type EngineFunc ¶
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 ErrorJournal ¶
type ErrorJournal struct {
// contains filtered or unexported fields
}
ErrorJournal is a bounded, time-windowed in-memory ring buffer of errors. Thread-safe. No persistence — this is for operational debugging.
func NewErrorJournal ¶
func NewErrorJournal(maxCount int, maxAge time.Duration) *ErrorJournal
NewErrorJournal creates a new error journal with the given retention limits.
func (*ErrorJournal) ListSince ¶
func (ej *ErrorJournal) ListSince(duration time.Duration) []ErrorJournalEntry
ListSince returns all errors within the given duration from now.
func (*ErrorJournal) LookupByDistID ¶
func (ej *ErrorJournal) LookupByDistID(distID string) (*ErrorJournalEntry, bool)
LookupByDistID returns the error entry for a specific distribution ID, if any.
func (*ErrorJournal) Record ¶
func (ej *ErrorJournal) Record(entry ErrorJournalEntry)
Record adds a new error entry to the journal, evicting old entries as needed.
type ErrorJournalEntry ¶
type ErrorJournalEntry struct {
DistributionID string `json:"distribution_id"`
Sender string `json:"sender"` // Sender identity (extracted from QNAME control zone)
MessageType string `json:"message_type"` // "ping", "beat", "sync", "update", or "unknown"
ErrorMsg string `json:"error_msg"`
QNAME string `json:"qname"` // Original NOTIFY qname
Timestamp time.Time `json:"timestamp"`
}
ErrorJournalEntry records a single error that occurred during CHUNK NOTIFY processing.
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 GossipMessage ¶
type GossipMessage struct {
GroupHash string `json:"group_hash"`
GroupName GroupNameProposal `json:"group_name"`
Members map[string]*MemberState `json:"members"` // key: provider identity
Election GroupElectionState `json:"election"`
}
GossipMessage carries gossip state for one provider group. Included in beats between agents that share group membership.
type GossipStateTable ¶
type GossipStateTable struct {
// key: group hash → member identity → MemberState
States map[string]map[string]*MemberState
// key: group hash → GroupElectionState
Elections map[string]*GroupElectionState
// key: group hash → GroupNameProposal (best proposal seen)
Names map[string]*GroupNameProposal
// Our identity
LocalID string
// contains filtered or unexported fields
}
GossipStateTable manages the NxN state matrix for all provider groups. Each entry is a MemberState keyed by (groupHash, memberIdentity).
func NewGossipStateTable ¶
func NewGossipStateTable(localID string) *GossipStateTable
NewGossipStateTable creates a new gossip state table.
func (*GossipStateTable) BuildGossipForPeer ¶
func (gst *GossipStateTable) BuildGossipForPeer(peerID string, pgm *ProviderGroupManager, lem ...*LeaderElectionManager) []GossipMessage
BuildGossipForPeer builds gossip messages for all groups shared with a peer. If a LeaderElectionManager is provided, group election state is included.
func (*GossipStateTable) CheckGroupState ¶
func (gst *GossipStateTable) CheckGroupState(groupHash string, expectedMembers []string)
CheckGroupState checks if all cells in the NxN matrix for a group are OPERATIONAL. Fires OnGroupOperational when the group first reaches full agreement. Fires OnGroupDegraded when a previously operational group loses agreement.
func (*GossipStateTable) GetGroupState ¶
func (gst *GossipStateTable) GetGroupState(groupHash string) (map[string]*MemberState, *GroupElectionState, *GroupNameProposal)
GetGroupState returns a deep copy of the state matrix for a group.
func (*GossipStateTable) MergeGossip ¶
func (gst *GossipStateTable) MergeGossip(msg *GossipMessage)
MergeGossip merges received gossip into the local state table. For each member's state entry, keep the one with the latest timestamp. The member's PeerStates map is replaced atomically (never cherry-pick individual peer entries from different timestamps).
func (*GossipStateTable) RefreshLocalStates ¶
func (gst *GossipStateTable) RefreshLocalStates(ar *AgentRegistry, pgm *ProviderGroupManager)
RefreshLocalStates updates our local state entries for all groups based on current agent registry state.
func (*GossipStateTable) SetOnElectionUpdate ¶
func (gst *GossipStateTable) SetOnElectionUpdate(fn func(groupHash string, state GroupElectionState))
func (*GossipStateTable) SetOnGroupDegraded ¶
func (gst *GossipStateTable) SetOnGroupDegraded(fn func(groupHash string))
func (*GossipStateTable) SetOnGroupOperational ¶
func (gst *GossipStateTable) SetOnGroupOperational(fn func(groupHash string))
func (*GossipStateTable) UpdateLocalState ¶
func (gst *GossipStateTable) UpdateLocalState(groupHash string, peerStates map[string]string, zones []string)
UpdateLocalState updates our own state entry for a group. This sets the Timestamp to now — only we update our own state.
type GroupElectionState ¶
type GroupElectionState struct {
Leader string `json:"leader,omitempty"` // identity of current leader
Term uint32 `json:"term,omitempty"`
LeaderExpiry time.Time `json:"leader_expiry,omitempty"`
}
GroupElectionState carries election state for a provider group.
type GroupNameProposal ¶
type GroupNameProposal struct {
GroupHash string `json:"group_hash"`
Name string `json:"name"`
Proposer string `json:"proposer"` // provider identity that chose the name
ProposedAt time.Time `json:"proposed_at"` // when the name was chosen
}
GroupNameProposal is a name proposed by a provider for a group.
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 HsyncConfirmationInfo ¶
type HsyncConfirmationInfo struct {
DistributionID string `json:"distribution_id"`
ConfirmerID string `json:"confirmer_id"`
Status string `json:"status"`
Message string `json:"message,omitempty"`
ConfirmedAt time.Time `json:"confirmed_at"`
ReceivedAt time.Time `json:"received_at"`
}
HsyncConfirmationInfo contains confirmation information for CLI display
func ConfirmRecordToInfo ¶
func ConfirmRecordToInfo(conf *SyncConfirmationRecord) *HsyncConfirmationInfo
ConfirmRecordToInfo converts a SyncConfirmationRecord to HsyncConfirmationInfo for CLI display.
type HsyncMetricsInfo ¶
type HsyncMetricsInfo struct {
SyncsSent int64 `json:"syncs_sent"`
SyncsReceived int64 `json:"syncs_received"`
SyncsConfirmed int64 `json:"syncs_confirmed"`
SyncsFailed int64 `json:"syncs_failed"`
BeatsSent int64 `json:"beats_sent"`
BeatsReceived int64 `json:"beats_received"`
BeatsMissed int64 `json:"beats_missed"`
AvgLatency int64 `json:"avg_latency"`
MaxLatency int64 `json:"max_latency"`
APIOperations int64 `json:"api_operations"`
DNSOperations int64 `json:"dns_operations"`
}
HsyncMetricsInfo contains aggregated metrics for CLI display
type HsyncPeerInfo ¶
type HsyncPeerInfo struct {
PeerID string `json:"peer_id"`
State string `json:"state"`
StateReason string `json:"state_reason,omitempty"`
DiscoverySource string `json:"discovery_source,omitempty"`
DiscoveryTime time.Time `json:"discovery_time,omitempty"`
PreferredTransport string `json:"preferred_transport"`
APIHost string `json:"api_host,omitempty"`
APIPort int `json:"api_port,omitempty"`
APIAvailable bool `json:"api_available"`
DNSHost string `json:"dns_host,omitempty"`
DNSPort int `json:"dns_port,omitempty"`
DNSAvailable bool `json:"dns_available"`
LastContactAt time.Time `json:"last_contact_at,omitempty"`
LastHelloAt time.Time `json:"last_hello_at,omitempty"`
LastBeatAt time.Time `json:"last_beat_at,omitempty"`
BeatInterval int `json:"beat_interval"`
BeatsSent int64 `json:"beats_sent"`
BeatsReceived int64 `json:"beats_received"`
FailedContacts int `json:"failed_contacts"`
}
HsyncPeerInfo contains peer information for CLI display
func PeerRecordToInfo ¶
func PeerRecordToInfo(peer *PeerRecord) *HsyncPeerInfo
PeerRecordToInfo converts a PeerRecord to HsyncPeerInfo for CLI display.
type HsyncStatus ¶
type HsyncSyncOpInfo ¶
type HsyncSyncOpInfo struct {
DistributionID string `json:"distribution_id"`
ZoneName string `json:"zone_name"`
SyncType string `json:"sync_type"`
Direction string `json:"direction"`
SenderID string `json:"sender_id"`
ReceiverID string `json:"receiver_id"`
Status string `json:"status"`
StatusMessage string `json:"status_message,omitempty"`
Transport string `json:"transport,omitempty"`
CreatedAt time.Time `json:"created_at"`
SentAt time.Time `json:"sent_at,omitempty"`
ReceivedAt time.Time `json:"received_at,omitempty"`
ConfirmedAt time.Time `json:"confirmed_at,omitempty"`
RetryCount int `json:"retry_count"`
}
HsyncSyncOpInfo contains sync operation information for CLI display
func SyncOpRecordToInfo ¶
func SyncOpRecordToInfo(op *SyncOperationRecord) *HsyncSyncOpInfo
SyncOpRecordToInfo converts a SyncOperationRecord to HsyncSyncOpInfo for CLI display.
type HsyncTransportEvent ¶
type HsyncTransportEvent struct {
EventTime time.Time `json:"event_time"`
PeerID string `json:"peer_id,omitempty"`
ZoneName string `json:"zone_name,omitempty"`
EventType string `json:"event_type"`
Transport string `json:"transport,omitempty"`
Direction string `json:"direction,omitempty"`
Success bool `json:"success"`
ErrorCode string `json:"error_code,omitempty"`
ErrorMessage string `json:"error_message,omitempty"`
}
HsyncTransportEvent contains transport event information for CLI display
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)
DebugLog *log.Logger // non-nil when imr debug logging is enabled
// RequireDnssecValidation: when true, security-sensitive lookups (TLSA, etc.) require
// a secure DNSSEC validation state. Default true; set false in lab environments where
// the full DNSSEC chain is not yet established.
RequireDnssecValidation bool
}
func (*Imr) AuthDNSQuery ¶
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) DefaultRRsetFetcher ¶
func (*Imr) DsyncDiscovery ¶
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) 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) ParseAdditionalForNSAddrs ¶
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) StartImrEngineListeners ¶
func (*Imr) TransportSignalCached ¶
func (*Imr) TransportSignalRRType ¶
type ImrClientQueryHookFunc ¶
type ImrClientQueryHookFunc func(ctx context.Context, w dns.ResponseWriter, r *dns.Msg, qname string, qtype uint16, msgoptions *edns0.MsgOptions) (context.Context, *dns.Msg)
ImrClientQueryHookFunc is called when an external client query arrives at the IMR listener. Return nil ctx to keep the original context, or a new context to enrich it (e.g. to carry a parent query ID through the resolution chain). Return nil *dns.Msg to proceed with normal resolution. Return a non-nil *dns.Msg to short-circuit: the msg is sent as the response and resolution is skipped.
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
Logging ImrLoggingConf `yaml:"logging" mapstructure:"logging"`
// RequireDnssecValidation: when true (default), TLSA and other security-sensitive
// records must have a secure DNSSEC validation state. Set to false to allow
// indeterminate/insecure records during lab/development when the full DNSSEC
// chain is not yet established.
RequireDnssecValidation *bool `yaml:"require_dnssec_validation" mapstructure:"require_dnssec_validation"`
}
type ImrLoggingConf ¶
type ImrOutboundQueryHookFunc ¶
type ImrOutboundQueryHookFunc func(ctx context.Context, qname string, qtype uint16, serverName string, serverAddr string, transport core.Transport) error
ImrOutboundQueryHookFunc is called before the IMR sends an iterative query to an authoritative server. Return nil to proceed with the query. Return a non-nil error to skip this server (behaves as if the server didn't respond).
type ImrRequest ¶
type ImrRequest struct {
Qname string
Qtype uint16
Qclass uint16
ResponseCh chan ImrResponse
}
type ImrResponse ¶
type ImrResponseHookFunc ¶
type ImrResponseHookFunc func(ctx context.Context, qname string, qtype uint16, serverName string, serverAddr string, transport core.Transport, response *dns.Msg, rcode int)
ImrResponseHookFunc is called after the IMR receives a response from an authoritative server. Observe-only — return value is ignored.
type ImrStubConf ¶
type ImrStubConf struct {
Zone string `validate:"required"`
// Servers []StubServerConf `validate:"required"`
Servers []cache.AuthServer `validate:"required"`
}
type InternalConf ¶
type InternalConf struct {
InternalDnsConf
InternalMpConf
}
InternalConf embeds both DNS and MP internal configuration. Field promotion means all existing access sites continue to work unchanged.
type InternalDnsConf ¶
type InternalDnsConf 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
RRsetCache *cache.RRsetCacheT // ConcurrentMap of cached RRsets from queries
ImrEngine *Imr
Scanner *Scanner // Scanner instance for async job tracking
}
InternalDnsConf holds DNS-specific internal state: channels, handlers, caches, and engine references. Stays in tdns after repo split.
type InternalMpConf ¶
type InternalMpConf struct {
SyncQ chan SyncRequest
MsgQs *MsgQs // aggregated channels for agent communication
SyncStatusQ chan SyncStatus
AgentRegistry *AgentRegistry
ZoneDataRepo *ZoneDataRepo
CombinerState *CombinerState // Combiner business logic state (error journal, protected namespaces)
TransportManager *transport.TransportManager // Generic transport (Router, PeerRegistry, DNS/API transports, RMQ)
MPTransport *MPTransportBridge // MP-specific transport bridge (authorization, discovery, enqueue, DNSKEY tracking)
LeaderElectionManager *LeaderElectionManager // Per-zone leader election for delegation sync; nil if not agent
ChunkPayloadStore ChunkPayloadStore // Optional: for query-mode CHUNK (agent); keyed by qname; set when agent chunk_mode is "query"
MPZoneNames []string // Zone names with OptMultiProvider, collected at parse time for SDE hydration
DistributionCache *DistributionCache // In-memory cache of distributions (agent/combiner)
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
}
InternalMpConf holds multi-provider internal state: transport, agent registry, combiner state, message channels. Moves to tdns-mp after repo split.
type KaspConf ¶
type KaspConf struct {
// PropagationDelay is how long to wait for DNSKEY RRsets to propagate
// through all caches before allowing state transitions.
// Used for published→standby and retired→removed transitions.
// Accepts Go duration strings: "1h", "3600s", "90m".
// Default: "1h".
PropagationDelay string `yaml:"propagation_delay" mapstructure:"propagation_delay"`
// StandbyZskCount is the number of standby ZSKs to maintain per zone.
// When the count drops below this, the KeyStateWorker generates new ZSKs.
// Default: 1. A value of 0 (or omitted) means use the default.
StandbyZskCount int `yaml:"standby_zsk_count" mapstructure:"standby_zsk_count"`
// StandbyKskCount is the number of standby KSKs to maintain per zone.
// When the count drops below this, the KeyStateWorker generates new KSKs.
// Default: 0 (no standby KSKs). Set to 1+ to enable standby KSK maintenance.
StandbyKskCount int `yaml:"standby_ksk_count" mapstructure:"standby_ksk_count"`
// CheckInterval is how often the KeyStateWorker runs its checks.
// Accepts Go duration strings: "1m", "60s", "5m".
// Default: "1m".
CheckInterval string `yaml:"check_interval" mapstructure:"check_interval"`
}
KaspConf holds Key and Signing Policy parameters for the signer. Controls the KeyStateWorker's automatic key state transitions and standby key maintenance. YAML key: "kasp:"
Example:
kasp:
propagation_delay: 1h
standby_zsk_count: 1
standby_ksk_count: 0
check_interval: 1m
type KeyBootstrapperRequest ¶
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 ¶
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 (*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) ApprovePendingEdit ¶
func (kdb *KeyDB) ApprovePendingEdit(editID int) (*PendingEditRecord, error)
ApprovePendingEdit moves a pending edit to the approved table. Returns the original pending edit data for processing.
func (*KeyDB) CleanupExpiredHsyncData ¶
CleanupExpiredData removes expired data from HSYNC tables. Should be called periodically (e.g., daily).
func (*KeyDB) ClearApprovedEdits ¶
ClearApprovedEdits deletes rows from CombinerApprovedEdits. If zone is empty, all rows are deleted; otherwise only rows for that zone.
func (*KeyDB) ClearContributions ¶
ClearContributions deletes rows from CombinerContributions. If zone is empty, all rows are deleted; otherwise only rows for that zone.
func (*KeyDB) ClearPendingEdits ¶
ClearPendingEdits deletes rows from CombinerPendingEdits. If zone is empty, all rows are deleted; otherwise only rows for that zone.
func (*KeyDB) ClearRejectedEdits ¶
ClearRejectedEdits deletes rows from CombinerRejectedEdits. If zone is empty, all rows are deleted; otherwise only rows for that zone.
func (*KeyDB) CreateAutoZone ¶
func (*KeyDB) DeferredUpdaterEngine ¶
func (*KeyDB) DelegationSyncher ¶
func (kdb *KeyDB) DelegationSyncher(ctx context.Context, delsyncq chan DelegationSyncRequest, notifyq chan NotifyRequest, conf *Config) error
func (*KeyDB) DeleteContributions ¶
DeleteContributions removes all rows for a specific agent/zone pair.
func (*KeyDB) DeletePublishInstruction ¶
DeletePublishInstruction removes the stored instruction for (zone, senderID).
func (*KeyDB) DnssecKeyMgmt ¶
func (kdb *KeyDB) DnssecKeyMgmt(tx *Tx, kp KeystorePost) (*KeystoreResponse, error)
func (*KeyDB) GenerateAndStageKey ¶
func (kdb *KeyDB) GenerateAndStageKey(zone, creator string, alg uint8, keytype string, isMultiProvider bool) (uint16, error)
GenerateAndStageKey generates a new DNSSEC key and stages it for the key pipeline. For multi-provider zones (isMultiProvider=true): created → mpdist (awaits remote confirmation) For normal zones: created → published (sets published_at, enters time-based pipeline)
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) GetAggregatedMetrics ¶
func (kdb *KeyDB) GetAggregatedMetrics() (*HsyncMetricsInfo, error)
GetAggregatedMetrics retrieves aggregated operational metrics.
func (*KeyDB) GetDnssecKeyPropagation ¶
GetDnssecKeyPropagation returns the propagation state for a specific key. Returns (confirmed bool, confirmedAt time.Time, err error).
func (*KeyDB) GetDnssecKeys ¶
func (kdb *KeyDB) GetDnssecKeys(zonename, state string) (*DnssecKeys, error)
func (*KeyDB) GetDnssecKeysByState ¶
func (kdb *KeyDB) GetDnssecKeysByState(zone string, state string) ([]DnssecKeyWithTimestamps, error)
GetDnssecKeysByState returns all DNSSEC keys in a given state, with lifecycle timestamps. If zone is empty, returns keys across all zones.
func (*KeyDB) GetKeyInventory ¶
func (kdb *KeyDB) GetKeyInventory(zonename string) ([]KeyInventoryItem, error)
GetKeyInventory returns the complete DNSKEY inventory for a zone — all keys across all states. Used by the signer to respond to RFI KEYSTATE requests. Returns lightweight entries (keytag, algorithm, flags, state, keyrr) without private keys.
func (*KeyDB) GetKeyStatus ¶
func (*KeyDB) GetPeer ¶
func (kdb *KeyDB) GetPeer(peerID string) (*PeerRecord, error)
GetPeer retrieves a peer by ID.
func (*KeyDB) GetPendingEdit ¶
func (kdb *KeyDB) GetPendingEdit(editID int) (*PendingEditRecord, error)
GetPendingEdit retrieves a single pending edit by edit_id.
func (*KeyDB) GetPublishInstruction ¶
func (kdb *KeyDB) GetPublishInstruction(zone, senderID string) (*StoredPublishInstruction, error)
GetPublishInstruction returns the stored instruction for (zone, senderID), or nil.
func (*KeyDB) GetSig0KeyRaw ¶
func (kdb *KeyDB) GetSig0KeyRaw(zonename, state string) (algorithm, privatekey, keyrr string, found bool, err error)
GetSig0KeyRaw returns the raw database column values for a SIG(0) key. Used for transferring key material between agents via RFI CONFIG.
func (*KeyDB) GetSig0Keys ¶
func (kdb *KeyDB) GetSig0Keys(zonename, state string) (*Sig0ActiveKeys, error)
func (*KeyDB) GetSyncOperation ¶
func (kdb *KeyDB) GetSyncOperation(distributionID string) (*SyncOperationRecord, error)
GetSyncOperation retrieves a sync operation by distribution ID.
func (*KeyDB) HandleKeyStateOption ¶
func (*KeyDB) IncrementPeerFailedContacts ¶
IncrementPeerFailedContacts increments the failed contacts counter.
func (*KeyDB) InitCombinerEditTables ¶
InitCombinerEditTables initializes only the combiner edit tables. Call this on combiner startup — avoids creating agent-only HSYNC tables.
func (*KeyDB) InitHsyncTables ¶
InitHsyncTables initializes the HSYNC tables in the KeyDB. Call this during application startup after KeyDB is created.
func (*KeyDB) ListApprovedEdits ¶
func (kdb *KeyDB) ListApprovedEdits(zone string) ([]*ApprovedEditRecord, error)
ListApprovedEdits returns all approved edits, optionally filtered by zone. If zone is empty, returns all approved edits across all zones.
func (*KeyDB) ListPeers ¶
func (kdb *KeyDB) ListPeers(state string) ([]*PeerRecord, error)
ListPeers retrieves all peers, optionally filtered by state.
func (*KeyDB) ListPendingEdits ¶
func (kdb *KeyDB) ListPendingEdits(zone string) ([]*PendingEditRecord, error)
ListPendingEdits returns all pending edits for a zone.
func (*KeyDB) ListRejectedEdits ¶
func (kdb *KeyDB) ListRejectedEdits(zone string) ([]*RejectedEditRecord, error)
ListRejectedEdits returns all rejected edits for a zone.
func (*KeyDB) ListSyncConfirmations ¶
func (kdb *KeyDB) ListSyncConfirmations(distributionID string, limit int) ([]*SyncConfirmationRecord, error)
ListSyncConfirmations retrieves confirmations, optionally filtered by distribution ID.
func (*KeyDB) ListSyncOperations ¶
func (kdb *KeyDB) ListSyncOperations(zoneName string, limit int) ([]*SyncOperationRecord, error)
ListSyncOperations retrieves sync operations, optionally filtered by zone.
func (*KeyDB) ListTransportEvents ¶
func (kdb *KeyDB) ListTransportEvents(peerID string, limit int) ([]*HsyncTransportEvent, error)
ListTransportEvents retrieves transport events, optionally filtered by peer.
func (*KeyDB) LoadAllContributions ¶
func (kdb *KeyDB) LoadAllContributions() (map[string]map[string]map[string]map[uint16]core.RRset, error)
LoadAllContributions loads the entire CombinerContributions table and returns it structured as zone → senderID → owner → rrtype → RRset. Used at startup to hydrate AgentContributions for all combiner zones.
func (*KeyDB) LoadAllPublishInstructions ¶
func (kdb *KeyDB) LoadAllPublishInstructions() (map[string]map[string]*StoredPublishInstruction, error)
LoadAllPublishInstructions loads all stored instructions, keyed by zone then senderID.
func (*KeyDB) LoadDnskeyTrustAnchors ¶
XXX: This should die now that we have a real IMR
func (*KeyDB) LoadOutgoingSerial ¶
func (*KeyDB) LoadSig0ChildKeys ¶
func (*KeyDB) Lock ¶
func (kdb *KeyDB) Lock()
Lock and Unlock expose the mutex for code that moves to tdns-mp and can no longer access the unexported kdb.mu.
func (*KeyDB) LogTransportEvent ¶
func (kdb *KeyDB) LogTransportEvent(peerID, zoneName, eventType, transportType, direction string, success bool, errorCode, errorMessage string, context map[string]interface{}) error
LogTransportEvent logs a transport event for debugging.
func (*KeyDB) MarkSyncOperationConfirmed ¶
MarkSyncOperationConfirmed marks a sync operation as confirmed.
func (*KeyDB) NextEditID ¶
NextEditID returns the next available edit ID across all three tables.
func (*KeyDB) ProcessKeyState ¶
func (kdb *KeyDB) ProcessKeyState(ks *edns0.KeyStateOption, zonename string) (*edns0.KeyStateOption, error)
func (*KeyDB) PromoteDnssecKey ¶
func (*KeyDB) RecordMetrics ¶
func (kdb *KeyDB) RecordMetrics(peerID, zoneName string, metrics *HsyncMetricsInfo) error
RecordMetrics records operational metrics for a time period.
func (*KeyDB) RejectPendingEdit ¶
func (kdb *KeyDB) RejectPendingEdit(editID int, reason string) (*PendingEditRecord, error)
RejectPendingEdit moves a pending edit to the rejected table with a reason. Returns the original pending edit data for sending rejection confirmation.
func (*KeyDB) ResolvePendingEdit ¶
func (kdb *KeyDB) ResolvePendingEdit(editID int, approvedRecords, rejectedRecords map[string][]string, reason string) error
ResolvePendingEdit removes a pending edit and writes the approved and rejected portions to their respective tables. This correctly handles partial results where some records were applied and others were rejected by policy.
approvedRecords: owner→[]rrstring for records that were applied or removed rejectedRecords: owner→[]rrstring for records that were rejected reason: rejection reason (used for all rejected records)
func (*KeyDB) RolloverKey ¶
RolloverKey performs a manual key rollover for the specified zone and key type. It swaps the oldest standby key to active and the current active key to retired. Returns the old active keyid and the new active keyid. If tx is non-nil, uses the existing transaction; otherwise begins its own.
func (*KeyDB) SaveContributions ¶
func (kdb *KeyDB) SaveContributions(zone, senderID string, contributions map[string]map[uint16]core.RRset) error
SaveContributions replaces all rows for (zone, senderID) with the current contributions. Runs in a transaction: DELETE old rows, INSERT new rows.
func (*KeyDB) SaveOutgoingSerial ¶
func (*KeyDB) SavePeer ¶
func (kdb *KeyDB) SavePeer(peer *PeerRecord) error
SavePeer inserts or updates a peer in the database.
func (*KeyDB) SavePendingEdit ¶
func (kdb *KeyDB) SavePendingEdit(rec *PendingEditRecord) error
SavePendingEdit inserts a new pending edit.
func (*KeyDB) SavePublishInstruction ¶
func (kdb *KeyDB) SavePublishInstruction(zone, senderID string, instr *core.PublishInstruction, publishedNS []string) error
SavePublishInstruction upserts a publish instruction for (zone, senderID).
func (*KeyDB) SaveSyncConfirmation ¶
func (kdb *KeyDB) SaveSyncConfirmation(conf *SyncConfirmationRecord) error
SaveSyncConfirmation inserts a confirmation record.
func (*KeyDB) SaveSyncOperation ¶
func (kdb *KeyDB) SaveSyncOperation(op *SyncOperationRecord) error
SaveSyncOperation inserts a new sync operation.
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) SetPropagationConfirmed ¶
SetPropagationConfirmed marks a DNSKEY as propagation-confirmed in the keystore. Called when the agent sends KEYSTATE "propagated" to the signer.
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) TransitionMpdistToPublished ¶
TransitionMpdistToPublished transitions a key from mpdist to published state. Called when the signer receives a "propagated" KEYSTATE signal from the agent, indicating all remote providers have confirmed the key. If the key is not in mpdist state, this is a no-op (returns nil).
func (*KeyDB) TransitionMpremoveToRemoved ¶
TransitionMpremoveToRemoved transitions a key from mpremove to removed state. Called when the signer receives a "propagated" KEYSTATE signal from the agent, indicating all remote providers have confirmed the key removal. If the key is not in mpremove state, this is a no-op (returns nil).
func (*KeyDB) TriggerChildKeyVerification ¶
TriggerChildKeyVerification starts an async verification of a child KEY that was just stored in the TrustStore. It uses the KeyBootstrapper's retry pattern: verify via DNS lookup, retry with backoff, then trust.
func (*KeyDB) UpdateDnssecKeyState ¶
UpdateDnssecKeyState transitions a DNSSEC key to a new state and sets the appropriate lifecycle timestamp. When transitioning to "published", sets published_at. When transitioning to "retired", sets retired_at. Invalidates the cache for both old and new states.
func (*KeyDB) UpdateKeyState ¶
func (kdb *KeyDB) UpdateKeyState(ctx context.Context, keyName string, keyid uint16, imr *Imr, algorithm uint8) error
UpdateKeyState sends a KeyState inquiry to the DSYNC target for the given key and updates the local key store with the parent's response. If the parent reports the key as unknown, triggers a bootstrap.
func (*KeyDB) UpdatePeerContact ¶
UpdatePeerContact updates the last contact timestamp.
func (*KeyDB) UpdatePeerState ¶
UpdatePeerState updates just the state fields of a peer.
func (*KeyDB) UpdateSyncOperationStatus ¶
UpdateSyncOperationStatus updates the status of a sync operation.
type KeyInventoryItem ¶
type KeyInventoryItem struct {
KeyTag uint16
Algorithm uint8
Flags uint16
State string // "created","mpdist","published","standby","active","retired","removed","foreign"
KeyRR string // Full DNSKEY RR string (public key data, no private key)
}
KeyInventoryItem is a lightweight DNSKEY entry for inventory responses. Does not include private key material — only the metadata needed for key classification.
type KeyInventorySnapshot ¶
type KeyInventorySnapshot struct {
SenderID string
Zone string
Inventory []KeyInventoryItem
Received time.Time
}
KeyInventorySnapshot stores a complete key inventory received from the signer.
NOTE: MP type in tdns because it is a field of ZoneMPExtension.
type KeyLifetime ¶
func GenKeyLifetime ¶
func GenKeyLifetime(lifetime, sigvalidity string) KeyLifetime
type KeystateInfo ¶
type KeystateInfo struct {
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
}
KeystateInfo reports the health of the KEYSTATE exchange with the signer for a zone.
type KeystateInventoryMsg ¶
type KeystateInventoryMsg struct {
SenderID string
Zone string
Inventory []KeyInventoryItem
}
KeystateInventoryMsg carries a complete KEYSTATE inventory from signer to agent. Delivered via MsgQs.KeystateInventory channel.
type KeystateSignalMsg ¶
type KeystateSignalMsg struct {
SenderID string
Zone string
KeyTag uint16
Signal string // "propagated", "rejected", "removed"
Message string
}
KeystateSignalMsg carries a per-key KEYSTATE signal from agent to signer. Delivered via MsgQs.KeystateSignal channel. Signals: "propagated" (all remote providers confirmed), "rejected" (some provider rejected).
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 LeaderElection ¶
type LeaderElection struct {
Zone ZoneName
Leader AgentId
LeaderExpiry time.Time
Active bool
Term uint64
MyVote uint32
Votes map[AgentId]uint32
Confirms map[AgentId]AgentId
ExpectedPeers int
VoteTimer *time.Timer
ConfirmTimer *time.Timer
ReelectTimer *time.Timer
// contains filtered or unexported fields
}
LeaderElection tracks the per-zone election state.
type LeaderElectionManager ¶
type LeaderElectionManager struct {
// contains filtered or unexported fields
}
LeaderElectionManager coordinates leader election across all zones. Phase 6: supports both per-zone elections (legacy) and per-group elections. When a ProviderGroupManager is set, elections are per-group and the leader covers all zones in the group. IsLeader checks group membership first.
func (*LeaderElectionManager) ApplyGossipElection ¶
func (lem *LeaderElectionManager) ApplyGossipElection(groupHash string, state GroupElectionState)
ApplyGossipElection updates the LEM with election state received via gossip. Only accepts the update if the gossip term is higher than the local term.
func (*LeaderElectionManager) DeferElection ¶
func (lem *LeaderElectionManager) DeferElection(zone ZoneName)
DeferElection records a zone as needing an election once peers become operational. Called from OnFirstLoad when peers aren't ready yet at zone load time.
func (*LeaderElectionManager) DeferGroupElection ¶
func (lem *LeaderElectionManager) DeferGroupElection(groupHash string)
DeferGroupElection records a group as needing an election when OnGroupOperational fires.
func (*LeaderElectionManager) GetAllLeaders ¶
func (lem *LeaderElectionManager) GetAllLeaders() []LeaderStatus
GetAllLeaders returns the current leader status for all zones with an active leader.
func (*LeaderElectionManager) GetGroupElectionState ¶
func (lem *LeaderElectionManager) GetGroupElectionState(groupHash string) GroupElectionState
GetGroupElectionState returns the election state for a group (for gossip).
func (*LeaderElectionManager) GetGroupLeader ¶
func (lem *LeaderElectionManager) GetGroupLeader(groupHash string) (AgentId, bool)
GetGroupLeader returns the current leader for a provider group.
func (*LeaderElectionManager) GetLeader ¶
func (lem *LeaderElectionManager) GetLeader(zone ZoneName) (AgentId, bool)
GetLeader returns the current leader for a zone, if known and not expired.
func (*LeaderElectionManager) GetParentSyncStatus ¶
func (lem *LeaderElectionManager) GetParentSyncStatus(zone ZoneName, zd *ZoneData, kdb *KeyDB, imr *Imr, ar *AgentRegistry) ParentSyncStatus
GetParentSyncStatus computes the current parent sync status for a zone on demand.
func (*LeaderElectionManager) GetPendingElections ¶
func (lem *LeaderElectionManager) GetPendingElections() []ZoneName
GetPendingElections returns zones with deferred elections (waiting for peers).
func (*LeaderElectionManager) HandleGroupMessage ¶
func (lem *LeaderElectionManager) HandleGroupMessage(groupHash string, senderID AgentId, rfiType string, records map[string][]string)
HandleGroupMessage dispatches an election message that carries a _group record.
func (*LeaderElectionManager) HandleMessage ¶
func (lem *LeaderElectionManager) HandleMessage(zone ZoneName, senderID AgentId, rfiType string, records map[string][]string)
HandleMessage dispatches an incoming election message to the appropriate handler.
func (*LeaderElectionManager) InvalidateGroupLeader ¶
func (lem *LeaderElectionManager) InvalidateGroupLeader(groupHash string)
InvalidateGroupLeader clears the leader for a group (e.g., when the group degrades). Keeps the term so "invalidated" status can be reported.
func (*LeaderElectionManager) IsLeader ¶
func (lem *LeaderElectionManager) IsLeader(zone ZoneName) bool
IsLeader returns true if the local agent is the current leader for a zone. Checks group-based election first (if provider groups are configured), then falls back to per-zone election.
func (*LeaderElectionManager) NotifyPeerOperational ¶
func (lem *LeaderElectionManager) NotifyPeerOperational(peerZones map[ZoneName]bool)
NotifyPeerOperational is called when a peer becomes operational. Checks if deferred elections or leaderless zones can now hold elections. Elections require ALL configured peers to be operational.
func (*LeaderElectionManager) SetConfiguredPeersFunc ¶
func (lem *LeaderElectionManager) SetConfiguredPeersFunc(f func(zone ZoneName) int)
SetConfiguredPeersFunc sets the callback that returns the number of configured peers for a zone (from HSYNC3 records, minus self). Elections require ALL configured peers to participate — partial elections are aborted.
func (*LeaderElectionManager) SetOnLeaderElected ¶
func (lem *LeaderElectionManager) SetOnLeaderElected(f func(zone ZoneName) error)
SetOnLeaderElected sets the callback invoked when the local agent wins an election. Used to trigger delegation sync setup (SIG(0) key generation + bootstrap with parent).
func (*LeaderElectionManager) SetOperationalPeersFunc ¶
func (lem *LeaderElectionManager) SetOperationalPeersFunc(f func(zone ZoneName) int)
SetOperationalPeersFunc sets the callback used to count operational peers for re-election.
func (*LeaderElectionManager) SetProviderGroupManager ¶
func (lem *LeaderElectionManager) SetProviderGroupManager(pgm *ProviderGroupManager)
SetProviderGroupManager sets the provider group manager for group-based elections.
func (*LeaderElectionManager) StartElection ¶
func (lem *LeaderElectionManager) StartElection(zone ZoneName, expectedPeers int)
StartElection initiates a new election for a zone. If expectedPeers is 0, the local agent immediately becomes leader without sending any messages.
func (*LeaderElectionManager) StartGroupElection ¶
func (lem *LeaderElectionManager) StartGroupElection(groupHash string, members []string, zones []ZoneName)
StartGroupElection initiates a leader election for a provider group. The election is broadcast using one of the group's zones as the RFI channel. The winner becomes leader for ALL zones in the group.
type LeaderStatus ¶
LeaderStatus describes the current leader for a single zone.
type LocalAgentApiConf ¶
type LocalAgentDnsConf ¶
type LocalAgentDnsConf struct {
Addresses struct {
Publish []string
Listen []string
}
BaseUrl string
Port uint16
ControlZone string `yaml:"control_zone" mapstructure:"control_zone"` // Zone used for NOTIFY(CHUNK) QNAMEs in DNS mode (default: agent identity)
// Chunk config (same key names as combiner for consistency)
ChunkMode string `yaml:"chunk_mode" mapstructure:"chunk_mode"` // "edns0" | "query"; query = store payload, receiver fetches via CHUNK query (default: edns0)
ChunkQueryEndpoint string `yaml:"chunk_query_endpoint" mapstructure:"chunk_query_endpoint"` // "include" | "none"; required when chunk_mode=query. include = signal in NOTIFY (EDNS0); none = receiver uses combiner.agents[].address
// ChunkMaxSize: maximum size (bytes) of each data chunk when fragmenting payloads via PrepareDistributionChunks.
// 0 = default (60000). Useful for testing fragmentation with small values (e.g. 500).
ChunkMaxSize int `yaml:"chunk_max_size" mapstructure:"chunk_max_size"`
// Message retention times for CHUNK distributions (in seconds)
MessageRetention MessageRetentionConf `yaml:"message_retention" mapstructure:"message_retention"`
}
type MPTransportBridge ¶
type MPTransportBridge struct {
*transport.TransportManager // generic (fields promoted via embedding)
// SupportedMechanisms lists active transports ("api", "dns")
SupportedMechanisms []string
// contains filtered or unexported fields
}
MPTransportBridge manages multiple transports for agent communication. MPTransportBridge aggregates MP-specific transport state and methods. It holds a reference to the generic transport.TransportManager and adds multi-provider functionality (message routing, authorization, agent discovery, DNSKEY propagation, reliable delivery wrappers).
func NewMPTransportBridge ¶
func NewMPTransportBridge(cfg *MPTransportBridgeConfig) *MPTransportBridge
NewTransportManager creates a new MPTransportBridge with both API and DNS transports.
func (*MPTransportBridge) DiscoverAndRegisterAgent ¶
func (tm *MPTransportBridge) DiscoverAndRegisterAgent(ctx context.Context, identity string) error
DiscoverAndRegisterAgent performs discovery and registration in one step.
func (*MPTransportBridge) EnqueueForCombiner ¶
func (tm *MPTransportBridge) EnqueueForCombiner(zone ZoneName, update *ZoneUpdate, distID string) (string, error)
EnqueueForCombiner enqueues a zone update for reliable delivery to the combiner. Called by SynchedDataEngine when a zone update needs to reach the combiner. If distID is non-empty, it is used as the distribution ID; otherwise a new one is generated. Returns the distributionID for tracking and any error.
func (*MPTransportBridge) EnqueueForSpecificAgent ¶
func (tm *MPTransportBridge) EnqueueForSpecificAgent(zone ZoneName, agentID AgentId, update *ZoneUpdate, distID string) error
EnqueueForSpecificAgent enqueues a zone update for a single agent. Used by "resync-targeted" to respond only to the requesting agent.
func (*MPTransportBridge) EnqueueForZoneAgents ¶
func (tm *MPTransportBridge) EnqueueForZoneAgents(zone ZoneName, update *ZoneUpdate, distID string) error
EnqueueForZoneAgents enqueues a zone update for reliable delivery to all remote agents involved with this zone (as determined by AgentRegistry). Called by SynchedDataEngine when a locally-originated update needs to reach all peer agents. Uses the same distID for all agents so the originating agent can correlate confirmations from combiner and agents.
func (*MPTransportBridge) GetDistributionRecipients ¶
func (tm *MPTransportBridge) GetDistributionRecipients(zone ZoneName, skipCombiner bool) []string
GetDistributionRecipients returns the list of recipient identities that will receive an update for the given zone. This is used by the SynchedDataEngine to populate TrackedRR.ExpectedRecipients so that ProcessConfirmation knows who must confirm before transitioning Pending → Accepted. If skipCombiner is true, the combiner is excluded from the list.
func (*MPTransportBridge) GetPreferredTransportName ¶
func (tm *MPTransportBridge) GetPreferredTransportName(agent *Agent) string
GetPreferredTransportName returns the preferred transport name for an agent.
func (*MPTransportBridge) GetQueuePendingMessages ¶
func (tm *MPTransportBridge) GetQueuePendingMessages() []transport.PendingMessageInfo
GetQueuePendingMessages returns a snapshot of all pending messages in the queue.
func (*MPTransportBridge) GetQueueStats ¶
func (tm *MPTransportBridge) GetQueueStats() transport.QueueStats
GetQueueStats returns statistics from the reliable message queue.
func (*MPTransportBridge) HasAPITransport ¶
func (tm *MPTransportBridge) HasAPITransport(agent *Agent) bool
HasAPITransport returns true if API transport is available for an agent.
func (*MPTransportBridge) HasDNSTransport ¶
func (tm *MPTransportBridge) HasDNSTransport(agent *Agent) bool
HasDNSTransport returns true if DNS transport is available for an agent.
func (*MPTransportBridge) IsPeerAuthorized ¶
func (tm *MPTransportBridge) IsPeerAuthorized(senderID string, zone string) (bool, string)
IsPeerAuthorized checks if a peer is authorized to communicate with us. Authorization can come from three sources:
1. Configured peers: Provided via AuthorizedPeers callback (role-specific) 2. LEGACY state: Established relationship with zero shared zones 3. HSYNC3 membership: Both peers listed in HSYNC3 RRset for a shared zone
This function is role-agnostic. Each role injects its own AuthorizedPeers callback at TransportManager creation time.
Parameters:
- senderID: Identity of the agent attempting to communicate
- zone: Optional zone name for HSYNC3 membership check (empty string skips HSYNC3 check)
Returns:
- authorized: true if agent is authorized
- reason: human-readable explanation of authorization decision
func (*MPTransportBridge) MarkDeliveryConfirmed ¶
func (tm *MPTransportBridge) MarkDeliveryConfirmed(distributionID string, senderID string) bool
MarkDeliveryConfirmed marks a queued message as confirmed by the recipient. senderID is the identity of the confirming party (= the original message recipient).
func (*MPTransportBridge) OnAgentDiscoveryComplete ¶
func (tm *MPTransportBridge) OnAgentDiscoveryComplete(agent *Agent)
OnAgentDiscoveryComplete is called when agent discovery completes. It syncs the Agent to a transport.Peer and sets preferred transport.
func (*MPTransportBridge) ProcessDnskeyConfirmation ¶
func (tm *MPTransportBridge) ProcessDnskeyConfirmation(distID string, source string, status string, rejectedItems []RejectedItemInfo) bool
ProcessDnskeyConfirmation checks if a confirmation is for a pending DNSKEY propagation. If so, marks the agent as confirmed. When all agents have confirmed, sends KEYSTATE "propagated" to the signer. If any agent rejects, sends KEYSTATE "rejected". Returns true if this confirmation was for a DNSKEY propagation (handled here).
func (*MPTransportBridge) RegisterChunkNotifyHandler ¶
func (tm *MPTransportBridge) RegisterChunkNotifyHandler() error
RegisterChunkNotifyHandler registers the CHUNK NOTIFY handler with tdns. This should be called during agent initialization.
func (*MPTransportBridge) RegisterDiscoveredAgent ¶
func (tm *MPTransportBridge) RegisterDiscoveredAgent(result *AgentDiscoveryResult) error
RegisterDiscoveredAgent adds a discovered agent to the PeerRegistry and optionally to AgentRegistry.
func (*MPTransportBridge) SelectTransport ¶
func (tm *MPTransportBridge) SelectTransport(peer *transport.Peer) transport.Transport
SelectTransport selects the appropriate transport for communicating with a peer.
func (*MPTransportBridge) SendBeatWithFallback ¶
func (tm *MPTransportBridge) SendBeatWithFallback(ctx context.Context, agent *Agent, sequence uint64) (*transport.BeatResponse, error)
SendBeatWithFallback sends a heartbeat to a peer with transport fallback. SendBeatWithFallback sends a Beat heartbeat to a peer (legacy name). UPDATED: Now sends Beat on ALL supported transports independently when both are configured. Returns success if ANY transport succeeds. Updates per-transport LastContactTime in Agent struct.
func (*MPTransportBridge) SendHelloWithFallback ¶
func (tm *MPTransportBridge) SendHelloWithFallback(ctx context.Context, agent *Agent, sharedZones []string) (*transport.HelloResponse, error)
SendHelloWithFallback sends a Hello handshake to a peer with transport fallback (legacy name). UPDATED: Now sends Hello on ALL supported transports independently when both are configured. Returns success if ANY transport succeeds. Updates per-transport state in Agent struct.
func (*MPTransportBridge) SendPing ¶
func (tm *MPTransportBridge) SendPing(ctx context.Context, peer *transport.Peer) (*transport.PingResponse, error)
SendPing sends a ping to a peer, preferring API transport when available.
func (*MPTransportBridge) SendSyncWithFallback ¶
func (tm *MPTransportBridge) SendSyncWithFallback(ctx context.Context, peer *transport.Peer, req *transport.SyncRequest) (*transport.SyncResponse, error)
SendWithFallback sends a message using the preferred transport, falling back if it fails.
func (*MPTransportBridge) StartIncomingMessageRouter ¶
func (tm *MPTransportBridge) StartIncomingMessageRouter(ctx context.Context)
StartIncomingMessageRouter starts a goroutine that routes incoming DNS messages to the appropriate hsyncengine channels. ctx is intentionally unused: kept in the signature for API stability and future use.
func (*MPTransportBridge) StartReliableQueue ¶
func (tm *MPTransportBridge) StartReliableQueue(ctx context.Context)
StartReliableQueue wires up the sendFunc and starts the queue's background worker. Must be called after MPTransportBridge is fully initialized (transports, combiner peer, etc.).
func (*MPTransportBridge) SyncPeerFromAgent ¶
func (tm *MPTransportBridge) SyncPeerFromAgent(agent *Agent) *transport.Peer
SyncPeerFromAgent creates or updates a transport.Peer from an existing Agent.
func (*MPTransportBridge) TrackDnskeyPropagation ¶
func (tm *MPTransportBridge) TrackDnskeyPropagation(zone ZoneName, distID string, keyTags []uint16, agents []AgentId)
TrackDnskeyPropagation registers a DNSKEY distribution for confirmation tracking. Called by SynchedDataEngine after enqueueing DNSKEY changes for remote agents.
type MPTransportBridgeConfig ¶
type MPTransportBridgeConfig struct {
LocalID string
ControlZone string
APITimeout time.Duration
DNSTimeout time.Duration
AgentRegistry *AgentRegistry
MsgQs *MsgQs
// ChunkMode: "edns0" or "query"; when "query", agent stores payload and sends NOTIFY without EDNS0; receiver fetches via CHUNK query
ChunkMode string
ChunkPayloadStore ChunkPayloadStore
// ChunkQueryEndpoint: for query mode, address (host:port) where agent answers CHUNK queries
ChunkQueryEndpoint string
// ChunkQueryEndpointInNotify: when true, include endpoint in NOTIFY (EDNS0 option 65005); when false, receiver uses static config (e.g. combiner.agents[].address)
ChunkQueryEndpointInNotify bool
// ChunkMaxSize: maximum data chunk size in bytes for PrepareDistributionChunks.
// 0 = default (60000). Set small (e.g. 500) for fragmentation testing.
ChunkMaxSize int
// PayloadCrypto enables JWS/JWE encryption for CHUNK payloads (optional)
// If set and Enabled, all outgoing CHUNK payloads will be encrypted and signed
PayloadCrypto *transport.PayloadCrypto
// DistributionCache: when set, outgoing CHUNK operations (ping, hello, etc.) are registered for "agent distrib list"
DistributionCache *DistributionCache
// SupportedMechanisms lists active transports ("api", "dns"); default: both if configured
SupportedMechanisms []string
// CombinerID is the identity of the combiner for this agent (from config).
// Used by EnqueueForCombiner to know which AgentRegistry entry is the combiner.
CombinerID string
// SignerID is the identity of the local signer for KEYSTATE signaling (Phase 6).
SignerID string
// SignerAddress is the DNS address (host:port) of the local signer.
SignerAddress string
// AuthorizedPeers returns the list of peer identities authorized via config.
// Called at runtime during authorization. Each role provides its own implementation.
// If nil, only HSYNC-based and LEGACY-based authorization is used.
AuthorizedPeers func() []string
// MessageRetention returns retention seconds for a given message type (operation).
// Used by distribution cache for expiration. If nil, default retention is used.
MessageRetention func(operation string) int
// GetImrEngine returns the IMR resolver for DNS-based agent discovery (optional).
// Uses a closure because ImrEngine starts asynchronously after TM creation.
// Only the agent needs this; combiner/signer/external apps pass nil.
GetImrEngine func() *Imr
// ClientCertFile and ClientKeyFile are the TLS client certificate presented when
// connecting to peers' sync API servers. Required when peers enforce mutual TLS
// (e.g. combiner/signer sync routers verify client cert against agent's TLSA record).
ClientCertFile string
ClientKeyFile string
}
MPTransportBridgeConfig holds configuration for creating a MPTransportBridge.
type MPZoneInfo ¶
type MPZoneInfo struct {
Providers []string `json:"providers"`
Signers []string `json:"signers"`
NSmgmt string `json:"nsmgmt"`
ParentSync string `json:"parentsync"`
Suffix string `json:"suffix,omitempty"`
Options []ZoneOption `json:"options"`
}
MPZoneInfo carries multi-provider zone details for the mplist command.
type MPdata ¶
type MPdata struct {
WeAreProvider bool // At least one of our agent identities matches an HSYNC3 Identity
OurLabel string // Our provider label from the matching HSYNC3 record
WeAreSigner bool // Our label appears in HSYNCPARAM signers (or zone is unsigned)
OtherSigners int // Count of other signers in HSYNCPARAM
ZoneSigned bool // HSYNCPARAM signers= is non-empty (zone uses multi-signer)
Options map[ZoneOption]bool // MP-specific options (future: migrate from zd.Options)
}
MPdata caches multi-provider membership and signing state for a zone. nil means the zone is not confirmed as a multi-provider zone (either OptMultiProvider is not set, or the zone owner hasn't declared it via HSYNC3+HSYNCPARAM, or we are not a listed provider). Populated during zone refresh by populateMPdata().
NOTE: This is an MP type that lives in tdns (not tdns-mp) because it is a field of ZoneMPExtension, which is a field of ZoneData.
type MSCAPIConf ¶
type MSCNotifyConf ¶
type MemChunkPayloadStore ¶
type MemChunkPayloadStore struct {
// contains filtered or unexported fields
}
MemChunkPayloadStore is an in-memory store with TTL.
func NewMemChunkPayloadStore ¶
func NewMemChunkPayloadStore(ttl time.Duration) *MemChunkPayloadStore
NewMemChunkPayloadStore creates a store with the given TTL (e.g. 5*time.Minute).
func (*MemChunkPayloadStore) Get ¶
func (s *MemChunkPayloadStore) Get(qname string) ([]byte, uint8, bool)
func (*MemChunkPayloadStore) GetChunk ¶
GetChunk returns a specific chunk by sequence number from a stored chunk array. Sequence 0 = manifest, 1..N = data chunks. The index into the array equals the sequence number.
type MemberState ¶
type MemberState struct {
Identity string `json:"identity"`
PeerStates map[string]string `json:"peer_states"` // key: peer identity, value: state string
Zones []string `json:"zones"` // zones this member serves in this group
Timestamp time.Time `json:"timestamp"` // set by the member itself
}
MemberState is one member's view of all other members in the group. Only the member itself updates its own MemberState (sets Timestamp). Other agents propagate it via gossip without modification.
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 MessageRetentionConf ¶
type MessageRetentionConf struct {
Beat int `yaml:"beat" mapstructure:"beat"` // Beat message retention (default: 30s)
Ping int `yaml:"ping" mapstructure:"ping"` // Ping message retention (default: 30s)
Hello int `yaml:"hello" mapstructure:"hello"` // Hello message retention (default: 300s)
Sync int `yaml:"sync" mapstructure:"sync"` // Sync message retention (default: 300s)
Relocate int `yaml:"relocate" mapstructure:"relocate"` // Relocate message retention (default: 300s)
Default int `yaml:"default" mapstructure:"default"` // Default retention for other types (default: 300s)
}
MessageRetentionConf defines retention times for different message types in CHUNK distributions. Times are in seconds. Beat and ping messages expire quickly to reduce clutter, while other message types are kept longer for debugging purposes.
func (*MessageRetentionConf) GetRetentionForMessageType ¶
func (m *MessageRetentionConf) GetRetentionForMessageType(messageType string) int
GetRetentionForMessageType returns the retention time in seconds for a given message type. Returns the configured value if set, otherwise returns the appropriate default.
type MetaGroupConfig ¶
type MetaGroupConfig = ConfigGroupConfig
MetaGroupConfig is deprecated, use ConfigGroupConfig instead
type MsgQs ¶
type MsgQs struct {
Hello chan *AgentMsgReport // incoming /hello from other agents
Beat chan *AgentMsgReport // incoming /beat from other agents
Ping chan *AgentMsgReport // incoming /ping 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
Confirmation chan *ConfirmationDetail // combiner confirmation feedback
KeystateInventory chan *KeystateInventoryMsg // incoming KEYSTATE inventory from signer
KeystateSignal chan *KeystateSignalMsg // incoming KEYSTATE signals (propagated/rejected) from agent to signer
EditsResponse chan *EditsResponseMsg // incoming EDITS response from combiner
ConfigResponse chan *ConfigResponseMsg // incoming CONFIG response from peer agent
AuditResponse chan *AuditResponseMsg // incoming AUDIT response from peer agent
StatusUpdate chan *StatusUpdateMsg // incoming STATUS-UPDATE notifications
// OnRemoteConfirmationReady is called when this agent (acting as a remote agent)
// receives a combiner confirmation for a sync that originated from another agent.
// The callback sends the final confirmation NOTIFY back to the originating agent.
OnRemoteConfirmationReady func(detail *RemoteConfirmationDetail)
}
type MultiProviderConf ¶
type MultiProviderConf struct {
// Role: "agent", "combiner", or "signer". Determines which fields are active.
Role string `yaml:"role"`
// Active: master switch for multi-provider mode.
// Must be true AND zone must have options: [multi-provider] for MP behavior.
Active bool `yaml:"active"`
// Identity: this node's identity (FQDN) for transport protocol.
Identity string `yaml:"identity"`
// LongTermJosePrivKey: path to JOSE private key for secure CHUNK.
LongTermJosePrivKey string `yaml:"long_term_jose_priv_key"`
// ChunkMode: "edns0" | "query" for outbound NOTIFY(CHUNK).
ChunkMode string `yaml:"chunk_mode" mapstructure:"chunk_mode"`
// ChunkMaxSize: maximum size (bytes) of each data chunk when fragmenting payloads.
// 0 = default (60000). Useful for testing fragmentation with small values.
ChunkMaxSize int `yaml:"chunk_max_size" mapstructure:"chunk_max_size"`
// Agents: the agent peers (address, JOSE public key, optional API URL).
// Used by signer and combiner roles.
Agents []*PeerConf `yaml:"agents"`
// SyncApi: sync API server config for inbound HELLO/BEAT/PING over HTTPS.
// Used by signer and combiner roles.
SyncApi struct {
Addresses struct {
Listen []string
}
CertFile string `yaml:"cert_file" mapstructure:"cert_file"`
KeyFile string `yaml:"key_file" mapstructure:"key_file"`
} `yaml:"sync_api" mapstructure:"sync_api"`
// CombinerOptions: list of combiner-specific option strings parsed at startup.
// Known options: "add-signature".
CombinerOptionsStrs []string `yaml:"combiner-options" mapstructure:"combiner-options"`
CombinerOptions map[CombinerOption]bool `yaml:"-" mapstructure:"-"`
// ChunkQueryEndpoint: "include" | "none"; required when chunk_mode=query (combiner role).
ChunkQueryEndpoint string `yaml:"chunk_query_endpoint" mapstructure:"chunk_query_endpoint"`
// Signature: template string for a TXT record injected into combined zones (demo feature).
// Supports {identity} and {zone} placeholders.
Signature string `yaml:"signature"`
AddSignature bool `yaml:"add-signature" mapstructure:"add-signature"` // DEPRECATED: use combiner-options: [add-signature]
// ProtectedNamespaces: list of domain suffixes that belong to this provider.
// NS records from remote agents whose targets fall within any of these namespaces
// are rejected (prevents namespace intrusion).
ProtectedNamespaces []string `yaml:"protected-namespaces" mapstructure:"protected-namespaces"`
// ProviderZones: zones owned by the provider where agents may make targeted edits
// (e.g. _signal KEY records). Unlike MP zones, these use config-driven RRtype
// restrictions and allow non-apex owners.
ProviderZones []ProviderZoneConf `yaml:"provider-zones" mapstructure:"provider-zones"`
// SignerOptions: list of signer-specific option strings parsed at startup.
SignerOptionsStrs []string `yaml:"signer-options" mapstructure:"signer-options"`
SignerOptions map[SignerOption]bool `yaml:"-" mapstructure:"-"`
// AgentOptions: list of agent-specific option strings parsed at startup.
AgentOptionsStrs []string `yaml:"agent-options" mapstructure:"agent-options"`
AgentOptions map[AgentOption]bool `yaml:"-" mapstructure:"-"`
// SupportedMechanisms: List of active transport mechanisms (default: ["api", "dns"] if both configured)
SupportedMechanisms []string `yaml:"supported_mechanisms" mapstructure:"supported_mechanisms"`
Local struct {
Notify []string
Nameservers []string `yaml:"nameservers,omitempty"`
}
Remote struct {
LocateInterval int
BeatInterval uint32
}
Syncengine struct {
Intervals struct {
HelloRetry int
}
}
Api LocalAgentApiConf
Dns LocalAgentDnsConf
// Combiner peer (agent only): address and combiner's JOSE public key path for secure CHUNK
Combiner *PeerConf `yaml:"combiner"`
// Signer peer (agent only): address and JOSE public key path for KEYSTATE signaling
Signer *PeerConf `yaml:"signer"`
// AuthorizedPeers: List of agent identities authorized to communicate
AuthorizedPeers []string `yaml:"authorized_peers"`
// Peers (DEPRECATED): Old format with embedded addresses/keys - use authorized_peers instead
Peers map[string]*PeerConf `yaml:"peers"`
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"`
}
}
}
MultiProviderConf holds config for multi-provider DNSSEC (RFC 8901). Used by all three MP roles: agent, combiner, and signer. The Role field determines which role-specific fields are relevant. YAML key: "multi-provider:"
func (*MultiProviderConf) FindAgent ¶
func (c *MultiProviderConf) FindAgent(identity string) *PeerConf
FindAgent returns the PeerConf for the agent with the given identity, or nil if not found.
type MultiSignerConf ¶
type MultiSignerConf struct {
Name string
Controller MultiSignerController
}
type MultiSignerController ¶
type MultiSignerController struct {
Name string
Notify MSCNotifyConf
API MSCAPIConf
}
type MultiSignerPost ¶
type MultiSignerResponse ¶
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 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 NotifyResponse ¶
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 ParentSyncStatus ¶
type ParentSyncStatus struct {
Zone ZoneName `json:"zone"`
Leader AgentId `json:"leader"`
LeaderExpiry time.Time `json:"leader_expiry"`
ElectionTerm uint64 `json:"election_term"`
IsLeader bool `json:"is_leader"`
KeyAlgorithm string `json:"key_algorithm,omitempty"`
KeyID uint16 `json:"key_id,omitempty"`
KeyRR string `json:"key_rr,omitempty"`
ApexPublished bool `json:"apex_published"`
ParentState uint8 `json:"parent_state"`
ParentStateName string `json:"parent_state_name,omitempty"`
ChildNS []string `json:"child_ns,omitempty"`
KeyPublication map[string]bool `json:"key_publication,omitempty"`
LastChecked time.Time `json:"last_checked"`
// Sync scheme info from parent DSYNC discovery
ParentZone string `json:"parent_zone,omitempty"`
SyncSchemes []DsyncSchemeInfo `json:"sync_schemes,omitempty"`
ActiveScheme string `json:"active_scheme,omitempty"` // best scheme: "UPDATE", "NOTIFY", etc.
// CDS/CSYNC publication status
CdsPublished bool `json:"cds_published"`
CsyncPublished bool `json:"csync_published"`
ZoneSigned bool `json:"zone_signed"`
// Peer agents for this zone
Peers []PeerSyncInfo `json:"peers,omitempty"`
}
ParentSyncStatus holds on-demand status information about parent delegation sync for a zone.
type PeerConf ¶
type PeerConf struct {
Address string `yaml:"address"`
LongTermJosePubKey string `yaml:"long_term_jose_pub_key"`
ApiBaseUrl string `yaml:"api_base_url,omitempty"` // Optional: for API transport (e.g. https://combiner:8085/api/v1)
Identity string `yaml:"identity"` // Peer identity (FQDN); required for combiner agents, optional for agent combiner
}
PeerConf holds address and public key path for the other party (agent or combiner).
type PeerInfo ¶
type PeerInfo struct {
PeerID string
PeerType string // "combiner" or "agent"
Transport string // "API" or "DNS"
Address string
CryptoType string // "JOSE" or "HPKE" (for DNS), "TLS" (for API), or "-"
DistribSent int // Number of distributions sent to this peer (deprecated - use TotalReceived)
LastUsed time.Time // Last time this peer was used
Addresses []string // IP addresses from discovery
Port uint16 // Port number
JWKData string // JWK data if available
KeyAlgorithm string // Key algorithm (e.g., "ES256")
HasJWK bool // Whether JWK is available
HasKEY bool // Whether KEY record is available
HasTLSA bool // Whether TLSA record is available
APIUri string // Full API URI
DNSUri string // Full DNS URI
Partial bool // Whether discovery was partial
State string // Agent state
ContactInfo string // Contact info status
// Per-message-type statistics
HelloSent uint64
HelloReceived uint64
BeatSent uint64
BeatReceived uint64
SyncSent uint64
SyncReceived uint64
PingSent uint64
PingReceived uint64
TotalSent uint64
TotalReceived uint64
}
PeerInfo holds information about a peer agent with established keys
type PeerRecord ¶
type PeerRecord struct {
ID int64
PeerID string
DiscoveryTime time.Time
DiscoverySource string
APIEndpoint string
APIHost string
APIPort int
APITlsaRecord string
APIAvailable bool
DNSHost string
DNSPort int
DNSKeyRecord string
DNSAvailable bool
OperationalHost string
OperationalPort int
OperationalTransport string
EncryptionPubkey string
VerificationPubkey string
State string
StateReason string
StateChangedAt time.Time
PreferredTransport string
LastContactAt time.Time
LastHelloAt time.Time
LastBeatAt time.Time
BeatInterval int
BeatsSent int64
BeatsReceived int64
FailedContacts int
CreatedAt time.Time
UpdatedAt time.Time
}
PeerRecord represents a row in the PeerRegistry table.
func PeerRecordFromAgent ¶
func PeerRecordFromAgent(agent *Agent) *PeerRecord
PeerRecordFromAgent creates a PeerRecord from an Agent.
func PeerRecordFromTransportPeer ¶
func PeerRecordFromTransportPeer(peer *transport.Peer) *PeerRecord
PeerRecordFromTransportPeer creates a PeerRecord from a transport.Peer.
type PeerSyncInfo ¶
type PeerSyncInfo struct {
Identity AgentId `json:"identity"`
State string `json:"state"`
Transport string `json:"transport"`
Operational bool `json:"operational"`
}
PeerSyncInfo describes a peer agent's status for a zone.
type PendingDnskeyPropagation ¶
type PendingDnskeyPropagation struct {
Zone ZoneName
DistributionID string
KeyTags []uint16 // DNSKEY key tags being propagated
ExpectedAgents map[AgentId]bool // Agents we're waiting for (true = confirmed)
Rejected bool // True if any agent rejected
RejectionMsg string // First rejection reason
CreatedAt time.Time
}
PendingDnskeyPropagation tracks a DNSKEY distribution awaiting confirmation from all remote agents.
type PendingEditRecord ¶
type PendingEditRecord struct {
EditID int `json:"edit_id"`
Zone string `json:"zone"`
SenderID string `json:"sender_id"`
DeliveredBy string `json:"delivered_by"`
DistributionID string `json:"distribution_id"`
Records map[string][]string `json:"records"`
ReceivedAt time.Time `json:"received_at"`
}
PendingEditRecord represents a row in the CombinerPendingEdits table.
type PendingRemoteConfirmation ¶
type PendingRemoteConfirmation struct {
OriginatingDistID string
OriginatingSender string
Zone ZoneName
CreatedAt time.Time
}
PendingRemoteConfirmation tracks the relationship between a combiner distID (generated locally on the remote agent) and the originating agent's distID/identity.
type PingResponse ¶
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 ProviderGroup ¶
type ProviderGroup struct {
GroupHash string // truncated SHA-256 of sorted member identities
Name string // human-friendly name (resolved via naming protocol)
Members []string // sorted provider identities (FQDNs)
Zones []ZoneName // zones served by this exact set of providers
NameProposal *GroupNameProposal // our proposal for this group's name
}
ProviderGroup represents a set of providers that together serve a group of zones. The group is identified by a hash of the sorted member identities.
func (*ProviderGroup) GroupSummary ¶
func (pg *ProviderGroup) GroupSummary() string
GroupSummary returns a compact string representation for logging.
type ProviderGroupManager ¶
type ProviderGroupManager struct {
Groups map[string]*ProviderGroup // key: group hash
LocalID string // our own identity
// contains filtered or unexported fields
}
ProviderGroupManager manages provider group computation and naming.
func NewProviderGroupManager ¶
func NewProviderGroupManager(localIdentity string) *ProviderGroupManager
NewProviderGroupManager creates a new provider group manager.
func (*ProviderGroupManager) GetGroup ¶
func (pgm *ProviderGroupManager) GetGroup(groupHash string) *ProviderGroup
GetGroup returns a specific provider group by hash.
func (*ProviderGroupManager) GetGroupByName ¶
func (pgm *ProviderGroupManager) GetGroupByName(name string) *ProviderGroup
GetGroupByName returns a provider group by its human-friendly name.
func (*ProviderGroupManager) GetGroupForZone ¶
func (pgm *ProviderGroupManager) GetGroupForZone(zone ZoneName) *ProviderGroup
GetGroupForZone returns the provider group that contains the given zone.
func (*ProviderGroupManager) GetGroups ¶
func (pgm *ProviderGroupManager) GetGroups() []*ProviderGroup
GetGroups returns a snapshot of all current provider groups.
func (*ProviderGroupManager) GetGroupsForIdentity ¶
func (pgm *ProviderGroupManager) GetGroupsForIdentity(identity string) []*ProviderGroup
GetGroupsForIdentity returns all groups that include the given identity.
func (*ProviderGroupManager) ProposeGroupName ¶
func (pgm *ProviderGroupManager) ProposeGroupName(groupHash, name string)
ProposeGroupName sets our name proposal for a group.
func (*ProviderGroupManager) RecomputeGroups ¶
func (pgm *ProviderGroupManager) RecomputeGroups()
RecomputeGroups scans all loaded zones, extracts HSYNC3 identity sets, and rebuilds the provider group map. This is a pure function of zone data.
type ProviderZoneConf ¶
type ProviderZoneConf struct {
Zone string `yaml:"zone"`
AllowedRRtypes []string `yaml:"allowed-rrtypes" mapstructure:"allowed-rrtypes"`
}
ProviderZoneConf configures a provider-owned zone that the combiner manages. Unlike MP zones (hardcoded RRtype whitelist, apex-only), provider zones use config-driven RRtype restrictions and allow non-apex record owners.
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 RRConfirmation ¶
type RRConfirmation struct {
Status string `json:"status"` // "accepted", "rejected", "removed", "pending"
Reason string `json:"reason,omitempty"` // rejection reason
Timestamp time.Time `json:"timestamp"`
}
RRConfirmation records a single recipient's confirmation status for a tracked RR.
type RRState ¶
type RRState uint8
RRState represents the lifecycle state of a tracked RR.
const ( RRStatePending RRState = iota // Sent to combiner, awaiting confirmation RRStateAccepted // Combiner accepted RRStateRejected // Combiner rejected (see Reason) RRStatePendingRemoval // Delete sent to combiner, awaiting confirmation RRStateRemoved // Combiner confirmed removal (audit trail) )
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) GetOnlyRRSet ¶
func (s *RRTypeStore) GetOnlyRRSet(key uint16) core.RRset
GetOnlyRRSet returns the RRset for key, or zero-value RRset if not found.
func (*RRTypeStore) Keys ¶
func (s *RRTypeStore) Keys() []uint16
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 RefresherResponse ¶
type RejectedEditRecord ¶
type RejectedEditRecord struct {
EditID int `json:"edit_id"`
Zone string `json:"zone"`
SenderID string `json:"sender_id"`
DistributionID string `json:"distribution_id"`
Records map[string][]string `json:"records"`
ReceivedAt time.Time `json:"received_at"`
RejectedAt time.Time `json:"rejected_at"`
Reason string `json:"reason"`
}
RejectedEditRecord represents a row in the CombinerRejectedEdits table.
type RejectedItem ¶
RejectedItem describes an RR that was rejected and why.
type RejectedItemInfo ¶
RejectedItemInfo describes an RR rejected by the combiner.
type RemoteConfirmationDetail ¶
type RemoteConfirmationDetail struct {
OriginatingDistID string
OriginatingSender string
Zone ZoneName
Status string
Message string
AppliedRecords []string
RemovedRecords []string
RejectedItems []RejectedItemInfo
Truncated bool
}
RemoteConfirmationDetail carries per-RR confirmation detail to send back to the originating agent after the remote agent's combiner confirms.
type RfiData ¶
type RfiData struct {
Status string // ok | error | ...
Time time.Time
Msg string
Error bool
ErrorMsg string
ZoneXfrSrcs []string
ZoneXfrAuth []string
ZoneXfrDsts []string
AuditData map[ZoneName]map[AgentId]map[uint16][]TrackedRRInfo `json:"audit_data,omitempty"`
ConfigData map[string]string `json:"config_data,omitempty"` // key-value config data for RFI CONFIG
}
RfiData is defined in core package to avoid circular dependencies.
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 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)
DSAdds []dns.RR // DS records to add to parent (from CDS→DS conversion)
DSRemoves []dns.RR // DS records to remove from parent
NSAdds []dns.RR // NS records to add at child apex (from CSYNC)
NSRemoves []dns.RR // NS records to remove from child apex (from CSYNC)
GlueAdds []dns.RR // A/AAAA glue records to add (owner in RR header)
GlueRemoves []dns.RR // A/AAAA glue records to remove
Error bool // Whether an error occurred
ErrorMsg string // Error message if Error is true
}
ScanTupleResponse contains the result of scanning a single ScanTuple
type Scanner ¶
type Scanner struct {
AuthQueryQ chan AuthQueryRequest
ImrEngine *Imr
Options []string
AtApexChecks int
AtApexInterval time.Duration
OnDelegationChange func(parentZone string, zd *ZoneData, resp ScanTupleResponse)
LogFile string
LogTemplate string
Log map[string]*log.Logger
Verbose bool
Debug bool
Jobs map[string]*ScanJobStatus
JobsMutex sync.RWMutex
}
func NewScanner ¶
func NewScanner(authqueryq chan AuthQueryRequest, verbose, debug bool) *Scanner
func (*Scanner) AuthQueryNG ¶
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) CheckDNSKEY ¶
func (scanner *Scanner) CheckDNSKEY(ctx context.Context, tuple ScanTuple, scanType ScanType, options *edns0.MsgOptions, responseCh chan<- ScanTupleResponse)
func (*Scanner) CsyncAnalyzeA ¶
func (*Scanner) CsyncAnalyzeAAAA ¶
func (*Scanner) CsyncAnalyzeNS ¶
func (scanner *Scanner) CsyncAnalyzeNS(zone string, cdd *ChildDelegationData) ([]dns.RR, bool, error)
Returns: new_rrs, changed=true, error
func (*Scanner) ProcessCDSNotify ¶
func (scanner *Scanner) ProcessCDSNotify(ctx context.Context, tuple ScanTuple, parentZD *ZoneData, scanType ScanType, options *edns0.MsgOptions, responseCh chan<- ScanTupleResponse)
ProcessCDSNotify handles a CDS NOTIFY by querying CDS from child nameservers, converting CDS→DS, and diffing against current DS. The scanner is read-only: results (DSAdds/DSRemoves) are returned in the ScanTupleResponse for the caller to act on.
func (*Scanner) ProcessCSYNCNotify ¶
func (scanner *Scanner) ProcessCSYNCNotify(ctx context.Context, tuple ScanTuple, parentZD *ZoneData, scanType ScanType, options *edns0.MsgOptions, responseCh chan<- ScanTupleResponse)
ProcessCSYNCNotify handles a CSYNC NOTIFY by querying CSYNC, NS, and glue from child nameservers, diffing against current delegation data, and reporting NS/glue adds/removes in the ScanTupleResponse. The scanner is read-only: results are returned for the caller to act on. Follows RFC 7477 processing algorithm.
func (*Scanner) UpdateCsyncStatus ¶
type ScannerPost ¶
type ScannerResponse ¶
type SensitiveString ¶
type SensitiveString string
SensitiveString wraps a string that should not appear in logs. Use .Value() to get the actual string; String() returns a redacted form.
func (SensitiveString) String ¶
func (s SensitiveString) String() string
String returns a redacted representation for safe logging.
func (SensitiveString) Value ¶
func (s SensitiveString) Value() string
Value returns the actual string value.
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 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 *core.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 SignerOption ¶
type SignerOption uint8
type SigningGroupInfo ¶
type SigningGroupInfo struct {
Description string `yaml:"description" mapstructure:"description"`
}
SigningGroupInfo provides documentation for signing groups (RFC 9432 terminology)
type StatusUpdateMsg ¶
type StatusUpdateMsg struct {
SenderID string
Zone string
SubType string
NSRecords []string
DSRecords []string
Result string
Msg string
}
StatusUpdateMsg carries a status-update notification. Delivered via MsgQs.StatusUpdate channel. Subtypes: "ns-changed", "ksk-changed", "parentsync-done".
type StoredPublishInstruction ¶
type StoredPublishInstruction struct {
Zone string
SenderID string
KEYRRs []string
CDSRRs []string
Locations []string
PublishedNS []string // NS targets with currently active _signal KEYs
UpdatedAt time.Time
}
StoredPublishInstruction is the persisted form of a PublishInstruction, augmented with the set of NS targets that currently have active _signal KEYs.
func (*StoredPublishInstruction) ToPublishInstruction ¶
func (s *StoredPublishInstruction) ToPublishInstruction() *core.PublishInstruction
ToPublishInstruction converts back to the wire-format struct.
type SyncConfirmationRecord ¶
type SyncConfirmationRecord struct {
ID int64
DistributionID string
ConfirmerID string
Status string
Message string
ItemsProcessed []ConfirmationItem
SignedProof string
ConfirmerSignature string
ConfirmedAt time.Time
ReceivedAt time.Time
}
SyncConfirmationRecord represents a row in the SyncConfirmations table.
type SyncOperationRecord ¶
type SyncOperationRecord struct {
ID int64
DistributionID string
ZoneName string
SyncType string
Direction string
SenderID string
ReceiverID string
Records []string
Serial uint32
Transport string
Encrypted bool
Status string
StatusMessage string
CreatedAt time.Time
SentAt time.Time
ReceivedAt time.Time
ConfirmedAt time.Time
ExpiresAt time.Time
RetryCount int
LastError string
LastErrorAt time.Time
}
SyncOperationRecord represents a row in the SyncOperations table.
type SyncRequest ¶
type SyncRequest struct {
Command string
ZoneName ZoneName
ZoneData *ZoneData
SyncStatus *HsyncStatus
OldDnskeys *core.RRset
NewDnskeys *core.RRset
DnskeyStatus *DnskeyStatus // Local DNSKEY adds/removes (Phase 5)
Response chan SyncResponse
}
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
TargetAgent AgentId // For "resync-targeted": send only to this agent
Response chan *SynchedDataCmdResponse
}
type SynchedDataCmdResponse ¶
type SynchedDataResponse ¶
type SynchedDataUpdate ¶
type SynchedDataUpdate struct {
Zone ZoneName
AgentId AgentId
UpdateType string // "local" or "remote"
Update *ZoneUpdate
OriginatingDistID string // Distribution ID from the originating agent (for remote updates)
Force bool // Bypass dedup check (always send even if RR already present)
SkipCombiner bool // Don't send to combiner (e.g. local DNSKEY changes — signer adds its own)
DnskeyKeyTags []uint16 // Key tags for DNSKEY propagation tracking (mpdist flow)
// Response chan *SynchedDataResponse
Response chan *AgentMsgResponse
}
type TargetUpdateStatus ¶
type TemplateConf ¶
type TmpSig0Key ¶
type TrackedRR ¶
type TrackedRR struct {
RR dns.RR
State RRState
Reason string // Rejection reason (empty unless rejected)
DistributionID string // Last distribution this RR was part of
UpdatedAt time.Time
Confirmations map[string]RRConfirmation // recipientID → per-recipient status
ExpectedRecipients []string // Who must confirm before state transitions to accepted
}
TrackedRR wraps a dns.RR with lifecycle state for combiner confirmation tracking.
type TrackedRRInfo ¶
type TrackedRRInfo struct {
RR string `json:"rr"`
State string `json:"state"`
KeyState string `json:"key_state,omitempty"`
Reason string `json:"reason,omitempty"`
DistributionID string `json:"distribution_id"`
UpdatedAt string `json:"updated_at"`
Confirmations map[string]RRConfirmation `json:"confirmations,omitempty"`
}
TrackedRRInfo is the JSON-serializable form for dump output.
type TrackedRRset ¶
type TrackedRRset struct {
Tracked []TrackedRR
}
TrackedRRset holds a set of tracked RRs for a single RRtype.
type TransactionErrorSummary ¶
type TransactionErrorSummary struct {
DistributionID string `json:"distribution_id"`
Age string `json:"age"`
Sender string `json:"sender"`
MessageType string `json:"message_type"`
ErrorMsg string `json:"error_msg"`
QNAME string `json:"qname"`
Timestamp string `json:"timestamp"`
}
TransactionErrorSummary contains summary information about a transaction error
type TransactionPost ¶
type TransactionPost struct {
Command string `json:"command"` // "open-outgoing", "open-incoming", "errors", "error-details"
Last string `json:"last,omitempty"` // Duration filter for errors (e.g. "30m", "2h")
DistID string `json:"dist_id,omitempty"` // For error-details: specific distribution ID
}
TransactionPost represents a request to the transaction API
type TransactionResponse ¶
type TransactionResponse struct {
Time time.Time `json:"time"`
Error bool `json:"error,omitempty"`
ErrorMsg string `json:"error_msg,omitempty"`
Msg string `json:"msg,omitempty"`
Transactions []*TransactionSummary `json:"transactions,omitempty"`
Errors []*TransactionErrorSummary `json:"errors,omitempty"`
ErrorDetail *TransactionErrorSummary `json:"error_detail,omitempty"`
}
TransactionResponse represents a response from the transaction API
type TransactionSummary ¶
type TransactionSummary struct {
DistributionID string `json:"distribution_id"`
Peer string `json:"peer"` // Receiver (outgoing) or Sender (incoming)
Operation string `json:"operation"`
Zone string `json:"zone,omitempty"`
Age string `json:"age"`
CreatedAt string `json:"created_at"`
State string `json:"state,omitempty"`
}
TransactionSummary contains summary information about an open transaction
type TransportConf ¶
type TruststorePost ¶
type TruststoreResponse ¶
type TsigDetails ¶
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
TTL uint32 `yaml:"ttl"`
}
Zone struct {
Type string // "selfsub" | "self" | "sub" | ...
RRtypes []string
TTL uint32 `yaml:"ttl"`
}
Validate bool
}
type UpdatePolicyDetail ¶
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
}
This is only called from the CLI command "tdns-cli ddns sync" and uses a SIG(0) key from the command line rather than the one in the keystore. Not to be used by TDNS-SERVER.
func SendUpdate ¶
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
}
type ValidatorRequest ¶
type ValidatorRequest struct {
Qname string
RRset *core.RRset
Response chan ValidatorResponse
}
type ValidatorResponse ¶
type VerificationInfo ¶
type ZoneAgentData ¶
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
DelegationBackend string `yaml:"delegation-backend" mapstructure:"delegation-backend"` // named backend for child delegation data
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
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 *core.ConcurrentMap[string, int]
ApexLen int
// RRs RRArray
Data *core.ConcurrentMap[string, OwnerData]
MP *ZoneMPExtension // Multi-provider state; nil for non-MP zones
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
FirstZoneLoad bool // true until first zone data has been loaded
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
DelegationBackend DelegationBackend // parent-side: backend for storing child delegation data
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
// RemoteDNSKEYs holds DNSKEY RRs from other signers (multi-signer mode 4).
// These are DNSKEYs found in the incoming zone that do not match keys in our
// local keystore. They are preserved across resignings and merged into the
// DNSKEY RRset during PublishDnskeyRRs().
RemoteDNSKEYs []dns.RR
// OnFirstLoad holds one-shot callbacks executed after the zone's first successful load.
// Apps register these before RefreshEngine starts, and RefreshEngine clears the slice
// after executing them. Protected by zd.mu.
OnFirstLoad []func(*ZoneData)
// contains filtered or unexported fields
}
func FindZone ¶
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 (*ZoneData) AddCombinerData ¶
AddCombinerData adds or updates local RRsets for the zone from a specific agent. Contributions are stored per-agent so that updates from different agents are accumulated (not replaced). The merged result is then written to CombinerData. senderID identifies the contributing agent (use "local" for CLI-originated data).
TODO: Add local/remote isolation policy. The policy must work at the individual RR level (not owner+rrtype), because multiple agents legitimately contribute to the same owner+rrtype (e.g. NS records from different providers at the apex). A local change must not delete or modify an RR contributed by a remote agent, and vice versa. The per-agent storage in AgentContributions already provides structural isolation; policy enforcement needs to happen at the RR level.
func (*ZoneData) AddCombinerDataNG ¶
AddCombinerDataNG adds or updates local RRsets for the zone from a specific agent. The input map keys are owner names and values are slices of RR strings. senderID identifies the contributing agent (use "" for CLI-originated data).
func (*ZoneData) AddOwner ¶
XXX: This MUST ONLY be called from the ZoneUpdater, due to locking issues
func (*ZoneData) AgentJWKKeyPrep ¶
AgentJWKKeyPrep publishes a JWK record for the agent's JOSE/HPKE long-term public keys. This provides RFC 7517 compliant public key discovery for payload encryption/signing.
NOTE: This is separate from SIG(0) keys (which use KEY records). JOSE/HPKE keys are used for CHUNK payload encryption/signing, not DNS UPDATE authentication.
Parameters:
- publishname: The name where the JWK record will be published (typically "dns.<identity>")
- kdb: The key database (unused, kept for interface compatibility)
func (*ZoneData) AgentSig0KeyPrep ¶
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 ¶
Returns approved, updatezone, error
func (*ZoneData) BestSyncScheme ¶
Find the best scheme (from the POV of the child) to sync the deletation with the parent
func (*ZoneData) BootstrapSig0KeyWithParent ¶
func (*ZoneData) BumpSerial ¶
func (zd *ZoneData) BumpSerial() (BumperResponse, error)
func (*ZoneData) BumpSerialOnly ¶
func (zd *ZoneData) BumpSerialOnly() (BumperResponse, error)
BumpSerialOnly increments the SOA serial and updates the SOA RR, but does not notify downstreams. Use when the caller will handle notification separately or when notification is not appropriate (e.g. inside a NOTIFY handler where triggering downstream NOTIFYs could cause side effects).
func (*ZoneData) CollectDynamicRRs ¶
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 ¶
Returns true if the zone data was modified.
func (*ZoneData) ComputeIndices ¶
func (zd *ZoneData) ComputeIndices()
func (*ZoneData) CreateTransportSignalRRs ¶
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 (*ZoneData) DnskeysChanged ¶
func (zd *ZoneData) DnskeysChanged(newzd *ZoneData) (bool, DelegationSyncStatus, error)
func (*ZoneData) DnskeysChangedNG ¶
func (*ZoneData) DoTransfer ¶
Return shouldTransfer, new upstream serial, error
func (*ZoneData) EnsureMP ¶
func (zd *ZoneData) EnsureMP()
EnsureMP initializes the MP extension if nil. Must be called with zd.mu held or before concurrent access begins.
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 ¶
Return updated, err
func (*ZoneData) FetchParentData ¶
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 ¶
If key not found *CachedDnskeyRRset is returned with nil value
func (*ZoneData) FindGlue ¶
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 (*ZoneData) FindSig0KeyViaDNS ¶
func (*ZoneData) FindSig0TrustedKey ¶
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 (*ZoneData) GetCombinerData ¶
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) GetKeystateError ¶
func (*ZoneData) GetKeystateOK ¶
func (*ZoneData) GetKeystateTime ¶
func (*ZoneData) GetLastKeyInventory ¶
func (zd *ZoneData) GetLastKeyInventory() *KeyInventorySnapshot
func (*ZoneData) GetOwnerNames ¶
func (*ZoneData) GetRemoteDNSKEYs ¶
func (*ZoneData) HsyncChanged ¶
func (zd *ZoneData) HsyncChanged(newzd *ZoneData) (bool, *HsyncStatus, error)
func (*ZoneData) InjectSignatureTXT ¶
func (zd *ZoneData) InjectSignatureTXT(conf *MultiProviderConf) bool
InjectSignatureTXT adds a combiner signature TXT record to the zone data. The record is placed at "hsync-signature.{zone}" to avoid conflicts with apex TXT records. Returns true if the signature was injected.
func (*ZoneData) IsChildDelegation ¶
XXX: Is qname the name of a zone cut for a child zone?
func (*ZoneData) LoadDynamicZoneFile ¶
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) LocalDnskeysChanged ¶
func (zd *ZoneData) LocalDnskeysChanged(newzd *ZoneData) (bool, *DnskeyStatus, error)
LocalDnskeysChanged compares old and new DNSKEY RRsets, filtering out known remote DNSKEYs, and returns whether local DNSKEYs changed. Modeled on HsyncChanged() but operates on dns.TypeDNSKEY.
"Remote" keys are those whose key tag matches zd.RemoteDNSKEYs. Everything else in the DNSKEY RRset is "local" (from our signer).
func (*ZoneData) LocalDnskeysFromKeystate ¶
func (zd *ZoneData) LocalDnskeysFromKeystate() (bool, *DnskeyStatus, error)
LocalDnskeysFromKeystate derives local DNSKEY adds/removes from the KEYSTATE inventory rather than from the zone transfer's DNSKEY RRset. The KEYSTATE inventory (from the signer) is the authoritative source for which keys are local vs foreign. Each inventory entry's KeyRR field contains the full DNSKEY RR string, so we can build dns.RR objects directly.
Returns (changed, status, error). If KEYSTATE is unavailable (LastKeyInventory == nil), returns (false, nil, nil) — caller should suppress SYNC-DNSKEY-RRSET.
func (*ZoneData) Lock ¶
func (zd *ZoneData) Lock()
Lock and Unlock expose the mutex for code that moves to tdns-mp and can no longer access the unexported zd.mu.
func (*ZoneData) LookupAndValidateRRset ¶
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 (*ZoneData) LookupRRset ¶
func (*ZoneData) MusicSig0KeyPrep ¶
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 (*ZoneData) NotifyDownstreams ¶
func (*ZoneData) ParentSig0KeyPrep ¶
func (*ZoneData) ParseZoneFromReader ¶
func (*ZoneData) PrintApexRRs ¶
func (*ZoneData) PrintOwnerNames ¶
func (*ZoneData) PrintOwners ¶
func (zd *ZoneData) PrintOwners()
func (*ZoneData) PublishAddrRR ¶
func (*ZoneData) PublishCdsRRs ¶
func (*ZoneData) PublishCsyncRR ¶
func (*ZoneData) PublishDnskeyRRs ¶
func (zd *ZoneData) PublishDnskeyRRs(dak *DnssecKeys) error
func (*ZoneData) PublishDsyncRRs ¶
func (*ZoneData) PublishJWKFromKeyRR ¶
PublishJWKFromKeyRR publishes a JWK record by extracting the public key from a KEY RR. This is useful for migrating existing KEY records to JWK format.
Parameters:
- owner: The DNS name for the JWK record
- keyRR: The existing KEY record containing the public key
Returns error if key extraction or encoding fails.
func (*ZoneData) PublishJWKRR ¶
PublishJWKRR publishes a JWK record for the specified owner and public key. The public key is encoded to RFC 7517 JWK format and published as a JWK RR.
Parameters:
- owner: The DNS name for the JWK record (typically the agent identity)
- publicKey: The crypto.PublicKey to encode and publish
- use: The intended use ("" to omit, "sig" for signing, "enc" for encryption)
Returns error if encoding fails or zone update fails.
func (*ZoneData) PublishKeyRRs ¶
func (zd *ZoneData) PublishKeyRRs(sak *Sig0ActiveKeys) error
func (*ZoneData) PublishSvcbRR ¶
func (*ZoneData) PublishTlsaRR ¶
func (*ZoneData) PublishUriRR ¶
Example: target: ms1.music.axfr.net baseurl: https://{TARGET}/api/v1 port: 443
func (*ZoneData) QueryResponder ¶
func (*ZoneData) ReadZoneData ¶
func (*ZoneData) ReadZoneFile ¶
func (*ZoneData) ReloadZone ¶
func (*ZoneData) RemoveCombinerDataByRRtype ¶
func (zd *ZoneData) RemoveCombinerDataByRRtype(senderID string, owner string, rrtype uint16) ([]string, error)
RemoveCombinerDataByRRtype removes all RRs of a given type from an agent's contributions for a specific owner. Used for ClassANY delete semantics. Returns the list of RR strings that were removed.
func (*ZoneData) RemoveCombinerDataNG ¶
func (zd *ZoneData) RemoveCombinerDataNG(senderID string, data map[string][]string) ([]string, error)
RemoveCombinerDataNG removes specific RRs from the agent's contributions. Input: senderID identifies the agent, data maps owner → RR strings (ClassINET format). Returns the list of RR strings that were actually removed. If an RR was already absent, it is not included in the returned list (true no-op detection).
func (*ZoneData) ReplaceCombinerDataByRRtype ¶
func (zd *ZoneData) ReplaceCombinerDataByRRtype(senderID, owner string, rrtype uint16, newRRs []dns.RR) (applied []string, removed []string, changed bool, err error)
ReplaceCombinerDataByRRtype atomically replaces an agent's contributions for a specific owner+rrtype with a new set of RRs. Returns the lists of actually added and removed RR strings, plus whether any change occurred. Used for "replace" operation semantics at the combiner level.
func (*ZoneData) RepopulateDynamicRRs ¶
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) RequestAndWaitForEdits ¶
RequestAndWaitForEdits sends an RFI EDITS to the combiner and waits for the contributions response. Applies the received records to the SynchedDataEngine as confirmed data (the combiner already has them).
Modeled on RequestAndWaitForKeyInventory.
func (*ZoneData) RequestAndWaitForKeyInventory ¶
RequestAndWaitForKeyInventory sends an RFI KEYSTATE to the signer and waits for the inventory response. Uses the inventory to populate zd.RemoteDNSKEYs by matching foreign key tags against the actual DNSKEY RRset in the zone.
Sets zd.KeystateOK/KeystateError/KeystateTime to reflect success or failure. KEYSTATE failure is an error condition — the agent depends on KEYSTATE for DNSKEY classification and must not guess when it's unavailable.
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 (*ZoneData) SetKeystateError ¶
func (*ZoneData) SetKeystateOK ¶
func (*ZoneData) SetKeystateTime ¶
func (*ZoneData) SetLastKeyInventory ¶
func (zd *ZoneData) SetLastKeyInventory(inv *KeyInventorySnapshot)
func (*ZoneData) SetOption ¶
func (zd *ZoneData) SetOption(option ZoneOption, value bool)
func (*ZoneData) SetRemoteDNSKEYs ¶
func (*ZoneData) SetupZoneSigning ¶
func (*ZoneData) SetupZoneSync ¶
func (zd *ZoneData) SetupZoneSync(delsyncq chan<- DelegationSyncRequest) error
func (*ZoneData) ShowNsecChain ¶
func (*ZoneData) Sig0KeyPreparation ¶
func (*ZoneData) SignZone ¶
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) 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 (*ZoneData) UnpublishCdsRRs ¶
UnpublishCdsRRs removes the CDS RRset from the zone apex.
func (*ZoneData) UnpublishCsyncRR ¶
func (*ZoneData) UnpublishDsyncRRs ¶
func (*ZoneData) UnpublishKeyRRs ¶
func (*ZoneData) UnpublishSvcbRR ¶
func (*ZoneData) UnpublishTlsaRR ¶
func (*ZoneData) UnpublishUriRR ¶
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 ¶
ValidateHsyncRRset checks that HSYNC3 and HSYNCPARAM records exist at the zone apex and that the HSYNCPARAM has valid keys. With HSYNCPARAM, NSmgmt is in a single record so per-RR consistency checks are unnecessary. Returns true if both record types exist and are valid, false otherwise. error is non-nil for errors other than the records not existing.
func (*ZoneData) ValidateRRset ¶
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 (*ZoneData) WriteDynamicZoneFile ¶
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) XXfindServerTSYNCRRset ¶
findServerTSYNCRRset returns a TSYNC RRset from any owner under this zone that starts with _dns.
func (*ZoneData) ZoneFileName ¶
ZoneFileName returns the path to use for this zone's file. Only zones with zonefile: set (in config) are written to disk; autozones and secondaries without zonefile are not persisted.
func (*ZoneData) ZoneTransferIn ¶
func (*ZoneData) ZoneTransferOut ¶
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
// Tracking stores per-RR lifecycle state parallel to Repo.
// Accessed only from the SynchedDataEngine goroutine.
// Structure: zone → agentId → rrtype → TrackedRRset
Tracking map[ZoneName]map[AgentId]map[uint16]*TrackedRRset
// PendingRemoteConfirms maps a combiner distID (generated by this remote agent)
// to the originating agent's distID and sender identity. When the combiner confirms
// the remote agent's enqueue, this mapping is used to send the final confirmation
// back to the originating agent with the correct originating distID.
PendingRemoteConfirms map[string]*PendingRemoteConfirmation
// contains filtered or unexported fields
}
func NewZoneDataRepo ¶
func NewZoneDataRepo() (*ZoneDataRepo, error)
func (*ZoneDataRepo) AddConfirmedRR ¶
func (zdr *ZoneDataRepo) AddConfirmedRR(zone ZoneName, agentID AgentId, rr dns.RR)
AddConfirmedRR adds a single RR to the repo and tracking as RRStateAccepted. Used to hydrate the SDE with pre-confirmed data from the combiner (RFI EDITS).
func (*ZoneDataRepo) EvaluateUpdate ¶
func (zdr *ZoneDataRepo) EvaluateUpdate(synchedDataUpdate *SynchedDataUpdate) (bool, string, error)
func (*ZoneDataRepo) MarkRRsPending ¶
func (zdr *ZoneDataRepo) MarkRRsPending(zone ZoneName, agent AgentId, update *ZoneUpdate, distID string, recipients []string)
MarkRRsPending marks all RRs in a ZoneUpdate as pending with the given distribution ID. Called after successful enqueue for combiner delivery. recipients is the list of expected confirmation sources (combiner + agents) for this distID. The RR transitions to accepted only after ALL recipients have confirmed.
For ClassINET RRs: marks as RRStatePending (addition awaiting confirmation). For ClassNONE RRs: finds the matching existing tracked RR and marks it as RRStatePendingRemoval. For ClassANY RRs: marks all tracked RRs for the rrtype as RRStatePendingRemoval.
func (*ZoneDataRepo) ProcessConfirmation ¶
func (zdr *ZoneDataRepo) ProcessConfirmation(detail *ConfirmationDetail, msgQs *MsgQs)
ProcessConfirmation updates tracked RR states based on combiner confirmation feedback. For additions: Pending → Accepted or Rejected. For deletions: PendingRemoval → Removed (and the RR is actually deleted from the ZoneDataRepo). If a PendingRemoval RR appears in the rejected list, it transitions back to Accepted.
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 ZoneDsyncResponse ¶
type ZoneMPExtension ¶
type ZoneMPExtension struct {
CombinerData *core.ConcurrentMap[string, OwnerData]
UpstreamData *core.ConcurrentMap[string, OwnerData] // Original upstream apex data (combiner NS fallback)
MPdata *MPdata // Multi-provider membership/signing state; nil = not MP
// AgentContributions stores per-agent contributions for the combiner.
// Key: agentID (e.g. "agent.alpha.dnslab."), Value: map[owner]map[rrtype]core.RRset
// When merging, all agents' contributions for the same owner/rrtype are combined
// into a single RRset in CombinerData.
AgentContributions map[string]map[string]map[uint16]core.RRset
// PersistContributions is set by the combiner at init time to persist an agent's
// contributions to the snapshot table after every write. Non-combiner apps leave it nil.
// Args: zone, senderID, agent's contributions (owner → rrtype → RRset).
PersistContributions func(string, string, map[string]map[uint16]core.RRset) error
// LastKeyInventory stores the most recent KEYSTATE inventory received from the signer.
// Used for diagnostics (CLI show-key-inventory command).
LastKeyInventory *KeyInventorySnapshot
// LocalDNSKEYs holds DNSKEY RRs that the signer classifies as local (not foreign).
// Derived from KEYSTATE inventory. Used to compute adds/removes on DNSKEY updates.
LocalDNSKEYs []dns.RR
// KEYSTATE health tracking — we depend on KEYSTATE for DNSKEY classification.
// Failure is an error condition that must be visible to the operator.
KeystateOK bool // true after successful KEYSTATE exchange
KeystateError string // error message from last failed attempt (empty on success)
KeystateTime time.Time // time of last KEYSTATE attempt
}
ZoneMPExtension holds multi-provider state for a zone. Access via zd.MP.
NOTE: This is an MP type that lives in tdns (not tdns-mp) because it is a field of ZoneData. tdns-mp code accesses these fields via zd.MP.
type ZoneOption ¶
type ZoneOption uint8
const ( OptDelSyncParent ZoneOption = iota + 1 OptDelSyncChild OptAllowUpdates OptAllowChildUpdates OptAllowEdits // Dynamically et if app=combiner and zone contains a HSYNC RRset OptFoldCase OptBlackLies OptDontPublishKey OptDontPublishJWK OptOnlineSigning OptInlineSigning OptMultiProvider OptDirty OptFrozen OptAutomaticZone // OptServerSvcb OptAddTransportSignal OptCatalogZone OptCatalogMemberAutoCreate OptCatalogMemberAutoDelete OptMPManualApproval OptMultiSigner // Dynamically set by signer when HSYNC shows multiple signers OptMPNotListedErr // Warning: zone has HSYNC3 but we are not listed as a provider OptMPDisallowEdits // Zone is signed but we are not a signer: no edits allowed )
type ZoneOptionHandler ¶
type ZoneOptionHandler func(zname string, options map[ZoneOption]bool)
ZoneOptionHandler is a callback invoked during ParseZones when a zone has a specific option set. Handlers are registered before ParseZones runs and fire synchronously during parsing.
Parameters:
- zname: the FQDN zone name
- options: all parsed options for this zone (read-only)
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
Wait bool // wait for refresh to complete before responding
Response chan RefresherResponse
}
type ZoneResponse ¶
type ZoneUpdate ¶
type ZoneUpdate struct {
Zone ZoneName
AgentId AgentId
ZoneClass string // "mp" (default) or "provider"
RRsets map[uint16]core.RRset // remote updates are only per RRset (i.e. full replace)
RRs []dns.RR // local updates can be per RR
Operations []core.RROperation // explicit operations (takes precedence over RRsets/RRs)
Publish *core.PublishInstruction // KEY/CDS publication instruction for combiner
}
type ZonefileDelegationBackend ¶
type ZonefileDelegationBackend struct {
// contains filtered or unexported fields
}
func (*ZonefileDelegationBackend) ApplyChildUpdate ¶
func (b *ZonefileDelegationBackend) ApplyChildUpdate(parentZone string, ur UpdateRequest) error
ApplyChildUpdate persists the update to the DB (as source of truth) and then regenerates the child's zone file fragment from the DB state.
func (*ZonefileDelegationBackend) GetDelegationData ¶
func (*ZonefileDelegationBackend) ListChildren ¶
func (b *ZonefileDelegationBackend) ListChildren(parentZone string) ([]string, error)
func (*ZonefileDelegationBackend) Name ¶
func (b *ZonefileDelegationBackend) Name() string
Source Files
¶
- acceptfunc.go
- agent_authorization.go
- agent_discovery.go
- agent_discovery_common.go
- agent_policy.go
- agent_setup.go
- agent_structs.go
- agent_utils.go
- api_structs.go
- api_utils.go
- apiclient.go
- apihandler_agent.go
- apihandler_agent_distrib.go
- apihandler_agent_router.go
- apihandler_auth.go
- apihandler_catalog.go
- apihandler_combiner.go
- apihandler_combiner_distrib.go
- apihandler_funcs.go
- apihandler_multisigner.go
- apihandler_transaction.go
- apihandler_zone.go
- apirouters.go
- auth_utils.go
- base32_utils.go
- catalog.go
- childsync_utils.go
- chunk_query_handler.go
- chunk_store.go
- combiner_chunk.go
- combiner_msg_handler.go
- combiner_peer.go
- combiner_utils.go
- config.go
- config_validate.go
- daemon_utils.go
- db.go
- db_combiner_contributions.go
- db_combiner_edits.go
- db_combiner_publish_instructions.go
- db_hsync.go
- db_outgoing_serial.go
- db_schema.go
- db_schema_hsync.go
- debughandlers.go
- defaultqueryhandlers.go
- defaults.go
- delegation_backend.go
- delegation_backend_db.go
- delegation_backend_direct.go
- delegation_backend_zonefile.go
- delegation_sync.go
- delegation_utils.go
- dnslookup.go
- dnssec_validate.go
- dnsutils.go
- do53.go
- doh.go
- doq.go
- dot.go
- dsync_lookup.go
- dynamic_zones.go
- enums.go
- error_journal.go
- global.go
- gossip.go
- hsync_beat.go
- hsync_hello.go
- hsync_infra_beat.go
- hsync_transport.go
- hsync_utils.go
- hsyncengine.go
- imr_helpers.go
- imrengine.go
- key_state_worker.go
- keybootstrapper.go
- keys_cmd.go
- keystate.go
- keystore.go
- logging.go
- main_initfuncs.go
- musicstructs.go
- notifier.go
- notifyreporter.go
- notifyresponder.go
- ops_a_aaaa.go
- ops_cds.go
- ops_csync.go
- ops_dnskey.go
- ops_dsync.go
- ops_hsync.go
- ops_jwk.go
- ops_key.go
- ops_svcb.go
- ops_svcb_tlsa.go
- ops_svcb_transport.go
- ops_tlsa.go
- ops_uri.go
- option_handlers.go
- parentsync_bootstrap.go
- parentsync_leader.go
- parseconfig.go
- parseoptions.go
- provider_groups.go
- queryresponder.go
- readkey.go
- refreshengine.go
- registration.go
- resigner.go
- rfc3597.go
- rfc9567.go
- rr_print.go
- rrset_utils.go
- rrtypestore.go
- sanitize_data.go
- scanner.go
- scanner_csync.go
- sig0_utils.go
- sig0_validate.go
- sign.go
- signer_msg_handler.go
- signer_peer.go
- signer_transport.go
- structs.go
- svcb_defs.go
- syncheddataengine.go
- truststore.go
- truststore_verify.go
- tsig_utils.go
- tsignal.go
- ttl_utils.go
- tty_utils.go
- updateresponder.go
- validatorengine.go
- wrappers.go
- zone_updater.go
- zone_utils.go