Implement returning errors from the scanner
This commit is contained in:
parent
c6deba77e0
commit
06ae052c32
2
dns.go
2
dns.go
|
@ -154,7 +154,7 @@ func (s RRset) Ok() bool {
|
||||||
type Exchange struct {
|
type Exchange struct {
|
||||||
Request *Msg // The question sent.
|
Request *Msg // The question sent.
|
||||||
Reply *Msg // The answer to the question that was sent.
|
Reply *Msg // The answer to the question that was sent.
|
||||||
Error error // If something when wrong, this contains the error.
|
ErrorMsg error // If something when wrong, this contains the error.
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNS resource records.
|
// DNS resource records.
|
||||||
|
|
|
@ -122,7 +122,7 @@ func TestParse(t *testing.T) {
|
||||||
t.Logf("`%s' should be equal to\n`%s', but is `%s'\n", i, o, rr.String())
|
t.Logf("`%s' should be equal to\n`%s', but is `%s'\n", i, o, rr.String())
|
||||||
t.Fail()
|
t.Fail()
|
||||||
} else {
|
} else {
|
||||||
t.Logf("RR is %s", rr.String())
|
t.Logf("RR is OK: `%s'", rr.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
82
zscan.go
82
zscan.go
|
@ -61,26 +61,34 @@ type Lex struct {
|
||||||
column int // column in the fil
|
column int // column in the fil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Token struct {
|
||||||
|
Rr RR // the scanned resource record
|
||||||
|
Err *ParseError // when an error occured, this is the specifics
|
||||||
|
}
|
||||||
|
|
||||||
// NewRR parses the string s and returns the RR contained in there. If the string
|
// NewRR parses the string s and returns the RR contained in there. If the string
|
||||||
// contains more than one RR, only the first is returned. If an error is detected
|
// contains more than one RR, only the first is returned. If an error is detected
|
||||||
// an error is returned.
|
// that error error is returned.
|
||||||
// If the class is not specified, the IN class is assumed. If the TTL is not
|
// If the class is not specified, the IN class is assumed. If the TTL is not
|
||||||
// specified DefaultTtl is assumed.
|
// specified DefaultTtl is assumed.
|
||||||
func NewRR(s string) (RR, error) {
|
func NewRR(s string) (RR, error) {
|
||||||
cr := make(chan RR)
|
t := make(chan Token)
|
||||||
if s[len(s)-1] != '\n' { // We need a closing newline
|
if s[len(s)-1] != '\n' { // We need a closing newline
|
||||||
go ParseZone(strings.NewReader(s+"\n"), cr)
|
go ParseZone(strings.NewReader(s+"\n"), t)
|
||||||
} else {
|
} else {
|
||||||
go ParseZone(strings.NewReader(s), cr)
|
go ParseZone(strings.NewReader(s), t)
|
||||||
}
|
}
|
||||||
r := <-cr // There are no error send as of yet
|
r := <-t
|
||||||
return r, nil // Todo: errors
|
if r.Err != nil {
|
||||||
|
return nil, r.Err
|
||||||
|
}
|
||||||
|
return r.Rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseZone reads a RFC 1035 zone from r. It returns each parsed RR on the
|
// ParseZone reads a RFC 1035 zone from r. It returns each parsed RR or on error
|
||||||
// channel cr. The channel cr is closed by ParseZone when the end of r is reached.
|
// on the channel t. The channel t is closed by ParseZone when the end of r is reached.
|
||||||
func ParseZone(r io.Reader, cr chan RR) {
|
func ParseZone(r io.Reader, t chan Token) {
|
||||||
defer close(cr)
|
defer close(t)
|
||||||
var s scanner.Scanner
|
var s scanner.Scanner
|
||||||
c := make(chan Lex)
|
c := make(chan Lex)
|
||||||
s.Init(r)
|
s.Init(r)
|
||||||
|
@ -105,9 +113,9 @@ func ParseZone(r io.Reader, cr chan RR) {
|
||||||
}
|
}
|
||||||
switch st {
|
switch st {
|
||||||
case _EXPECT_OWNER:
|
case _EXPECT_OWNER:
|
||||||
// Set the defaults here
|
// Set the defaults here
|
||||||
h.Ttl = DefaultTtl
|
h.Ttl = DefaultTtl
|
||||||
h.Class = ClassINET
|
h.Class = ClassINET
|
||||||
switch l.value {
|
switch l.value {
|
||||||
case _NEWLINE: // Empty line
|
case _NEWLINE: // Empty line
|
||||||
st = _EXPECT_OWNER
|
st = _EXPECT_OWNER
|
||||||
|
@ -115,12 +123,14 @@ func ParseZone(r io.Reader, cr chan RR) {
|
||||||
h.Name = l.token
|
h.Name = l.token
|
||||||
st = _EXPECT_OWNER_BL
|
st = _EXPECT_OWNER_BL
|
||||||
default:
|
default:
|
||||||
fmt.Printf("%s\n", &ParseError{"Error at the start", l})
|
t <- Token{Err: &ParseError{"Error at the start", l}}
|
||||||
st = _EXPECT_OWNER
|
return
|
||||||
|
//st = _EXPECT_OWNER
|
||||||
}
|
}
|
||||||
case _EXPECT_OWNER_BL:
|
case _EXPECT_OWNER_BL:
|
||||||
if l.value != _BLANK {
|
if l.value != _BLANK {
|
||||||
fmt.Printf("%s\n", &ParseError{"No blank after owner", l})
|
t <- Token{Err: &ParseError{"No blank after owner", l}}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
st = _EXPECT_ANY
|
st = _EXPECT_ANY
|
||||||
case _EXPECT_ANY:
|
case _EXPECT_ANY:
|
||||||
|
@ -131,28 +141,33 @@ func ParseZone(r io.Reader, cr chan RR) {
|
||||||
case _CLASS:
|
case _CLASS:
|
||||||
h.Class, ok = Str_class[strings.ToUpper(l.token)]
|
h.Class, ok = Str_class[strings.ToUpper(l.token)]
|
||||||
if !ok {
|
if !ok {
|
||||||
fmt.Printf("%s\n", &ParseError{"Unknown class", l})
|
t <- Token{Err: &ParseError{"Unknown class", l}}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
st = _EXPECT_ANY_NOCLASS_BL
|
st = _EXPECT_ANY_NOCLASS_BL
|
||||||
case _STRING: // TTL is this case
|
case _STRING: // TTL is this case
|
||||||
ttl, ok := strconv.Atoi(l.token)
|
ttl, ok := strconv.Atoi(l.token)
|
||||||
if ok != nil {
|
if ok != nil {
|
||||||
fmt.Printf("%s\n", &ParseError{"Not a TTL", l})
|
t <- Token{Err: &ParseError{"Not a TTL", l}}
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
h.Ttl = uint32(ttl)
|
h.Ttl = uint32(ttl)
|
||||||
}
|
}
|
||||||
st = _EXPECT_ANY_NOTTL_BL
|
st = _EXPECT_ANY_NOTTL_BL
|
||||||
default:
|
default:
|
||||||
fmt.Printf("%s\n", &ParseError{"Expecting RR type, TTL or class, not this...", l})
|
t <- Token{Err: &ParseError{"Expecting RR type, TTL or class, not this...", l}}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
case _EXPECT_ANY_NOCLASS_BL:
|
case _EXPECT_ANY_NOCLASS_BL:
|
||||||
if l.value != _BLANK {
|
if l.value != _BLANK {
|
||||||
fmt.Printf("%s\n", &ParseError{"No blank before NOCLASS", l})
|
t <- Token{Err: &ParseError{"No blank before NOCLASS", l}}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
st = _EXPECT_ANY_NOCLASS
|
st = _EXPECT_ANY_NOCLASS
|
||||||
case _EXPECT_ANY_NOTTL_BL:
|
case _EXPECT_ANY_NOTTL_BL:
|
||||||
if l.value != _BLANK {
|
if l.value != _BLANK {
|
||||||
fmt.Printf("%s\n", &ParseError{"No blank before NOTTL", l})
|
t <- Token{Err: &ParseError{"No blank before NOTTL", l}}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
st = _EXPECT_ANY_NOTTL
|
st = _EXPECT_ANY_NOTTL
|
||||||
case _EXPECT_ANY_NOTTL:
|
case _EXPECT_ANY_NOTTL:
|
||||||
|
@ -160,7 +175,8 @@ func ParseZone(r io.Reader, cr chan RR) {
|
||||||
case _CLASS:
|
case _CLASS:
|
||||||
h.Class, ok = Str_class[strings.ToUpper(l.token)]
|
h.Class, ok = Str_class[strings.ToUpper(l.token)]
|
||||||
if !ok {
|
if !ok {
|
||||||
fmt.Printf("%s\n", &ParseError{"Unknown class", l})
|
t <- Token{Err: &ParseError{"Unknown class", l}}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
st = _EXPECT_RRTYPE_BL
|
st = _EXPECT_RRTYPE_BL
|
||||||
case _RRTYPE:
|
case _RRTYPE:
|
||||||
|
@ -172,7 +188,8 @@ func ParseZone(r io.Reader, cr chan RR) {
|
||||||
case _STRING: // TTL
|
case _STRING: // TTL
|
||||||
ttl, ok := strconv.Atoi(l.token)
|
ttl, ok := strconv.Atoi(l.token)
|
||||||
if ok != nil {
|
if ok != nil {
|
||||||
fmt.Printf("%s\n", &ParseError{"Not a TTL", l})
|
t <- Token{Err: &ParseError{"Not a TTL", l}}
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
h.Ttl = uint32(ttl)
|
h.Ttl = uint32(ttl)
|
||||||
}
|
}
|
||||||
|
@ -181,25 +198,30 @@ func ParseZone(r io.Reader, cr chan RR) {
|
||||||
h.Rrtype, _ = Str_rr[strings.ToUpper(l.token)]
|
h.Rrtype, _ = Str_rr[strings.ToUpper(l.token)]
|
||||||
st = _EXPECT_RDATA
|
st = _EXPECT_RDATA
|
||||||
default:
|
default:
|
||||||
fmt.Printf("%s\n", &ParseError{"Expecting RR type or TTL, not this...", l})
|
t <- Token{Err: &ParseError{"Expecting RR type or TTL, not this...", l}}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
case _EXPECT_RRTYPE_BL:
|
case _EXPECT_RRTYPE_BL:
|
||||||
if l.value != _BLANK {
|
if l.value != _BLANK {
|
||||||
fmt.Printf("%s\n", &ParseError{"No blank after", l})
|
t <- Token{Err: &ParseError{"No blank after", l}}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
st = _EXPECT_RRTYPE
|
st = _EXPECT_RRTYPE
|
||||||
case _EXPECT_RRTYPE:
|
case _EXPECT_RRTYPE:
|
||||||
if l.value != _RRTYPE {
|
if l.value != _RRTYPE {
|
||||||
fmt.Printf("%s\n", &ParseError{"Unknown RR type", l})
|
t <- Token{Err: &ParseError{"Unknown RR type", l}}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
h.Rrtype, _ = Str_rr[strings.ToUpper(l.token)]
|
h.Rrtype, _ = Str_rr[strings.ToUpper(l.token)]
|
||||||
st = _EXPECT_RDATA
|
st = _EXPECT_RDATA
|
||||||
case _EXPECT_RDATA:
|
case _EXPECT_RDATA:
|
||||||
|
// I could save my token here...? l
|
||||||
r, e := setRR(h, c)
|
r, e := setRR(h, c)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
fmt.Printf("%v\n", e)
|
t <- Token{Err: e}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
cr <- r
|
t <- Token{Rr: r}
|
||||||
st = _EXPECT_OWNER
|
st = _EXPECT_OWNER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,7 +352,7 @@ func zlexer(s scanner.Scanner, c chan Lex) {
|
||||||
}
|
}
|
||||||
brace--
|
brace--
|
||||||
if brace < 0 {
|
if brace < 0 {
|
||||||
fmt.Printf("Error\n")
|
fmt.Printf("%s\n", &ParseError{"Extra closing brace", l})
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if commt {
|
if commt {
|
||||||
|
@ -341,6 +363,4 @@ func zlexer(s scanner.Scanner, c chan Lex) {
|
||||||
}
|
}
|
||||||
tok = s.Scan()
|
tok = s.Scan()
|
||||||
}
|
}
|
||||||
// Hmm
|
|
||||||
// fmt.Printf("XX %s XXX", str)
|
|
||||||
}
|
}
|
||||||
|
|
46
zscan_rr.go
46
zscan_rr.go
|
@ -11,13 +11,11 @@ import (
|
||||||
// All data from the channel c is either _STRING or _BLANK.
|
// All data from the channel c is either _STRING or _BLANK.
|
||||||
// After the rdata there may come 1 _BLANK and then a _NEWLINE
|
// After the rdata there may come 1 _BLANK and then a _NEWLINE
|
||||||
// or immediately a _NEWLINE. If this is not the case we flag
|
// or immediately a _NEWLINE. If this is not the case we flag
|
||||||
// an error: garbage after rdata.
|
// an *ParseError: garbage after rdata.
|
||||||
|
|
||||||
func setRR(h RR_Header, c chan Lex) (RR, error) {
|
func setRR(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
var (
|
var r RR
|
||||||
r RR
|
e := new(ParseError)
|
||||||
e error
|
|
||||||
)
|
|
||||||
switch h.Rrtype {
|
switch h.Rrtype {
|
||||||
case TypeA:
|
case TypeA:
|
||||||
r, e = setA(h, c)
|
r, e = setA(h, c)
|
||||||
|
@ -87,7 +85,7 @@ func setRR(h RR_Header, c chan Lex) (RR, error) {
|
||||||
return r, e
|
return r, e
|
||||||
}
|
}
|
||||||
|
|
||||||
func slurpRemainder(c chan Lex) error {
|
func slurpRemainder(c chan Lex) *ParseError {
|
||||||
l := <-c
|
l := <-c
|
||||||
if DEBUG {
|
if DEBUG {
|
||||||
fmt.Printf("%\v", l)
|
fmt.Printf("%\v", l)
|
||||||
|
@ -112,7 +110,7 @@ func slurpRemainder(c chan Lex) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setA(h RR_Header, c chan Lex) (RR, error) {
|
func setA(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_A)
|
rr := new(RR_A)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
|
||||||
|
@ -124,7 +122,7 @@ func setA(h RR_Header, c chan Lex) (RR, error) {
|
||||||
return rr, nil
|
return rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setAAAA(h RR_Header, c chan Lex) (RR, error) {
|
func setAAAA(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_AAAA)
|
rr := new(RR_AAAA)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
|
||||||
|
@ -136,7 +134,7 @@ func setAAAA(h RR_Header, c chan Lex) (RR, error) {
|
||||||
return rr, nil
|
return rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNS(h RR_Header, c chan Lex) (RR, error) {
|
func setNS(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_NS)
|
rr := new(RR_NS)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
|
||||||
|
@ -148,7 +146,7 @@ func setNS(h RR_Header, c chan Lex) (RR, error) {
|
||||||
return rr, nil
|
return rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setMX(h RR_Header, c chan Lex) (RR, error) {
|
func setMX(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_MX)
|
rr := new(RR_MX)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
|
||||||
|
@ -167,7 +165,7 @@ func setMX(h RR_Header, c chan Lex) (RR, error) {
|
||||||
return rr, nil
|
return rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
func setCNAME(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_CNAME)
|
rr := new(RR_CNAME)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
|
||||||
|
@ -179,7 +177,7 @@ func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
||||||
return rr, nil
|
return rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setSOA(h RR_Header, c chan Lex) (RR, error) {
|
func setSOA(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_SOA)
|
rr := new(RR_SOA)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
|
||||||
|
@ -198,7 +196,7 @@ func setSOA(h RR_Header, c chan Lex) (RR, error) {
|
||||||
<-c // _BLANK
|
<-c // _BLANK
|
||||||
|
|
||||||
var j int
|
var j int
|
||||||
var e error
|
var e error
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
l = <-c
|
l = <-c
|
||||||
if j, e = strconv.Atoi(l.token); e != nil {
|
if j, e = strconv.Atoi(l.token); e != nil {
|
||||||
|
@ -221,7 +219,7 @@ func setSOA(h RR_Header, c chan Lex) (RR, error) {
|
||||||
return rr, nil
|
return rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setRRSIG(h RR_Header, c chan Lex) (RR, error) {
|
func setRRSIG(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_RRSIG)
|
rr := new(RR_RRSIG)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
l := <-c
|
l := <-c
|
||||||
|
@ -297,7 +295,7 @@ func setRRSIG(h RR_Header, c chan Lex) (RR, error) {
|
||||||
return rr, nil
|
return rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNSEC(h RR_Header, c chan Lex) (RR, error) {
|
func setNSEC(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_NSEC)
|
rr := new(RR_NSEC)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
|
||||||
|
@ -328,7 +326,7 @@ func setNSEC(h RR_Header, c chan Lex) (RR, error) {
|
||||||
return rr, nil
|
return rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNSEC3(h RR_Header, c chan Lex) (RR, error) {
|
func setNSEC3(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_NSEC3)
|
rr := new(RR_NSEC3)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
|
||||||
|
@ -382,7 +380,7 @@ func setNSEC3(h RR_Header, c chan Lex) (RR, error) {
|
||||||
return rr, nil
|
return rr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setDNSKEY(h RR_Header, c chan Lex) (RR, error) {
|
func setDNSKEY(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_DNSKEY)
|
rr := new(RR_DNSKEY)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
|
||||||
|
@ -424,7 +422,7 @@ func setDNSKEY(h RR_Header, c chan Lex) (RR, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
func setNSEC3PARAM(h RR_Header, c chan Lex) (RR, error) {
|
func setNSEC3PARAM(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_NSEC3PARAM)
|
rr := new(RR_NSEC3PARAM)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
rdf := fields(data[mark:p], 4)
|
rdf := fields(data[mark:p], 4)
|
||||||
|
@ -449,7 +447,7 @@ func setNSEC3PARAM(h RR_Header, c chan Lex) (RR, error) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func setTXT(h RR_Header, c chan Lex) (RR, error) {
|
func setTXT(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_TXT)
|
rr := new(RR_TXT)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
|
||||||
|
@ -472,7 +470,7 @@ func setTXT(h RR_Header, c chan Lex) (RR, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
func setDS(h RR_Header, c chan Lex) (RR, error) {
|
func setDS(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_DS)
|
rr := new(RR_DS)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
action setDS {
|
action setDS {
|
||||||
|
@ -503,7 +501,7 @@ func setDS(h RR_Header, c chan Lex) (RR, error) {
|
||||||
zp.RR <- rr
|
zp.RR <- rr
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
func setCNAME(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_CNAME)
|
rr := new(RR_CNAME)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
action setDLV {
|
action setDLV {
|
||||||
|
@ -534,7 +532,7 @@ func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
||||||
zp.RR <- rr
|
zp.RR <- rr
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
func setCNAME(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_CNAME)
|
rr := new(RR_CNAME)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
action setTA {
|
action setTA {
|
||||||
|
@ -566,7 +564,7 @@ func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func setSSHFP(h RR_Header, c chan Lex) (RR, error) {
|
func setSSHFP(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||||
rr := new(RR_CNAME)
|
rr := new(RR_CNAME)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
var (
|
var (
|
||||||
|
|
Loading…
Reference in New Issue