gitea

Development moved to Codeberg

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
  98. 98
  99. 99
  100. 100
  101. 101
  102. 102
  103. 103
  104. 104
  105. 105
  106. 106
  107. 107
  108. 108
  109. 109
  110. 110
  111. 111
  112. 112
  113. 113
package dns

import "strings"

// PrivateRdata is an interface used for implementing "Private Use" RR types, see
// RFC 6895. This allows one to experiment with new RR types, without requesting an
// official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
type PrivateRdata interface {
	// String returns the text presentation of the Rdata of the Private RR.
	String() string
	// Parse parses the Rdata of the private RR.
	Parse([]string) error
	// Pack is used when packing a private RR into a buffer.
	Pack([]byte) (int, error)
	// Unpack is used when unpacking a private RR from a buffer.
	Unpack([]byte) (int, error)
	// Copy copies the Rdata into the PrivateRdata argument.
	Copy(PrivateRdata) error
	// Len returns the length in octets of the Rdata.
	Len() int
}

// PrivateRR represents an RR that uses a PrivateRdata user-defined type.
// It mocks normal RRs and implements dns.RR interface.
type PrivateRR struct {
	Hdr  RR_Header
	Data PrivateRdata

	generator func() PrivateRdata // for copy
}

// Header return the RR header of r.
func (r *PrivateRR) Header() *RR_Header { return &r.Hdr }

func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() }

// Private len and copy parts to satisfy RR interface.
func (r *PrivateRR) len(off int, compression map[string]struct{}) int {
	l := r.Hdr.len(off, compression)
	l += r.Data.Len()
	return l
}

func (r *PrivateRR) copy() RR {
	// make new RR like this:
	rr := &PrivateRR{r.Hdr, r.generator(), r.generator}

	if err := r.Data.Copy(rr.Data); err != nil {
		panic("dns: got value that could not be used to copy Private rdata: " + err.Error())
	}

	return rr
}

func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
	n, err := r.Data.Pack(msg[off:])
	if err != nil {
		return len(msg), err
	}
	off += n
	return off, nil
}

func (r *PrivateRR) unpack(msg []byte, off int) (int, error) {
	off1, err := r.Data.Unpack(msg[off:])
	off += off1
	return off, err
}

func (r *PrivateRR) parse(c *zlexer, origin string) *ParseError {
	var l lex
	text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
Fetch:
	for {
		// TODO(miek): we could also be returning _QUOTE, this might or might not
		// be an issue (basically parsing TXT becomes hard)
		switch l, _ = c.Next(); l.value {
		case zNewline, zEOF:
			break Fetch
		case zString:
			text = append(text, l.token)
		}
	}

	err := r.Data.Parse(text)
	if err != nil {
		return &ParseError{"", err.Error(), l}
	}

	return nil
}

func (r *PrivateRR) isDuplicate(r2 RR) bool { return false }

// PrivateHandle registers a private resource record type. It requires
// string and numeric representation of private RR type and generator function as argument.
func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) {
	rtypestr = strings.ToUpper(rtypestr)

	TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator(), generator} }
	TypeToString[rtype] = rtypestr
	StringToType[rtypestr] = rtype
}

// PrivateHandleRemove removes definitions required to support private RR type.
func PrivateHandleRemove(rtype uint16) {
	rtypestr, ok := TypeToString[rtype]
	if ok {
		delete(TypeToRR, rtype)
		delete(TypeToString, rtype)
		delete(StringToType, rtypestr)
	}
}