edns.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. package dns
  2. import (
  3. "encoding/hex"
  4. "errors"
  5. "net"
  6. "strconv"
  7. )
  8. // EDNS0 Option codes.
  9. const (
  10. EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
  11. EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
  12. EDNS0NSID = 0x3 // nsid (RFC5001)
  13. EDNS0DAU = 0x5 // DNSSEC Algorithm Understood
  14. EDNS0DHU = 0x6 // DS Hash Understood
  15. EDNS0N3U = 0x7 // NSEC3 Hash Understood
  16. EDNS0SUBNET = 0x8 // client-subnet (RFC6891)
  17. EDNS0EXPIRE = 0x9 // EDNS0 expire
  18. EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET
  19. EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891)
  20. EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891)
  21. _DO = 1 << 15 // dnssec ok
  22. )
  23. // OPT is the EDNS0 RR appended to messages to convey extra (meta) information.
  24. // See RFC 6891.
  25. type OPT struct {
  26. Hdr RR_Header
  27. Option []EDNS0 `dns:"opt"`
  28. }
  29. func (rr *OPT) String() string {
  30. s := "\n;; OPT PSEUDOSECTION:\n; EDNS: version " + strconv.Itoa(int(rr.Version())) + "; "
  31. if rr.Do() {
  32. s += "flags: do; "
  33. } else {
  34. s += "flags: ; "
  35. }
  36. s += "udp: " + strconv.Itoa(int(rr.UDPSize()))
  37. for _, o := range rr.Option {
  38. switch o.(type) {
  39. case *EDNS0_NSID:
  40. s += "\n; NSID: " + o.String()
  41. h, e := o.pack()
  42. var r string
  43. if e == nil {
  44. for _, c := range h {
  45. r += "(" + string(c) + ")"
  46. }
  47. s += " " + r
  48. }
  49. case *EDNS0_SUBNET:
  50. s += "\n; SUBNET: " + o.String()
  51. if o.(*EDNS0_SUBNET).DraftOption {
  52. s += " (draft)"
  53. }
  54. case *EDNS0_UL:
  55. s += "\n; UPDATE LEASE: " + o.String()
  56. case *EDNS0_LLQ:
  57. s += "\n; LONG LIVED QUERIES: " + o.String()
  58. case *EDNS0_DAU:
  59. s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String()
  60. case *EDNS0_DHU:
  61. s += "\n; DS HASH UNDERSTOOD: " + o.String()
  62. case *EDNS0_N3U:
  63. s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
  64. case *EDNS0_LOCAL:
  65. s += "\n; LOCAL OPT: " + o.String()
  66. }
  67. }
  68. return s
  69. }
  70. func (rr *OPT) len() int {
  71. l := rr.Hdr.len()
  72. for i := 0; i < len(rr.Option); i++ {
  73. l += 4 // Account for 2-byte option code and 2-byte option length.
  74. lo, _ := rr.Option[i].pack()
  75. l += len(lo)
  76. }
  77. return l
  78. }
  79. // return the old value -> delete SetVersion?
  80. // Version returns the EDNS version used. Only zero is defined.
  81. func (rr *OPT) Version() uint8 {
  82. return uint8((rr.Hdr.Ttl & 0x00FF0000) >> 16)
  83. }
  84. // SetVersion sets the version of EDNS. This is usually zero.
  85. func (rr *OPT) SetVersion(v uint8) {
  86. rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | (uint32(v) << 16)
  87. }
  88. // ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL).
  89. func (rr *OPT) ExtendedRcode() uint8 {
  90. return uint8((rr.Hdr.Ttl & 0xFF000000) >> 24)
  91. }
  92. // SetExtendedRcode sets the EDNS extended RCODE field.
  93. func (rr *OPT) SetExtendedRcode(v uint8) {
  94. rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | (uint32(v) << 24)
  95. }
  96. // UDPSize returns the UDP buffer size.
  97. func (rr *OPT) UDPSize() uint16 {
  98. return rr.Hdr.Class
  99. }
  100. // SetUDPSize sets the UDP buffer size.
  101. func (rr *OPT) SetUDPSize(size uint16) {
  102. rr.Hdr.Class = size
  103. }
  104. // Do returns the value of the DO (DNSSEC OK) bit.
  105. func (rr *OPT) Do() bool {
  106. return rr.Hdr.Ttl&_DO == _DO
  107. }
  108. // SetDo sets the DO (DNSSEC OK) bit.
  109. func (rr *OPT) SetDo() {
  110. rr.Hdr.Ttl |= _DO
  111. }
  112. // EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to
  113. // it.
  114. type EDNS0 interface {
  115. // Option returns the option code for the option.
  116. Option() uint16
  117. // pack returns the bytes of the option data.
  118. pack() ([]byte, error)
  119. // unpack sets the data as found in the buffer. Is also sets
  120. // the length of the slice as the length of the option data.
  121. unpack([]byte) error
  122. // String returns the string representation of the option.
  123. String() string
  124. }
  125. // The nsid EDNS0 option is used to retrieve a nameserver
  126. // identifier. When sending a request Nsid must be set to the empty string
  127. // The identifier is an opaque string encoded as hex.
  128. // Basic use pattern for creating an nsid option:
  129. //
  130. // o := new(dns.OPT)
  131. // o.Hdr.Name = "."
  132. // o.Hdr.Rrtype = dns.TypeOPT
  133. // e := new(dns.EDNS0_NSID)
  134. // e.Code = dns.EDNS0NSID
  135. // e.Nsid = "AA"
  136. // o.Option = append(o.Option, e)
  137. type EDNS0_NSID struct {
  138. Code uint16 // Always EDNS0NSID
  139. Nsid string // This string needs to be hex encoded
  140. }
  141. func (e *EDNS0_NSID) pack() ([]byte, error) {
  142. h, err := hex.DecodeString(e.Nsid)
  143. if err != nil {
  144. return nil, err
  145. }
  146. return h, nil
  147. }
  148. func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID }
  149. func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil }
  150. func (e *EDNS0_NSID) String() string { return string(e.Nsid) }
  151. // EDNS0_SUBNET is the subnet option that is used to give the remote nameserver
  152. // an idea of where the client lives. It can then give back a different
  153. // answer depending on the location or network topology.
  154. // Basic use pattern for creating an subnet option:
  155. //
  156. // o := new(dns.OPT)
  157. // o.Hdr.Name = "."
  158. // o.Hdr.Rrtype = dns.TypeOPT
  159. // e := new(dns.EDNS0_SUBNET)
  160. // e.Code = dns.EDNS0SUBNET
  161. // e.Family = 1 // 1 for IPv4 source address, 2 for IPv6
  162. // e.NetMask = 32 // 32 for IPV4, 128 for IPv6
  163. // e.SourceScope = 0
  164. // e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4
  165. // // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6
  166. // o.Option = append(o.Option, e)
  167. //
  168. // Note: the spec (draft-ietf-dnsop-edns-client-subnet-00) has some insane logic
  169. // for which netmask applies to the address. This code will parse all the
  170. // available bits when unpacking (up to optlen). When packing it will apply
  171. // SourceNetmask. If you need more advanced logic, patches welcome and good luck.
  172. type EDNS0_SUBNET struct {
  173. Code uint16 // Always EDNS0SUBNET
  174. Family uint16 // 1 for IP, 2 for IP6
  175. SourceNetmask uint8
  176. SourceScope uint8
  177. Address net.IP
  178. DraftOption bool // Set to true if using the old (0x50fa) option code
  179. }
  180. func (e *EDNS0_SUBNET) Option() uint16 {
  181. if e.DraftOption {
  182. return EDNS0SUBNETDRAFT
  183. }
  184. return EDNS0SUBNET
  185. }
  186. func (e *EDNS0_SUBNET) pack() ([]byte, error) {
  187. b := make([]byte, 4)
  188. b[0], b[1] = packUint16(e.Family)
  189. b[2] = e.SourceNetmask
  190. b[3] = e.SourceScope
  191. switch e.Family {
  192. case 1:
  193. if e.SourceNetmask > net.IPv4len*8 {
  194. return nil, errors.New("dns: bad netmask")
  195. }
  196. if len(e.Address.To4()) != net.IPv4len {
  197. return nil, errors.New("dns: bad address")
  198. }
  199. ip := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8))
  200. needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up
  201. b = append(b, ip[:needLength]...)
  202. case 2:
  203. if e.SourceNetmask > net.IPv6len*8 {
  204. return nil, errors.New("dns: bad netmask")
  205. }
  206. if len(e.Address) != net.IPv6len {
  207. return nil, errors.New("dns: bad address")
  208. }
  209. ip := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8))
  210. needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up
  211. b = append(b, ip[:needLength]...)
  212. default:
  213. return nil, errors.New("dns: bad address family")
  214. }
  215. return b, nil
  216. }
  217. func (e *EDNS0_SUBNET) unpack(b []byte) error {
  218. if len(b) < 4 {
  219. return ErrBuf
  220. }
  221. e.Family, _ = unpackUint16(b, 0)
  222. e.SourceNetmask = b[2]
  223. e.SourceScope = b[3]
  224. switch e.Family {
  225. case 1:
  226. if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 {
  227. return errors.New("dns: bad netmask")
  228. }
  229. addr := make([]byte, net.IPv4len)
  230. for i := 0; i < net.IPv4len && 4+i < len(b); i++ {
  231. addr[i] = b[4+i]
  232. }
  233. e.Address = net.IPv4(addr[0], addr[1], addr[2], addr[3])
  234. case 2:
  235. if e.SourceNetmask > net.IPv6len*8 || e.SourceScope > net.IPv6len*8 {
  236. return errors.New("dns: bad netmask")
  237. }
  238. addr := make([]byte, net.IPv6len)
  239. for i := 0; i < net.IPv6len && 4+i < len(b); i++ {
  240. addr[i] = b[4+i]
  241. }
  242. e.Address = net.IP{addr[0], addr[1], addr[2], addr[3], addr[4],
  243. addr[5], addr[6], addr[7], addr[8], addr[9], addr[10],
  244. addr[11], addr[12], addr[13], addr[14], addr[15]}
  245. default:
  246. return errors.New("dns: bad address family")
  247. }
  248. return nil
  249. }
  250. func (e *EDNS0_SUBNET) String() (s string) {
  251. if e.Address == nil {
  252. s = "<nil>"
  253. } else if e.Address.To4() != nil {
  254. s = e.Address.String()
  255. } else {
  256. s = "[" + e.Address.String() + "]"
  257. }
  258. s += "/" + strconv.Itoa(int(e.SourceNetmask)) + "/" + strconv.Itoa(int(e.SourceScope))
  259. return
  260. }
  261. // The EDNS0_UL (Update Lease) (draft RFC) option is used to tell the server to set
  262. // an expiration on an update RR. This is helpful for clients that cannot clean
  263. // up after themselves. This is a draft RFC and more information can be found at
  264. // http://files.dns-sd.org/draft-sekar-dns-ul.txt
  265. //
  266. // o := new(dns.OPT)
  267. // o.Hdr.Name = "."
  268. // o.Hdr.Rrtype = dns.TypeOPT
  269. // e := new(dns.EDNS0_UL)
  270. // e.Code = dns.EDNS0UL
  271. // e.Lease = 120 // in seconds
  272. // o.Option = append(o.Option, e)
  273. type EDNS0_UL struct {
  274. Code uint16 // Always EDNS0UL
  275. Lease uint32
  276. }
  277. func (e *EDNS0_UL) Option() uint16 { return EDNS0UL }
  278. func (e *EDNS0_UL) String() string { return strconv.FormatUint(uint64(e.Lease), 10) }
  279. // Copied: http://golang.org/src/pkg/net/dnsmsg.go
  280. func (e *EDNS0_UL) pack() ([]byte, error) {
  281. b := make([]byte, 4)
  282. b[0] = byte(e.Lease >> 24)
  283. b[1] = byte(e.Lease >> 16)
  284. b[2] = byte(e.Lease >> 8)
  285. b[3] = byte(e.Lease)
  286. return b, nil
  287. }
  288. func (e *EDNS0_UL) unpack(b []byte) error {
  289. if len(b) < 4 {
  290. return ErrBuf
  291. }
  292. e.Lease = uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
  293. return nil
  294. }
  295. // EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
  296. // Implemented for completeness, as the EDNS0 type code is assigned.
  297. type EDNS0_LLQ struct {
  298. Code uint16 // Always EDNS0LLQ
  299. Version uint16
  300. Opcode uint16
  301. Error uint16
  302. Id uint64
  303. LeaseLife uint32
  304. }
  305. func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
  306. func (e *EDNS0_LLQ) pack() ([]byte, error) {
  307. b := make([]byte, 18)
  308. b[0], b[1] = packUint16(e.Version)
  309. b[2], b[3] = packUint16(e.Opcode)
  310. b[4], b[5] = packUint16(e.Error)
  311. b[6] = byte(e.Id >> 56)
  312. b[7] = byte(e.Id >> 48)
  313. b[8] = byte(e.Id >> 40)
  314. b[9] = byte(e.Id >> 32)
  315. b[10] = byte(e.Id >> 24)
  316. b[11] = byte(e.Id >> 16)
  317. b[12] = byte(e.Id >> 8)
  318. b[13] = byte(e.Id)
  319. b[14] = byte(e.LeaseLife >> 24)
  320. b[15] = byte(e.LeaseLife >> 16)
  321. b[16] = byte(e.LeaseLife >> 8)
  322. b[17] = byte(e.LeaseLife)
  323. return b, nil
  324. }
  325. func (e *EDNS0_LLQ) unpack(b []byte) error {
  326. if len(b) < 18 {
  327. return ErrBuf
  328. }
  329. e.Version, _ = unpackUint16(b, 0)
  330. e.Opcode, _ = unpackUint16(b, 2)
  331. e.Error, _ = unpackUint16(b, 4)
  332. e.Id = uint64(b[6])<<56 | uint64(b[6+1])<<48 | uint64(b[6+2])<<40 |
  333. uint64(b[6+3])<<32 | uint64(b[6+4])<<24 | uint64(b[6+5])<<16 | uint64(b[6+6])<<8 | uint64(b[6+7])
  334. e.LeaseLife = uint32(b[14])<<24 | uint32(b[14+1])<<16 | uint32(b[14+2])<<8 | uint32(b[14+3])
  335. return nil
  336. }
  337. func (e *EDNS0_LLQ) String() string {
  338. s := strconv.FormatUint(uint64(e.Version), 10) + " " + strconv.FormatUint(uint64(e.Opcode), 10) +
  339. " " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(uint64(e.Id), 10) +
  340. " " + strconv.FormatUint(uint64(e.LeaseLife), 10)
  341. return s
  342. }
  343. type EDNS0_DAU struct {
  344. Code uint16 // Always EDNS0DAU
  345. AlgCode []uint8
  346. }
  347. func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU }
  348. func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil }
  349. func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil }
  350. func (e *EDNS0_DAU) String() string {
  351. s := ""
  352. for i := 0; i < len(e.AlgCode); i++ {
  353. if a, ok := AlgorithmToString[e.AlgCode[i]]; ok {
  354. s += " " + a
  355. } else {
  356. s += " " + strconv.Itoa(int(e.AlgCode[i]))
  357. }
  358. }
  359. return s
  360. }
  361. type EDNS0_DHU struct {
  362. Code uint16 // Always EDNS0DHU
  363. AlgCode []uint8
  364. }
  365. func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU }
  366. func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil }
  367. func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil }
  368. func (e *EDNS0_DHU) String() string {
  369. s := ""
  370. for i := 0; i < len(e.AlgCode); i++ {
  371. if a, ok := HashToString[e.AlgCode[i]]; ok {
  372. s += " " + a
  373. } else {
  374. s += " " + strconv.Itoa(int(e.AlgCode[i]))
  375. }
  376. }
  377. return s
  378. }
  379. type EDNS0_N3U struct {
  380. Code uint16 // Always EDNS0N3U
  381. AlgCode []uint8
  382. }
  383. func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U }
  384. func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil }
  385. func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil }
  386. func (e *EDNS0_N3U) String() string {
  387. // Re-use the hash map
  388. s := ""
  389. for i := 0; i < len(e.AlgCode); i++ {
  390. if a, ok := HashToString[e.AlgCode[i]]; ok {
  391. s += " " + a
  392. } else {
  393. s += " " + strconv.Itoa(int(e.AlgCode[i]))
  394. }
  395. }
  396. return s
  397. }
  398. type EDNS0_EXPIRE struct {
  399. Code uint16 // Always EDNS0EXPIRE
  400. Expire uint32
  401. }
  402. func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
  403. func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) }
  404. func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
  405. b := make([]byte, 4)
  406. b[0] = byte(e.Expire >> 24)
  407. b[1] = byte(e.Expire >> 16)
  408. b[2] = byte(e.Expire >> 8)
  409. b[3] = byte(e.Expire)
  410. return b, nil
  411. }
  412. func (e *EDNS0_EXPIRE) unpack(b []byte) error {
  413. if len(b) < 4 {
  414. return ErrBuf
  415. }
  416. e.Expire = uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
  417. return nil
  418. }
  419. // The EDNS0_LOCAL option is used for local/experimental purposes. The option
  420. // code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
  421. // (RFC6891), although any unassigned code can actually be used. The content of
  422. // the option is made available in Data, unaltered.
  423. // Basic use pattern for creating a local option:
  424. //
  425. // o := new(dns.OPT)
  426. // o.Hdr.Name = "."
  427. // o.Hdr.Rrtype = dns.TypeOPT
  428. // e := new(dns.EDNS0_LOCAL)
  429. // e.Code = dns.EDNS0LOCALSTART
  430. // e.Data = []byte{72, 82, 74}
  431. // o.Option = append(o.Option, e)
  432. type EDNS0_LOCAL struct {
  433. Code uint16
  434. Data []byte
  435. }
  436. func (e *EDNS0_LOCAL) Option() uint16 { return e.Code }
  437. func (e *EDNS0_LOCAL) String() string {
  438. return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data)
  439. }
  440. func (e *EDNS0_LOCAL) pack() ([]byte, error) {
  441. b := make([]byte, len(e.Data))
  442. copied := copy(b, e.Data)
  443. if copied != len(e.Data) {
  444. return nil, ErrBuf
  445. }
  446. return b, nil
  447. }
  448. func (e *EDNS0_LOCAL) unpack(b []byte) error {
  449. e.Data = make([]byte, len(b))
  450. copied := copy(e.Data, b)
  451. if copied != len(b) {
  452. return ErrBuf
  453. }
  454. return nil
  455. }