edns.go 15 KB

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