package checker import ( "context" "fmt" sdk "git.happydns.org/checker-sdk-go/checker" ) type dnameCoexistenceRule struct{} func (dnameCoexistenceRule) Name() string { return "dname_coexistence" } func (dnameCoexistenceRule) Description() string { return "Flags RRsets that sit at the same owner as a DNAME (RFC 6672 §2.3)." } func (dnameCoexistenceRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, _ sdk.CheckerOptions) []sdk.CheckState { data, errState := loadAlias(ctx, obs) if errState != nil { return errState } if !apexKnown(data) { return skipped("apex lookup failed") } if len(data.DNAMESubstitutions) == 0 { return skipped("no DNAME in chain") } if len(data.DNAMECoexistence) == 0 { return okState(data.Owner, "all DNAME nodes have no sibling records") } var out []sdk.CheckState for owner, coexisting := range data.DNAMECoexistence { for _, rr := range coexisting { out = append(out, withHint(sdk.CheckState{ Status: sdk.StatusCrit, Subject: owner, Message: fmt.Sprintf("%s and DNAME both exist at %s (RFC 6672 §2.3)", rr.Type, owner), Code: rr.Type, }, "Remove the sibling record or move it under a different label; a DNAME owner must not carry other data.")) } } return out } type cnameCoexistenceRule struct{} func (cnameCoexistenceRule) Name() string { return "cname_coexistence" } func (cnameCoexistenceRule) Description() string { return "Flags other RRsets that sit at the same owner as a CNAME (RFC 1034 §3.6.2 / RFC 2181 §10.1). Honours allowApexCNAME and recognizeApexFlattening." } func (cnameCoexistenceRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, opts sdk.CheckerOptions) []sdk.CheckState { data, errState := loadAlias(ctx, obs) if errState != nil { return errState } if !apexKnown(data) { return skipped("apex lookup failed") } if !data.OwnerHasCNAME { return skipped("owner has no CNAME") } if len(data.Coexisting) == 0 { return okState(data.Owner, "CNAME is the only RRset at its owner") } isApex := data.OwnerIsApex recognize := recognizeApexFlattening(opts) allow := allowApexCNAME(opts) var out []sdk.CheckState for _, rr := range data.Coexisting { // Provider-side flattening serves apex A/AAAA on a synthetic owner, // so the wire-level coexistence is intentional, not a zone bug. if isApex && recognize && data.ApexFlattening && (rr.Type == "A" || rr.Type == "AAAA") { continue } status := sdk.StatusCrit if isApex && allow { status = sdk.StatusWarn } out = append(out, withHint(sdk.CheckState{ Status: status, Subject: data.Owner, Message: fmt.Sprintf("%s and CNAME both exist at %s (RFC 1034 §3.6.2 / RFC 2181 §10.1)", rr.Type, data.Owner), Code: rr.Type, }, "Remove the sibling record or move it under a different label; a name cannot simultaneously carry a CNAME and other data.")) } if len(out) == 0 { return okState(data.Owner, "CNAME coexistence exempted by ALIAS/ANAME flattening") } return out }