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 = 4096 // DefaultMsgSize is the standard default for messages larger than 512 bytes. 10 MinMsgSize = 512 // MinMsgSize is the minimal size of a DNS packet. 11 MaxMsgSize = 65535 // MaxMsgSize is the largest possible DNS packet. 12) 13 14// Error represents a DNS error. 15type Error struct{ err string } 16 17func (e *Error) Error() string { 18 if e == nil { 19 return "dns: <nil>" 20 } 21 return "dns: " + e.err 22} 23 24// An RR represents a resource record. 25type RR interface { 26 // Header returns the header of an resource record. The header contains 27 // everything up to the rdata. 28 Header() *RR_Header 29 // String returns the text representation of the resource record. 30 String() string 31 32 // copy returns a copy of the RR 33 copy() RR 34 // len returns the length (in octets) of the uncompressed RR in wire format. 35 len() int 36 // pack packs an RR into wire format. 37 pack([]byte, int, map[string]int, bool) (int, error) 38} 39 40// RR_Header is the header all DNS resource records share. 41type RR_Header struct { 42 Name string `dns:"cdomain-name"` 43 Rrtype uint16 44 Class uint16 45 Ttl uint32 46 Rdlength uint16 // Length of data after header. 47} 48 49// Header returns itself. This is here to make RR_Header implements the RR interface. 50func (h *RR_Header) Header() *RR_Header { return h } 51 52// Just to implement the RR interface. 53func (h *RR_Header) copy() RR { return nil } 54 55func (h *RR_Header) copyHeader() *RR_Header { 56 r := new(RR_Header) 57 r.Name = h.Name 58 r.Rrtype = h.Rrtype 59 r.Class = h.Class 60 r.Ttl = h.Ttl 61 r.Rdlength = h.Rdlength 62 return r 63} 64 65func (h *RR_Header) String() string { 66 var s string 67 68 if h.Rrtype == TypeOPT { 69 s = ";" 70 // and maybe other things 71 } 72 73 s += sprintName(h.Name) + "\t" 74 s += strconv.FormatInt(int64(h.Ttl), 10) + "\t" 75 s += Class(h.Class).String() + "\t" 76 s += Type(h.Rrtype).String() + "\t" 77 return s 78} 79 80func (h *RR_Header) len() int { 81 l := len(h.Name) + 1 82 l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2) 83 return l 84} 85 86// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597. 87func (rr *RFC3597) ToRFC3597(r RR) error { 88 buf := make([]byte, r.len()*2) 89 off, err := PackRR(r, buf, 0, nil, false) 90 if err != nil { 91 return err 92 } 93 buf = buf[:off] 94 if int(r.Header().Rdlength) > off { 95 return ErrBuf 96 } 97 98 rfc3597, _, err := unpackRFC3597(*r.Header(), buf, off-int(r.Header().Rdlength)) 99 if err != nil { 100 return err 101 } 102 *rr = *rfc3597.(*RFC3597) 103 return nil 104} 105