1package dns 2 3import "strconv" 4 5const ( 6 year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits. 7 defaultTtl = 3600 // Default internal TTL. 8 9 // DefaultMsgSize is the standard default for messages larger than 512 bytes. 10 DefaultMsgSize = 4096 11 // MinMsgSize is the minimal size of a DNS packet. 12 MinMsgSize = 512 13 // MaxMsgSize is the largest possible DNS packet. 14 MaxMsgSize = 65535 15) 16 17// Error represents a DNS error. 18type Error struct{ err string } 19 20func (e *Error) Error() string { 21 if e == nil { 22 return "dns: <nil>" 23 } 24 return "dns: " + e.err 25} 26 27// An RR represents a resource record. 28type RR interface { 29 // Header returns the header of an resource record. The header contains 30 // everything up to the rdata. 31 Header() *RR_Header 32 // String returns the text representation of the resource record. 33 String() string 34 35 // copy returns a copy of the RR 36 copy() RR 37 38 // len returns the length (in octets) of the compressed or uncompressed RR in wire format. 39 // 40 // If compression is nil, the uncompressed size will be returned, otherwise the compressed 41 // size will be returned and domain names will be added to the map for future compression. 42 len(off int, compression map[string]struct{}) int 43 44 // pack packs the records RDATA into wire format. The header will 45 // already have been packed into msg. 46 pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) 47 48 // unpack unpacks an RR from wire format. 49 // 50 // This will only be called on a new and empty RR type with only the header populated. It 51 // will only be called if the record's RDATA is non-empty. 52 unpack(msg []byte, off int) (off1 int, err error) 53 54 // parse parses an RR from zone file format. 55 // 56 // This will only be called on a new and empty RR type with only the header populated. 57 parse(c *zlexer, origin string) *ParseError 58 59 // isDuplicate returns whether the two RRs are duplicates. 60 isDuplicate(r2 RR) bool 61} 62 63// RR_Header is the header all DNS resource records share. 64type RR_Header struct { 65 Name string `dns:"cdomain-name"` 66 Rrtype uint16 67 Class uint16 68 Ttl uint32 69 Rdlength uint16 // Length of data after header. 70} 71 72// Header returns itself. This is here to make RR_Header implements the RR interface. 73func (h *RR_Header) Header() *RR_Header { return h } 74 75// Just to implement the RR interface. 76func (h *RR_Header) copy() RR { return nil } 77 78func (h *RR_Header) String() string { 79 var s string 80 81 if h.Rrtype == TypeOPT { 82 s = ";" 83 // and maybe other things 84 } 85 86 s += sprintName(h.Name) + "\t" 87 s += strconv.FormatInt(int64(h.Ttl), 10) + "\t" 88 s += Class(h.Class).String() + "\t" 89 s += Type(h.Rrtype).String() + "\t" 90 return s 91} 92 93func (h *RR_Header) len(off int, compression map[string]struct{}) int { 94 l := domainNameLen(h.Name, off, compression, true) 95 l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2) 96 return l 97} 98 99func (h *RR_Header) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { 100 // RR_Header has no RDATA to pack. 101 return off, nil 102} 103 104func (h *RR_Header) unpack(msg []byte, off int) (int, error) { 105 panic("dns: internal error: unpack should never be called on RR_Header") 106} 107 108func (h *RR_Header) parse(c *zlexer, origin string) *ParseError { 109 panic("dns: internal error: parse should never be called on RR_Header") 110} 111 112// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597. 113func (rr *RFC3597) ToRFC3597(r RR) error { 114 buf := make([]byte, Len(r)*2) 115 headerEnd, off, err := packRR(r, buf, 0, compressionMap{}, false) 116 if err != nil { 117 return err 118 } 119 buf = buf[:off] 120 121 *rr = RFC3597{Hdr: *r.Header()} 122 rr.Hdr.Rdlength = uint16(off - headerEnd) 123 124 if noRdata(rr.Hdr) { 125 return nil 126 } 127 128 _, err = rr.unpack(buf, headerEnd) 129 if err != nil { 130 return err 131 } 132 133 return nil 134} 135