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