8 // PrivateRdata is an interface used for implementing "Private Use" RR types, see
9 // RFC 6895. This allows one to experiment with new RR types, without requesting an
10 // official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
11 type PrivateRdata interface {
12 // String returns the text presentaton of the Rdata of the Private RR.
14 // Parse parses the Rdata of the private RR.
16 // Pack is used when packing a private RR into a buffer.
17 Pack([]byte) (int, error)
18 // Unpack is used when unpacking a private RR from a buffer.
19 // TODO(miek): diff. signature than Pack, see edns0.go for instance.
20 Unpack([]byte) (int, error)
21 // Copy copies the Rdata.
22 Copy(PrivateRdata) error
23 // Len returns the length in octets of the Rdata.
27 // PrivateRR represents an RR that uses a PrivateRdata user-defined type.
28 // It mocks normal RRs and implements dns.RR interface.
29 type PrivateRR struct {
34 func mkPrivateRR(rrtype uint16) *PrivateRR {
35 // Panics if RR is not an instance of PrivateRR.
36 rrfunc, ok := TypeToRR[rrtype]
38 panic(fmt.Sprintf("dns: invalid operation with Private RR type %d", rrtype))
42 rr, ok := anyrr.(*PrivateRR)
44 panic(fmt.Sprintf("dns: RR is not a PrivateRR, TypeToRR[%d] generator returned %T", rrtype, anyrr))
50 // Header return the RR header of r.
51 func (r *PrivateRR) Header() *RR_Header { return &r.Hdr }
53 func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() }
55 // Private len and copy parts to satisfy RR interface.
56 func (r *PrivateRR) len(off int, compression map[string]struct{}) int {
57 l := r.Hdr.len(off, compression)
62 func (r *PrivateRR) copy() RR {
63 // make new RR like this:
64 rr := mkPrivateRR(r.Hdr.Rrtype)
67 err := r.Data.Copy(rr.Data)
69 panic("dns: got value that could not be used to copy Private rdata")
74 func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
75 n, err := r.Data.Pack(msg[off:])
83 func (r *PrivateRR) unpack(msg []byte, off int) (int, error) {
84 off1, err := r.Data.Unpack(msg[off:])
89 func (r *PrivateRR) parse(c *zlexer, origin, file string) *ParseError {
91 text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
94 // TODO(miek): we could also be returning _QUOTE, this might or might not
95 // be an issue (basically parsing TXT becomes hard)
96 switch l, _ = c.Next(); l.value {
100 text = append(text, l.token)
104 err := r.Data.Parse(text)
106 return &ParseError{file, err.Error(), l}
112 func (r1 *PrivateRR) isDuplicate(r2 RR) bool { return false }
114 // PrivateHandle registers a private resource record type. It requires
115 // string and numeric representation of private RR type and generator function as argument.
116 func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) {
117 rtypestr = strings.ToUpper(rtypestr)
119 TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator()} }
120 TypeToString[rtype] = rtypestr
121 StringToType[rtypestr] = rtype
124 // PrivateHandleRemove removes definitions required to support private RR type.
125 func PrivateHandleRemove(rtype uint16) {
126 rtypestr, ok := TypeToString[rtype]
128 delete(TypeToRR, rtype)
129 delete(TypeToString, rtype)
130 delete(StringToType, rtypestr)