You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

privaterr.go 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package dns
  2. import "strings"
  3. // PrivateRdata is an interface used for implementing "Private Use" RR types, see
  4. // RFC 6895. This allows one to experiment with new RR types, without requesting an
  5. // official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
  6. type PrivateRdata interface {
  7. // String returns the text presentation of the Rdata of the Private RR.
  8. String() string
  9. // Parse parses the Rdata of the private RR.
  10. Parse([]string) error
  11. // Pack is used when packing a private RR into a buffer.
  12. Pack([]byte) (int, error)
  13. // Unpack is used when unpacking a private RR from a buffer.
  14. Unpack([]byte) (int, error)
  15. // Copy copies the Rdata into the PrivateRdata argument.
  16. Copy(PrivateRdata) error
  17. // Len returns the length in octets of the Rdata.
  18. Len() int
  19. }
  20. // PrivateRR represents an RR that uses a PrivateRdata user-defined type.
  21. // It mocks normal RRs and implements dns.RR interface.
  22. type PrivateRR struct {
  23. Hdr RR_Header
  24. Data PrivateRdata
  25. generator func() PrivateRdata // for copy
  26. }
  27. // Header return the RR header of r.
  28. func (r *PrivateRR) Header() *RR_Header { return &r.Hdr }
  29. func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() }
  30. // Private len and copy parts to satisfy RR interface.
  31. func (r *PrivateRR) len(off int, compression map[string]struct{}) int {
  32. l := r.Hdr.len(off, compression)
  33. l += r.Data.Len()
  34. return l
  35. }
  36. func (r *PrivateRR) copy() RR {
  37. // make new RR like this:
  38. rr := &PrivateRR{r.Hdr, r.generator(), r.generator}
  39. if err := r.Data.Copy(rr.Data); err != nil {
  40. panic("dns: got value that could not be used to copy Private rdata: " + err.Error())
  41. }
  42. return rr
  43. }
  44. func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
  45. n, err := r.Data.Pack(msg[off:])
  46. if err != nil {
  47. return len(msg), err
  48. }
  49. off += n
  50. return off, nil
  51. }
  52. func (r *PrivateRR) unpack(msg []byte, off int) (int, error) {
  53. off1, err := r.Data.Unpack(msg[off:])
  54. off += off1
  55. return off, err
  56. }
  57. func (r *PrivateRR) parse(c *zlexer, origin string) *ParseError {
  58. var l lex
  59. text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
  60. Fetch:
  61. for {
  62. // TODO(miek): we could also be returning _QUOTE, this might or might not
  63. // be an issue (basically parsing TXT becomes hard)
  64. switch l, _ = c.Next(); l.value {
  65. case zNewline, zEOF:
  66. break Fetch
  67. case zString:
  68. text = append(text, l.token)
  69. }
  70. }
  71. err := r.Data.Parse(text)
  72. if err != nil {
  73. return &ParseError{"", err.Error(), l}
  74. }
  75. return nil
  76. }
  77. func (r *PrivateRR) isDuplicate(r2 RR) bool { return false }
  78. // PrivateHandle registers a private resource record type. It requires
  79. // string and numeric representation of private RR type and generator function as argument.
  80. func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) {
  81. rtypestr = strings.ToUpper(rtypestr)
  82. TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator(), generator} }
  83. TypeToString[rtype] = rtypestr
  84. StringToType[rtypestr] = rtype
  85. }
  86. // PrivateHandleRemove removes definitions required to support private RR type.
  87. func PrivateHandleRemove(rtype uint16) {
  88. rtypestr, ok := TypeToString[rtype]
  89. if ok {
  90. delete(TypeToRR, rtype)
  91. delete(TypeToString, rtype)
  92. delete(StringToType, rtypestr)
  93. }
  94. }