OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / miekg / dns / privaterr.go
1 package dns
2
3 import (
4         "fmt"
5         "strings"
6 )
7
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.
13         String() string
14         // Parse parses the Rdata of the private RR.
15         Parse([]string) error
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.
24         Len() int
25 }
26
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 {
30         Hdr  RR_Header
31         Data PrivateRdata
32 }
33
34 func mkPrivateRR(rrtype uint16) *PrivateRR {
35         // Panics if RR is not an instance of PrivateRR.
36         rrfunc, ok := TypeToRR[rrtype]
37         if !ok {
38                 panic(fmt.Sprintf("dns: invalid operation with Private RR type %d", rrtype))
39         }
40
41         anyrr := rrfunc()
42         rr, ok := anyrr.(*PrivateRR)
43         if !ok {
44                 panic(fmt.Sprintf("dns: RR is not a PrivateRR, TypeToRR[%d] generator returned %T", rrtype, anyrr))
45         }
46
47         return rr
48 }
49
50 // Header return the RR header of r.
51 func (r *PrivateRR) Header() *RR_Header { return &r.Hdr }
52
53 func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() }
54
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)
58         l += r.Data.Len()
59         return l
60 }
61
62 func (r *PrivateRR) copy() RR {
63         // make new RR like this:
64         rr := mkPrivateRR(r.Hdr.Rrtype)
65         rr.Hdr = r.Hdr
66
67         err := r.Data.Copy(rr.Data)
68         if err != nil {
69                 panic("dns: got value that could not be used to copy Private rdata")
70         }
71         return rr
72 }
73
74 func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
75         n, err := r.Data.Pack(msg[off:])
76         if err != nil {
77                 return len(msg), err
78         }
79         off += n
80         return off, nil
81 }
82
83 func (r *PrivateRR) unpack(msg []byte, off int) (int, error) {
84         off1, err := r.Data.Unpack(msg[off:])
85         off += off1
86         return off, err
87 }
88
89 func (r *PrivateRR) parse(c *zlexer, origin, file string) *ParseError {
90         var l lex
91         text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
92 Fetch:
93         for {
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 {
97                 case zNewline, zEOF:
98                         break Fetch
99                 case zString:
100                         text = append(text, l.token)
101                 }
102         }
103
104         err := r.Data.Parse(text)
105         if err != nil {
106                 return &ParseError{file, err.Error(), l}
107         }
108
109         return nil
110 }
111
112 func (r1 *PrivateRR) isDuplicate(r2 RR) bool { return false }
113
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)
118
119         TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator()} }
120         TypeToString[rtype] = rtypestr
121         StringToType[rtypestr] = rtype
122 }
123
124 // PrivateHandleRemove removes definitions required to support private RR type.
125 func PrivateHandleRemove(rtype uint16) {
126         rtypestr, ok := TypeToString[rtype]
127         if ok {
128                 delete(TypeToRR, rtype)
129                 delete(TypeToString, rtype)
130                 delete(StringToType, rtypestr)
131         }
132 }