From d974738f2ae1aaa425aa52075c18dba3de4dcd26 Mon Sep 17 00:00:00 2001 From: devStorm <59678453+developStorm@users.noreply.github.com> Date: Tue, 22 Oct 2024 15:20:02 -0700 Subject: [PATCH 1/4] feat: base ans getter for all answer types --- makefile | 5 +- src/zdns/answers.go | 6 ++ src/zdns/answers_generate.go | 103 +++++++++++++++++++++++++++++++++++ src/zdns/answers_helper.go | 33 +++++++++++ 4 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 src/zdns/answers_generate.go create mode 100644 src/zdns/answers_helper.go diff --git a/makefile b/makefile index 395d412f..ffff13ee 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,9 @@ all: zdns -zdns: +generate: + go generate ./... + +zdns: generate go build -o zdns clean: diff --git a/src/zdns/answers.go b/src/zdns/answers.go index c2bf2754..45ac2c54 100644 --- a/src/zdns/answers.go +++ b/src/zdns/answers.go @@ -24,6 +24,12 @@ import ( "github.com/miekg/dns" ) +//go:generate go run answers_generate.go + +type WithBaseAnswer interface { + BaseAns() *Answer +} + type Answer struct { TTL uint32 `json:"ttl" groups:"ttl,normal,long,trace"` Type string `json:"type,omitempty" groups:"short,normal,long,trace"` diff --git a/src/zdns/answers_generate.go b/src/zdns/answers_generate.go new file mode 100644 index 00000000..5213396b --- /dev/null +++ b/src/zdns/answers_generate.go @@ -0,0 +1,103 @@ +//go:build ignore +// +build ignore + +// answers_generate.go is meant to run with go generate. It will use +// go/{importer,types} to track down all the DNS answer struct types that embed +// the Answer struct. Then for each type, it will generate extraction and conversion +// methods based on the struct tags. The generated source is written to answers_common.go, +// and is meant to be checked into git. +package main + +import ( + "bytes" + "go/format" + "go/types" + "log" + "os" + "text/template" + + "golang.org/x/tools/go/packages" +) + +var packageHdr = ` +// Code generated by "go run answers_generate.go"; DO NOT EDIT. + +package zdns + +` + +var baseAnsFunc = template.Must(template.New("answerHeaderFunc").Parse(` +func (ans *Answer) BaseAns() *Answer { return ans } +{{range .}} func (ans *{{.}}) BaseAns() *Answer { return &ans.Answer } +{{end}} + +`)) + +func main() { + // Import and type-check the package + pkg, err := loadModule("github.com/zmap/zdns/src/zdns") + fatalIfErr(err) + scope := pkg.Scope() + + // Collect all answer types (*X) that embed the Answer struct + var answerTypes []string + for _, name := range scope.Names() { + o := scope.Lookup(name) + if o == nil || !o.Exported() { + continue + } + if _, isAnswerType := getAnswerType(o.Type(), scope); isAnswerType { + answerTypes = append(answerTypes, o.Name()) + } + } + + b := &bytes.Buffer{} + b.WriteString(packageHdr) + + // Generate answerHeaderFunc + fatalIfErr(baseAnsFunc.Execute(b, answerTypes)) + + // Format the generated code + res, err := format.Source(b.Bytes()) + if err != nil { + b.WriteTo(os.Stderr) + log.Fatal(err) + } + + // Write the result to answers_helper.go + f, err := os.Create("answers_helper.go") + fatalIfErr(err) + defer f.Close() + f.Write(res) +} + +// loadModule retrieves package description for a given module. +func loadModule(name string) (*types.Package, error) { + conf := packages.Config{Mode: packages.NeedTypes | packages.NeedTypesInfo} + pkgs, err := packages.Load(&conf, name) + if err != nil { + return nil, err + } + return pkgs[0].Types, nil +} + +// getAnswerType checks if a type embeds the Answer struct and returns true if it does. +func getAnswerType(t types.Type, scope *types.Scope) (*types.Struct, bool) { + st, ok := t.Underlying().(*types.Struct) + if !ok { + return nil, false + } + if st.NumFields() == 0 { + return nil, false + } + if st.Field(0).Type() == scope.Lookup("Answer").Type() { + return st, true + } + return nil, false +} + +func fatalIfErr(err error) { + if err != nil { + log.Fatal(err) + } +} diff --git a/src/zdns/answers_helper.go b/src/zdns/answers_helper.go new file mode 100644 index 00000000..ccce12e9 --- /dev/null +++ b/src/zdns/answers_helper.go @@ -0,0 +1,33 @@ +// Code generated by "go run answers_generate.go"; DO NOT EDIT. + +package zdns + +func (ans *Answer) BaseAns() *Answer { return ans } +func (ans *AFSDBAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *CAAAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *CERTAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *CSYNCAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *DNSKEYAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *DSAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *GPOSAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *HINFOAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *HIPAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *LOCAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *MINFOAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *NAPTRAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *NSEC3Answer) BaseAns() *Answer { return &ans.Answer } +func (ans *NSEC3ParamAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *NSECAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *PXAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *PrefAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *RPAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *RRSIGAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *SMIMEAAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *SOAAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *SRVAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *SSHFPAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *SVCBAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *TALINKAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *TKEYAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *TLSAAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans *URIAnswer) BaseAns() *Answer { return &ans.Answer } From 1661db380ad22d172d4287dea5e324fb3b1e5b2b Mon Sep 17 00:00:00 2001 From: devStorm <59678453+developStorm@users.noreply.github.com> Date: Tue, 22 Oct 2024 16:45:59 -0700 Subject: [PATCH 2/4] refactor: cache now expect WithBaseAnswer values --- src/zdns/answers_generate.go | 5 +- src/zdns/answers_helper.go | 58 ++++++++++---------- src/zdns/cache.go | 100 ++++++++++++++++++----------------- 3 files changed, 82 insertions(+), 81 deletions(-) diff --git a/src/zdns/answers_generate.go b/src/zdns/answers_generate.go index 5213396b..a271d291 100644 --- a/src/zdns/answers_generate.go +++ b/src/zdns/answers_generate.go @@ -27,10 +27,9 @@ package zdns ` var baseAnsFunc = template.Must(template.New("answerHeaderFunc").Parse(` -func (ans *Answer) BaseAns() *Answer { return ans } -{{range .}} func (ans *{{.}}) BaseAns() *Answer { return &ans.Answer } +func (ans Answer) BaseAns() *Answer { return &ans } +{{range .}} func (ans {{.}}) BaseAns() *Answer { return &ans.Answer } {{end}} - `)) func main() { diff --git a/src/zdns/answers_helper.go b/src/zdns/answers_helper.go index ccce12e9..699802b6 100644 --- a/src/zdns/answers_helper.go +++ b/src/zdns/answers_helper.go @@ -2,32 +2,32 @@ package zdns -func (ans *Answer) BaseAns() *Answer { return ans } -func (ans *AFSDBAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *CAAAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *CERTAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *CSYNCAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *DNSKEYAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *DSAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *GPOSAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *HINFOAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *HIPAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *LOCAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *MINFOAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *NAPTRAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *NSEC3Answer) BaseAns() *Answer { return &ans.Answer } -func (ans *NSEC3ParamAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *NSECAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *PXAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *PrefAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *RPAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *RRSIGAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *SMIMEAAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *SOAAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *SRVAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *SSHFPAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *SVCBAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *TALINKAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *TKEYAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *TLSAAnswer) BaseAns() *Answer { return &ans.Answer } -func (ans *URIAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans Answer) BaseAns() *Answer { return &ans } +func (ans AFSDBAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans CAAAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans CERTAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans CSYNCAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans DNSKEYAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans DSAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans GPOSAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans HINFOAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans HIPAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans LOCAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans MINFOAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans NAPTRAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans NSEC3Answer) BaseAns() *Answer { return &ans.Answer } +func (ans NSEC3ParamAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans NSECAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans PXAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans PrefAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans RPAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans RRSIGAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans SMIMEAAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans SOAAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans SRVAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans SSHFPAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans SVCBAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans TALINKAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans TKEYAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans TLSAAnswer) BaseAns() *Answer { return &ans.Answer } +func (ans URIAnswer) BaseAns() *Answer { return &ans.Answer } diff --git a/src/zdns/cache.go b/src/zdns/cache.go index e6ddd054..d88fca54 100644 --- a/src/zdns/cache.go +++ b/src/zdns/cache.go @@ -39,7 +39,7 @@ type CachedResult struct { } type TimedAnswer struct { - Answer Answer + Answer WithBaseAnswer ExpiresAt time.Time } @@ -140,7 +140,7 @@ func (s *Cache) getCachedResult(q Question, ns *NameServer, isAuthority bool, de for _, cachedAnswer := range cachedRes.Answers { if cachedAnswer.ExpiresAt.Before(now) { partiallyExpired = true - s.VerboseLog(depth+2, "expiring cache answer ", cachedAnswer.Answer.Name) + s.VerboseLog(depth+2, "expiring cache answer ", cachedAnswer.Answer.BaseAns().Name) } else { retv.Answers = append(retv.Answers, cachedAnswer.Answer) } @@ -148,7 +148,7 @@ func (s *Cache) getCachedResult(q Question, ns *NameServer, isAuthority bool, de for _, cachedAuthority := range cachedRes.Authorities { if cachedAuthority.ExpiresAt.Before(now) { partiallyExpired = true - s.VerboseLog(depth+2, "expiring cache authority ", cachedAuthority.Answer.Name) + s.VerboseLog(depth+2, "expiring cache authority ", cachedAuthority.Answer.BaseAns().Name) } else { retv.Authorities = append(retv.Authorities, cachedAuthority.Answer) } @@ -156,7 +156,7 @@ func (s *Cache) getCachedResult(q Question, ns *NameServer, isAuthority bool, de for _, cachedAdditional := range cachedRes.Additionals { if cachedAdditional.ExpiresAt.Before(now) { partiallyExpired = true - s.VerboseLog(depth+2, "expiring cache additional ", cachedAdditional.Answer.Name) + s.VerboseLog(depth+2, "expiring cache additional ", cachedAdditional.Answer.BaseAns().Name) } else { retv.Additional = append(retv.Additional, cachedAdditional.Answer) } @@ -169,68 +169,68 @@ func (s *Cache) getCachedResult(q Question, ns *NameServer, isAuthority bool, de return nil, false, false } - s.VerboseLog(depth+2, "Cache hit for ", q.Name, ": ", retv) + s.VerboseLog(depth+2, "Cache hit for ", q.Name, ": ", *retv) return retv, true, partiallyExpired } -func isCacheableType(ans *Answer) bool { +func isCacheableType(ans WithBaseAnswer) bool { // only cache records that can help prevent future iteration: A(AAA), NS, (C|D)NAME. // This will prevent some entries that will never help future iteration (e.g., PTR) // from causing unnecessary cache evictions. //// TODO: this is overly broad right now and will unnecessarily cache some leaf A/AAAA records. However, - return ans.RrType == dns.TypeA || ans.RrType == dns.TypeAAAA || ans.RrType == dns.TypeNS || ans.RrType == dns.TypeDNAME || ans.RrType == dns.TypeCNAME + + rrType := ans.BaseAns().RrType + return rrType == dns.TypeA || rrType == dns.TypeAAAA || rrType == dns.TypeNS || rrType == dns.TypeDNAME || rrType == dns.TypeCNAME || rrType == dns.TypeDS || rrType == dns.TypeDNSKEY } func (s *Cache) buildCachedResult(res *SingleQueryResult, depth int, layer string) *CachedResult { now := time.Now() cachedRes := CachedResult{} cachedRes.Answers = make([]TimedAnswer, 0, len(res.Answers)) - for _, a := range res.Answers { - castAns, ok := a.(Answer) + + var getExpirationForSafeAnswer = func(a any) (WithBaseAnswer, time.Time) { + castAns, ok := a.(WithBaseAnswer) if !ok { - s.VerboseLog(depth+1, "SafeAddCachedAnswer: unable to cast to Answer: ", layer, ": ", a) - continue + s.VerboseLog(depth+1, "SafeAddCachedAnswer: unable to cast to WithBaseAnswer: ", layer, ": ", a) + return nil, time.Time{} } - if !isCacheableType(&castAns) { + + if !isCacheableType(castAns) { s.VerboseLog(depth+1, "SafeAddCachedAnswer: ignoring non-cacheable type: ", layer, ": ", castAns) - continue + return nil, time.Time{} + } + + return castAns, now.Add(time.Duration(castAns.BaseAns().TTL) * time.Second) + } + + for _, a := range res.Answers { + castAns, expiresAt := getExpirationForSafeAnswer(a) + if castAns != nil { + cachedRes.Answers = append(cachedRes.Answers, TimedAnswer{ + Answer: castAns, + ExpiresAt: expiresAt, + }) } - cachedRes.Answers = append(cachedRes.Answers, TimedAnswer{ - Answer: castAns, - ExpiresAt: now.Add(time.Duration(castAns.TTL) * time.Second), - }) } cachedRes.Authorities = make([]TimedAnswer, 0, len(res.Authorities)) for _, a := range res.Authorities { - castAns, ok := a.(Answer) - if !ok { - s.VerboseLog(depth+1, "SafeAddCachedAnswer: unable to cast to Answer: ", layer, ": ", a) - continue - } - if !isCacheableType(&castAns) { - s.VerboseLog(depth+1, "SafeAddCachedAnswer: ignoring non-cacheable type: ", layer, ": ", castAns) - continue + castAns, expiresAt := getExpirationForSafeAnswer(a) + if castAns != nil { + cachedRes.Authorities = append(cachedRes.Authorities, TimedAnswer{ + Answer: castAns, + ExpiresAt: expiresAt, + }) } - cachedRes.Authorities = append(cachedRes.Authorities, TimedAnswer{ - Answer: castAns, - ExpiresAt: now.Add(time.Duration(castAns.TTL) * time.Second), - }) } cachedRes.Additionals = make([]TimedAnswer, 0, len(res.Additional)) for _, a := range res.Additional { - castAns, ok := a.(Answer) - if !ok { - s.VerboseLog(depth+1, "SafeAddCachedAnswer: unable to cast to Answer: ", layer, ": ", a) - continue - } - if !isCacheableType(&castAns) { - s.VerboseLog(depth+1, "SafeAddCachedAnswer: ignoring non-cacheable type: ", layer, ": ", castAns) - continue + castAns, expiresAt := getExpirationForSafeAnswer(a) + if castAns != nil { + cachedRes.Additionals = append(cachedRes.Additionals, TimedAnswer{ + Answer: castAns, + ExpiresAt: expiresAt, + }) } - cachedRes.Additionals = append(cachedRes.Additionals, TimedAnswer{ - Answer: castAns, - ExpiresAt: now.Add(time.Duration(castAns.TTL) * time.Second), - }) } return &cachedRes } @@ -242,16 +242,17 @@ func (s *Cache) SafeAddCachedAnswer(q Question, res *SingleQueryResult, ns *Name } // check for poison for _, a := range util.Concat(res.Answers, res.Authorities, res.Additional) { - castAns, ok := a.(Answer) + castAns, ok := a.(WithBaseAnswer) if !ok { // if we can't cast, it won't be added to the cache. We'll log in buildCachedResult continue } - if ok, _ = nameIsBeneath(castAns.Name, layer); !ok { + baseAns := castAns.BaseAns() + if ok, _ = nameIsBeneath(baseAns.Name, layer); !ok { if len(nsString) > 0 { - s.VerboseLog(depth+1, "SafeAddCachedAnswer: detected poison: ", castAns.Name, "(", castAns.Type, "): @", nsString, ", ", layer, " , aborting") + s.VerboseLog(depth+1, "SafeAddCachedAnswer: detected poison: ", baseAns.Name, "(", baseAns.Type, "): @", nsString, ", ", layer, " , aborting") } else { - s.VerboseLog(depth+1, "SafeAddCachedAnswer: detected poison: ", castAns.Name, "(", castAns.Type, "): ", layer, " , aborting") + s.VerboseLog(depth+1, "SafeAddCachedAnswer: detected poison: ", baseAns.Name, "(", baseAns.Type, "): ", layer, " , aborting") } return } @@ -285,15 +286,16 @@ func (s *Cache) SafeAddCachedAuthority(res *SingleQueryResult, ns *NameServer, d } authName := "" for _, auth := range res.Authorities { - castAuth, ok := auth.(Answer) + castAuth, ok := auth.(WithBaseAnswer) if !ok { // if we can't cast, it won't be added to the cache. We'll log in buildCachedResult continue } + baseAns := castAuth.BaseAns() if len(authName) == 0 { - authName = castAuth.Name - } else if authName != castAuth.Name { - s.VerboseLog(depth+1, "SafeAddCachedAuthority: multiple authority names: ", layer, ": ", authName, " ", castAuth.Name, " , aborting") + authName = baseAns.Name + } else if authName != baseAns.Name { + s.VerboseLog(depth+1, "SafeAddCachedAuthority: multiple authority names: ", layer, ": ", authName, " ", baseAns.Name, " , aborting") return } } From 183a12d87e5abbc2e665687aaac000267002306f Mon Sep 17 00:00:00 2001 From: devStorm <59678453+developStorm@users.noreply.github.com> Date: Tue, 22 Oct 2024 16:59:31 -0700 Subject: [PATCH 3/4] patch: generate should be phony target --- makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile b/makefile index ffff13ee..9e4cd62f 100644 --- a/makefile +++ b/makefile @@ -40,5 +40,5 @@ benchmark: zdns ci: zdns lint test integration-tests license-check -.PHONY: zdns clean test integration-tests lint ci license-check benchmark +.PHONY: generate zdns clean test integration-tests lint ci license-check benchmark From 414dc597aef9f15ac81fe02f209aa701351096de Mon Sep 17 00:00:00 2001 From: devStorm <59678453+developStorm@users.noreply.github.com> Date: Fri, 25 Oct 2024 22:20:40 -0700 Subject: [PATCH 4/4] chore: add license header --- src/zdns/answers_generate.go | 91 ++++++++++++++++++++++++++++++++++++ src/zdns/answers_helper.go | 45 ++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/src/zdns/answers_generate.go b/src/zdns/answers_generate.go index a271d291..a57653ab 100644 --- a/src/zdns/answers_generate.go +++ b/src/zdns/answers_generate.go @@ -1,6 +1,52 @@ //go:build ignore // +build ignore +/* + * ZDNS Copyright 2024 Regents of the University of Michigan + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/* + * BSD 3-Clause License + + * Copyright (c) 2009, The Go Authors. Extensions copyright (c) 2011, Miek Gieben. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + // answers_generate.go is meant to run with go generate. It will use // go/{importer,types} to track down all the DNS answer struct types that embed // the Answer struct. Then for each type, it will generate extraction and conversion @@ -21,6 +67,51 @@ import ( var packageHdr = ` // Code generated by "go run answers_generate.go"; DO NOT EDIT. +/* + * ZDNS Copyright 2024 Regents of the University of Michigan + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/* + * BSD 3-Clause License + + * Copyright (c) 2009, The Go Authors. Extensions copyright (c) 2011, Miek Gieben. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ package zdns diff --git a/src/zdns/answers_helper.go b/src/zdns/answers_helper.go index 699802b6..d754293b 100644 --- a/src/zdns/answers_helper.go +++ b/src/zdns/answers_helper.go @@ -1,4 +1,49 @@ // Code generated by "go run answers_generate.go"; DO NOT EDIT. +/* + * ZDNS Copyright 2024 Regents of the University of Michigan + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/* + * BSD 3-Clause License + + * Copyright (c) 2009, The Go Authors. Extensions copyright (c) 2011, Miek Gieben. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ package zdns