msg.go 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159
  1. // DNS packet assembly, see RFC 1035. Converting from - Unpack() -
  2. // and to - Pack() - wire format.
  3. // All the packers and unpackers take a (msg []byte, off int)
  4. // and return (off1 int, ok bool). If they return ok==false, they
  5. // also return off1==len(msg), so that the next unpacker will
  6. // also fail. This lets us avoid checks of ok until the end of a
  7. // packing sequence.
  8. package dns
  9. //go:generate go run msg_generate.go
  10. //go:generate go run compress_generate.go
  11. import (
  12. crand "crypto/rand"
  13. "encoding/binary"
  14. "fmt"
  15. "math/big"
  16. "math/rand"
  17. "strconv"
  18. "sync"
  19. )
  20. const (
  21. maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
  22. maxDomainNameWireOctets = 255 // See RFC 1035 section 2.3.4
  23. )
  24. var (
  25. ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm.
  26. ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication.
  27. ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used is too small for the message.
  28. ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being used before it is initialized.
  29. ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ...
  30. ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot.
  31. ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID.
  32. ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid.
  33. ErrKey error = &Error{err: "bad key"}
  34. ErrKeySize error = &Error{err: "bad key size"}
  35. ErrLongDomain error = &Error{err: fmt.Sprintf("domain name exceeded %d wire-format octets", maxDomainNameWireOctets)}
  36. ErrNoSig error = &Error{err: "no signature found"}
  37. ErrPrivKey error = &Error{err: "bad private key"}
  38. ErrRcode error = &Error{err: "bad rcode"}
  39. ErrRdata error = &Error{err: "bad rdata"}
  40. ErrRRset error = &Error{err: "bad rrset"}
  41. ErrSecret error = &Error{err: "no secrets defined"}
  42. ErrShortRead error = &Error{err: "short read"}
  43. ErrSig error = &Error{err: "bad signature"} // ErrSig indicates that a signature can not be cryptographically validated.
  44. ErrSoa error = &Error{err: "no SOA"} // ErrSOA indicates that no SOA RR was seen when doing zone transfers.
  45. ErrTime error = &Error{err: "bad time"} // ErrTime indicates a timing error in TSIG authentication.
  46. ErrTruncated error = &Error{err: "failed to unpack truncated message"} // ErrTruncated indicates that we failed to unpack a truncated message. We unpacked as much as we had so Msg can still be used, if desired.
  47. )
  48. // Id by default, returns a 16 bits random number to be used as a
  49. // message id. The random provided should be good enough. This being a
  50. // variable the function can be reassigned to a custom function.
  51. // For instance, to make it return a static value:
  52. //
  53. // dns.Id = func() uint16 { return 3 }
  54. var Id func() uint16 = id
  55. var (
  56. idLock sync.Mutex
  57. idRand *rand.Rand
  58. )
  59. // id returns a 16 bits random number to be used as a
  60. // message id. The random provided should be good enough.
  61. func id() uint16 {
  62. idLock.Lock()
  63. if idRand == nil {
  64. // This (partially) works around
  65. // https://github.com/golang/go/issues/11833 by only
  66. // seeding idRand upon the first call to id.
  67. var seed int64
  68. var buf [8]byte
  69. if _, err := crand.Read(buf[:]); err == nil {
  70. seed = int64(binary.LittleEndian.Uint64(buf[:]))
  71. } else {
  72. seed = rand.Int63()
  73. }
  74. idRand = rand.New(rand.NewSource(seed))
  75. }
  76. // The call to idRand.Uint32 must be within the
  77. // mutex lock because *rand.Rand is not safe for
  78. // concurrent use.
  79. //
  80. // There is no added performance overhead to calling
  81. // idRand.Uint32 inside a mutex lock over just
  82. // calling rand.Uint32 as the global math/rand rng
  83. // is internally protected by a sync.Mutex.
  84. id := uint16(idRand.Uint32())
  85. idLock.Unlock()
  86. return id
  87. }
  88. // MsgHdr is a a manually-unpacked version of (id, bits).
  89. type MsgHdr struct {
  90. Id uint16
  91. Response bool
  92. Opcode int
  93. Authoritative bool
  94. Truncated bool
  95. RecursionDesired bool
  96. RecursionAvailable bool
  97. Zero bool
  98. AuthenticatedData bool
  99. CheckingDisabled bool
  100. Rcode int
  101. }
  102. // Msg contains the layout of a DNS message.
  103. type Msg struct {
  104. MsgHdr
  105. Compress bool `json:"-"` // If true, the message will be compressed when converted to wire format.
  106. Question []Question // Holds the RR(s) of the question section.
  107. Answer []RR // Holds the RR(s) of the answer section.
  108. Ns []RR // Holds the RR(s) of the authority section.
  109. Extra []RR // Holds the RR(s) of the additional section.
  110. }
  111. // ClassToString is a maps Classes to strings for each CLASS wire type.
  112. var ClassToString = map[uint16]string{
  113. ClassINET: "IN",
  114. ClassCSNET: "CS",
  115. ClassCHAOS: "CH",
  116. ClassHESIOD: "HS",
  117. ClassNONE: "NONE",
  118. ClassANY: "ANY",
  119. }
  120. // OpcodeToString maps Opcodes to strings.
  121. var OpcodeToString = map[int]string{
  122. OpcodeQuery: "QUERY",
  123. OpcodeIQuery: "IQUERY",
  124. OpcodeStatus: "STATUS",
  125. OpcodeNotify: "NOTIFY",
  126. OpcodeUpdate: "UPDATE",
  127. }
  128. // RcodeToString maps Rcodes to strings.
  129. var RcodeToString = map[int]string{
  130. RcodeSuccess: "NOERROR",
  131. RcodeFormatError: "FORMERR",
  132. RcodeServerFailure: "SERVFAIL",
  133. RcodeNameError: "NXDOMAIN",
  134. RcodeNotImplemented: "NOTIMPL",
  135. RcodeRefused: "REFUSED",
  136. RcodeYXDomain: "YXDOMAIN", // See RFC 2136
  137. RcodeYXRrset: "YXRRSET",
  138. RcodeNXRrset: "NXRRSET",
  139. RcodeNotAuth: "NOTAUTH",
  140. RcodeNotZone: "NOTZONE",
  141. RcodeBadSig: "BADSIG", // Also known as RcodeBadVers, see RFC 6891
  142. // RcodeBadVers: "BADVERS",
  143. RcodeBadKey: "BADKEY",
  144. RcodeBadTime: "BADTIME",
  145. RcodeBadMode: "BADMODE",
  146. RcodeBadName: "BADNAME",
  147. RcodeBadAlg: "BADALG",
  148. RcodeBadTrunc: "BADTRUNC",
  149. RcodeBadCookie: "BADCOOKIE",
  150. }
  151. // Domain names are a sequence of counted strings
  152. // split at the dots. They end with a zero-length string.
  153. // PackDomainName packs a domain name s into msg[off:].
  154. // If compression is wanted compress must be true and the compression
  155. // map needs to hold a mapping between domain names and offsets
  156. // pointing into msg.
  157. func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
  158. off1, _, err = packDomainName(s, msg, off, compression, compress)
  159. return
  160. }
  161. func packDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, labels int, err error) {
  162. // special case if msg == nil
  163. lenmsg := 256
  164. if msg != nil {
  165. lenmsg = len(msg)
  166. }
  167. ls := len(s)
  168. if ls == 0 { // Ok, for instance when dealing with update RR without any rdata.
  169. return off, 0, nil
  170. }
  171. // If not fully qualified, error out, but only if msg == nil #ugly
  172. switch {
  173. case msg == nil:
  174. if s[ls-1] != '.' {
  175. s += "."
  176. ls++
  177. }
  178. case msg != nil:
  179. if s[ls-1] != '.' {
  180. return lenmsg, 0, ErrFqdn
  181. }
  182. }
  183. // Each dot ends a segment of the name.
  184. // We trade each dot byte for a length byte.
  185. // Except for escaped dots (\.), which are normal dots.
  186. // There is also a trailing zero.
  187. // Compression
  188. nameoffset := -1
  189. pointer := -1
  190. // Emit sequence of counted strings, chopping at dots.
  191. begin := 0
  192. bs := []byte(s)
  193. roBs, bsFresh, escapedDot := s, true, false
  194. for i := 0; i < ls; i++ {
  195. if bs[i] == '\\' {
  196. for j := i; j < ls-1; j++ {
  197. bs[j] = bs[j+1]
  198. }
  199. ls--
  200. if off+1 > lenmsg {
  201. return lenmsg, labels, ErrBuf
  202. }
  203. // check for \DDD
  204. if i+2 < ls && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
  205. bs[i] = dddToByte(bs[i:])
  206. for j := i + 1; j < ls-2; j++ {
  207. bs[j] = bs[j+2]
  208. }
  209. ls -= 2
  210. }
  211. escapedDot = bs[i] == '.'
  212. bsFresh = false
  213. continue
  214. }
  215. if bs[i] == '.' {
  216. if i > 0 && bs[i-1] == '.' && !escapedDot {
  217. // two dots back to back is not legal
  218. return lenmsg, labels, ErrRdata
  219. }
  220. if i-begin >= 1<<6 { // top two bits of length must be clear
  221. return lenmsg, labels, ErrRdata
  222. }
  223. // off can already (we're in a loop) be bigger than len(msg)
  224. // this happens when a name isn't fully qualified
  225. if off+1 > lenmsg {
  226. return lenmsg, labels, ErrBuf
  227. }
  228. if msg != nil {
  229. msg[off] = byte(i - begin)
  230. }
  231. offset := off
  232. off++
  233. for j := begin; j < i; j++ {
  234. if off+1 > lenmsg {
  235. return lenmsg, labels, ErrBuf
  236. }
  237. if msg != nil {
  238. msg[off] = bs[j]
  239. }
  240. off++
  241. }
  242. if compress && !bsFresh {
  243. roBs = string(bs)
  244. bsFresh = true
  245. }
  246. // Don't try to compress '.'
  247. // We should only compress when compress it true, but we should also still pick
  248. // up names that can be used for *future* compression(s).
  249. if compression != nil && roBs[begin:] != "." {
  250. if p, ok := compression[roBs[begin:]]; !ok {
  251. // Only offsets smaller than this can be used.
  252. if offset < maxCompressionOffset {
  253. compression[roBs[begin:]] = offset
  254. }
  255. } else {
  256. // The first hit is the longest matching dname
  257. // keep the pointer offset we get back and store
  258. // the offset of the current name, because that's
  259. // where we need to insert the pointer later
  260. // If compress is true, we're allowed to compress this dname
  261. if pointer == -1 && compress {
  262. pointer = p // Where to point to
  263. nameoffset = offset // Where to point from
  264. break
  265. }
  266. }
  267. }
  268. labels++
  269. begin = i + 1
  270. }
  271. escapedDot = false
  272. }
  273. // Root label is special
  274. if len(bs) == 1 && bs[0] == '.' {
  275. return off, labels, nil
  276. }
  277. // If we did compression and we find something add the pointer here
  278. if pointer != -1 {
  279. // We have two bytes (14 bits) to put the pointer in
  280. // if msg == nil, we will never do compression
  281. binary.BigEndian.PutUint16(msg[nameoffset:], uint16(pointer^0xC000))
  282. off = nameoffset + 1
  283. goto End
  284. }
  285. if msg != nil && off < len(msg) {
  286. msg[off] = 0
  287. }
  288. End:
  289. off++
  290. return off, labels, nil
  291. }
  292. // Unpack a domain name.
  293. // In addition to the simple sequences of counted strings above,
  294. // domain names are allowed to refer to strings elsewhere in the
  295. // packet, to avoid repeating common suffixes when returning
  296. // many entries in a single domain. The pointers are marked
  297. // by a length byte with the top two bits set. Ignoring those
  298. // two bits, that byte and the next give a 14 bit offset from msg[0]
  299. // where we should pick up the trail.
  300. // Note that if we jump elsewhere in the packet,
  301. // we return off1 == the offset after the first pointer we found,
  302. // which is where the next record will start.
  303. // In theory, the pointers are only allowed to jump backward.
  304. // We let them jump anywhere and stop jumping after a while.
  305. // UnpackDomainName unpacks a domain name into a string.
  306. func UnpackDomainName(msg []byte, off int) (string, int, error) {
  307. s := make([]byte, 0, 64)
  308. off1 := 0
  309. lenmsg := len(msg)
  310. maxLen := maxDomainNameWireOctets
  311. ptr := 0 // number of pointers followed
  312. Loop:
  313. for {
  314. if off >= lenmsg {
  315. return "", lenmsg, ErrBuf
  316. }
  317. c := int(msg[off])
  318. off++
  319. switch c & 0xC0 {
  320. case 0x00:
  321. if c == 0x00 {
  322. // end of name
  323. break Loop
  324. }
  325. // literal string
  326. if off+c > lenmsg {
  327. return "", lenmsg, ErrBuf
  328. }
  329. for j := off; j < off+c; j++ {
  330. switch b := msg[j]; b {
  331. case '.', '(', ')', ';', ' ', '@':
  332. fallthrough
  333. case '"', '\\':
  334. s = append(s, '\\', b)
  335. // presentation-format \X escapes add an extra byte
  336. maxLen += 1
  337. default:
  338. if b < 32 || b >= 127 { // unprintable, use \DDD
  339. var buf [3]byte
  340. bufs := strconv.AppendInt(buf[:0], int64(b), 10)
  341. s = append(s, '\\')
  342. for i := 0; i < 3-len(bufs); i++ {
  343. s = append(s, '0')
  344. }
  345. for _, r := range bufs {
  346. s = append(s, r)
  347. }
  348. // presentation-format \DDD escapes add 3 extra bytes
  349. maxLen += 3
  350. } else {
  351. s = append(s, b)
  352. }
  353. }
  354. }
  355. s = append(s, '.')
  356. off += c
  357. case 0xC0:
  358. // pointer to somewhere else in msg.
  359. // remember location after first ptr,
  360. // since that's how many bytes we consumed.
  361. // also, don't follow too many pointers --
  362. // maybe there's a loop.
  363. if off >= lenmsg {
  364. return "", lenmsg, ErrBuf
  365. }
  366. c1 := msg[off]
  367. off++
  368. if ptr == 0 {
  369. off1 = off
  370. }
  371. if ptr++; ptr > 10 {
  372. return "", lenmsg, &Error{err: "too many compression pointers"}
  373. }
  374. // pointer should guarantee that it advances and points forwards at least
  375. // but the condition on previous three lines guarantees that it's
  376. // at least loop-free
  377. off = (c^0xC0)<<8 | int(c1)
  378. default:
  379. // 0x80 and 0x40 are reserved
  380. return "", lenmsg, ErrRdata
  381. }
  382. }
  383. if ptr == 0 {
  384. off1 = off
  385. }
  386. if len(s) == 0 {
  387. s = []byte(".")
  388. } else if len(s) >= maxLen {
  389. // error if the name is too long, but don't throw it away
  390. return string(s), lenmsg, ErrLongDomain
  391. }
  392. return string(s), off1, nil
  393. }
  394. func packTxt(txt []string, msg []byte, offset int, tmp []byte) (int, error) {
  395. if len(txt) == 0 {
  396. if offset >= len(msg) {
  397. return offset, ErrBuf
  398. }
  399. msg[offset] = 0
  400. return offset, nil
  401. }
  402. var err error
  403. for i := range txt {
  404. if len(txt[i]) > len(tmp) {
  405. return offset, ErrBuf
  406. }
  407. offset, err = packTxtString(txt[i], msg, offset, tmp)
  408. if err != nil {
  409. return offset, err
  410. }
  411. }
  412. return offset, nil
  413. }
  414. func packTxtString(s string, msg []byte, offset int, tmp []byte) (int, error) {
  415. lenByteOffset := offset
  416. if offset >= len(msg) || len(s) > len(tmp) {
  417. return offset, ErrBuf
  418. }
  419. offset++
  420. bs := tmp[:len(s)]
  421. copy(bs, s)
  422. for i := 0; i < len(bs); i++ {
  423. if len(msg) <= offset {
  424. return offset, ErrBuf
  425. }
  426. if bs[i] == '\\' {
  427. i++
  428. if i == len(bs) {
  429. break
  430. }
  431. // check for \DDD
  432. if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
  433. msg[offset] = dddToByte(bs[i:])
  434. i += 2
  435. } else {
  436. msg[offset] = bs[i]
  437. }
  438. } else {
  439. msg[offset] = bs[i]
  440. }
  441. offset++
  442. }
  443. l := offset - lenByteOffset - 1
  444. if l > 255 {
  445. return offset, &Error{err: "string exceeded 255 bytes in txt"}
  446. }
  447. msg[lenByteOffset] = byte(l)
  448. return offset, nil
  449. }
  450. func packOctetString(s string, msg []byte, offset int, tmp []byte) (int, error) {
  451. if offset >= len(msg) || len(s) > len(tmp) {
  452. return offset, ErrBuf
  453. }
  454. bs := tmp[:len(s)]
  455. copy(bs, s)
  456. for i := 0; i < len(bs); i++ {
  457. if len(msg) <= offset {
  458. return offset, ErrBuf
  459. }
  460. if bs[i] == '\\' {
  461. i++
  462. if i == len(bs) {
  463. break
  464. }
  465. // check for \DDD
  466. if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
  467. msg[offset] = dddToByte(bs[i:])
  468. i += 2
  469. } else {
  470. msg[offset] = bs[i]
  471. }
  472. } else {
  473. msg[offset] = bs[i]
  474. }
  475. offset++
  476. }
  477. return offset, nil
  478. }
  479. func unpackTxt(msg []byte, off0 int) (ss []string, off int, err error) {
  480. off = off0
  481. var s string
  482. for off < len(msg) && err == nil {
  483. s, off, err = unpackTxtString(msg, off)
  484. if err == nil {
  485. ss = append(ss, s)
  486. }
  487. }
  488. return
  489. }
  490. func unpackTxtString(msg []byte, offset int) (string, int, error) {
  491. if offset+1 > len(msg) {
  492. return "", offset, &Error{err: "overflow unpacking txt"}
  493. }
  494. l := int(msg[offset])
  495. if offset+l+1 > len(msg) {
  496. return "", offset, &Error{err: "overflow unpacking txt"}
  497. }
  498. s := make([]byte, 0, l)
  499. for _, b := range msg[offset+1 : offset+1+l] {
  500. switch b {
  501. case '"', '\\':
  502. s = append(s, '\\', b)
  503. default:
  504. if b < 32 || b > 127 { // unprintable
  505. var buf [3]byte
  506. bufs := strconv.AppendInt(buf[:0], int64(b), 10)
  507. s = append(s, '\\')
  508. for i := 0; i < 3-len(bufs); i++ {
  509. s = append(s, '0')
  510. }
  511. for _, r := range bufs {
  512. s = append(s, r)
  513. }
  514. } else {
  515. s = append(s, b)
  516. }
  517. }
  518. }
  519. offset += 1 + l
  520. return string(s), offset, nil
  521. }
  522. // Helpers for dealing with escaped bytes
  523. func isDigit(b byte) bool { return b >= '0' && b <= '9' }
  524. func dddToByte(s []byte) byte {
  525. return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0'))
  526. }
  527. // Helper function for packing and unpacking
  528. func intToBytes(i *big.Int, length int) []byte {
  529. buf := i.Bytes()
  530. if len(buf) < length {
  531. b := make([]byte, length)
  532. copy(b[length-len(buf):], buf)
  533. return b
  534. }
  535. return buf
  536. }
  537. // PackRR packs a resource record rr into msg[off:].
  538. // See PackDomainName for documentation about the compression.
  539. func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
  540. if rr == nil {
  541. return len(msg), &Error{err: "nil rr"}
  542. }
  543. off1, err = rr.pack(msg, off, compression, compress)
  544. if err != nil {
  545. return len(msg), err
  546. }
  547. // TODO(miek): Not sure if this is needed? If removed we can remove rawmsg.go as well.
  548. if rawSetRdlength(msg, off, off1) {
  549. return off1, nil
  550. }
  551. return off, ErrRdata
  552. }
  553. // UnpackRR unpacks msg[off:] into an RR.
  554. func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) {
  555. h, off, msg, err := unpackHeader(msg, off)
  556. if err != nil {
  557. return nil, len(msg), err
  558. }
  559. end := off + int(h.Rdlength)
  560. if fn, known := typeToUnpack[h.Rrtype]; !known {
  561. rr, off, err = unpackRFC3597(h, msg, off)
  562. } else {
  563. rr, off, err = fn(h, msg, off)
  564. }
  565. if off != end {
  566. return &h, end, &Error{err: "bad rdlength"}
  567. }
  568. return rr, off, err
  569. }
  570. // unpackRRslice unpacks msg[off:] into an []RR.
  571. // If we cannot unpack the whole array, then it will return nil
  572. func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error) {
  573. var r RR
  574. // Optimistically make dst be the length that was sent
  575. dst := make([]RR, 0, l)
  576. for i := 0; i < l; i++ {
  577. off1 := off
  578. r, off, err = UnpackRR(msg, off)
  579. if err != nil {
  580. off = len(msg)
  581. break
  582. }
  583. // If offset does not increase anymore, l is a lie
  584. if off1 == off {
  585. l = i
  586. break
  587. }
  588. dst = append(dst, r)
  589. }
  590. if err != nil && off == len(msg) {
  591. dst = nil
  592. }
  593. return dst, off, err
  594. }
  595. // Convert a MsgHdr to a string, with dig-like headers:
  596. //
  597. //;; opcode: QUERY, status: NOERROR, id: 48404
  598. //
  599. //;; flags: qr aa rd ra;
  600. func (h *MsgHdr) String() string {
  601. if h == nil {
  602. return "<nil> MsgHdr"
  603. }
  604. s := ";; opcode: " + OpcodeToString[h.Opcode]
  605. s += ", status: " + RcodeToString[h.Rcode]
  606. s += ", id: " + strconv.Itoa(int(h.Id)) + "\n"
  607. s += ";; flags:"
  608. if h.Response {
  609. s += " qr"
  610. }
  611. if h.Authoritative {
  612. s += " aa"
  613. }
  614. if h.Truncated {
  615. s += " tc"
  616. }
  617. if h.RecursionDesired {
  618. s += " rd"
  619. }
  620. if h.RecursionAvailable {
  621. s += " ra"
  622. }
  623. if h.Zero { // Hmm
  624. s += " z"
  625. }
  626. if h.AuthenticatedData {
  627. s += " ad"
  628. }
  629. if h.CheckingDisabled {
  630. s += " cd"
  631. }
  632. s += ";"
  633. return s
  634. }
  635. // Pack packs a Msg: it is converted to to wire format.
  636. // If the dns.Compress is true the message will be in compressed wire format.
  637. func (dns *Msg) Pack() (msg []byte, err error) {
  638. return dns.PackBuffer(nil)
  639. }
  640. // PackBuffer packs a Msg, using the given buffer buf. If buf is too small
  641. // a new buffer is allocated.
  642. func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
  643. // We use a similar function in tsig.go's stripTsig.
  644. var (
  645. dh Header
  646. compression map[string]int
  647. )
  648. if dns.Compress {
  649. compression = make(map[string]int) // Compression pointer mappings
  650. }
  651. if dns.Rcode < 0 || dns.Rcode > 0xFFF {
  652. return nil, ErrRcode
  653. }
  654. if dns.Rcode > 0xF {
  655. // Regular RCODE field is 4 bits
  656. opt := dns.IsEdns0()
  657. if opt == nil {
  658. return nil, ErrExtendedRcode
  659. }
  660. opt.SetExtendedRcode(uint8(dns.Rcode >> 4))
  661. dns.Rcode &= 0xF
  662. }
  663. // Convert convenient Msg into wire-like Header.
  664. dh.Id = dns.Id
  665. dh.Bits = uint16(dns.Opcode)<<11 | uint16(dns.Rcode)
  666. if dns.Response {
  667. dh.Bits |= _QR
  668. }
  669. if dns.Authoritative {
  670. dh.Bits |= _AA
  671. }
  672. if dns.Truncated {
  673. dh.Bits |= _TC
  674. }
  675. if dns.RecursionDesired {
  676. dh.Bits |= _RD
  677. }
  678. if dns.RecursionAvailable {
  679. dh.Bits |= _RA
  680. }
  681. if dns.Zero {
  682. dh.Bits |= _Z
  683. }
  684. if dns.AuthenticatedData {
  685. dh.Bits |= _AD
  686. }
  687. if dns.CheckingDisabled {
  688. dh.Bits |= _CD
  689. }
  690. // Prepare variable sized arrays.
  691. question := dns.Question
  692. answer := dns.Answer
  693. ns := dns.Ns
  694. extra := dns.Extra
  695. dh.Qdcount = uint16(len(question))
  696. dh.Ancount = uint16(len(answer))
  697. dh.Nscount = uint16(len(ns))
  698. dh.Arcount = uint16(len(extra))
  699. // We need the uncompressed length here, because we first pack it and then compress it.
  700. msg = buf
  701. uncompressedLen := compressedLen(dns, false)
  702. if packLen := uncompressedLen + 1; len(msg) < packLen {
  703. msg = make([]byte, packLen)
  704. }
  705. // Pack it in: header and then the pieces.
  706. off := 0
  707. off, err = dh.pack(msg, off, compression, dns.Compress)
  708. if err != nil {
  709. return nil, err
  710. }
  711. for i := 0; i < len(question); i++ {
  712. off, err = question[i].pack(msg, off, compression, dns.Compress)
  713. if err != nil {
  714. return nil, err
  715. }
  716. }
  717. for i := 0; i < len(answer); i++ {
  718. off, err = PackRR(answer[i], msg, off, compression, dns.Compress)
  719. if err != nil {
  720. return nil, err
  721. }
  722. }
  723. for i := 0; i < len(ns); i++ {
  724. off, err = PackRR(ns[i], msg, off, compression, dns.Compress)
  725. if err != nil {
  726. return nil, err
  727. }
  728. }
  729. for i := 0; i < len(extra); i++ {
  730. off, err = PackRR(extra[i], msg, off, compression, dns.Compress)
  731. if err != nil {
  732. return nil, err
  733. }
  734. }
  735. return msg[:off], nil
  736. }
  737. // Unpack unpacks a binary message to a Msg structure.
  738. func (dns *Msg) Unpack(msg []byte) (err error) {
  739. var (
  740. dh Header
  741. off int
  742. )
  743. if dh, off, err = unpackMsgHdr(msg, off); err != nil {
  744. return err
  745. }
  746. dns.Id = dh.Id
  747. dns.Response = (dh.Bits & _QR) != 0
  748. dns.Opcode = int(dh.Bits>>11) & 0xF
  749. dns.Authoritative = (dh.Bits & _AA) != 0
  750. dns.Truncated = (dh.Bits & _TC) != 0
  751. dns.RecursionDesired = (dh.Bits & _RD) != 0
  752. dns.RecursionAvailable = (dh.Bits & _RA) != 0
  753. dns.Zero = (dh.Bits & _Z) != 0
  754. dns.AuthenticatedData = (dh.Bits & _AD) != 0
  755. dns.CheckingDisabled = (dh.Bits & _CD) != 0
  756. dns.Rcode = int(dh.Bits & 0xF)
  757. if off == len(msg) {
  758. return ErrTruncated
  759. }
  760. // Optimistically use the count given to us in the header
  761. dns.Question = make([]Question, 0, int(dh.Qdcount))
  762. for i := 0; i < int(dh.Qdcount); i++ {
  763. off1 := off
  764. var q Question
  765. q, off, err = unpackQuestion(msg, off)
  766. if err != nil {
  767. // Even if Truncated is set, we only will set ErrTruncated if we
  768. // actually got the questions
  769. return err
  770. }
  771. if off1 == off { // Offset does not increase anymore, dh.Qdcount is a lie!
  772. dh.Qdcount = uint16(i)
  773. break
  774. }
  775. dns.Question = append(dns.Question, q)
  776. }
  777. dns.Answer, off, err = unpackRRslice(int(dh.Ancount), msg, off)
  778. // The header counts might have been wrong so we need to update it
  779. dh.Ancount = uint16(len(dns.Answer))
  780. if err == nil {
  781. dns.Ns, off, err = unpackRRslice(int(dh.Nscount), msg, off)
  782. }
  783. // The header counts might have been wrong so we need to update it
  784. dh.Nscount = uint16(len(dns.Ns))
  785. if err == nil {
  786. dns.Extra, off, err = unpackRRslice(int(dh.Arcount), msg, off)
  787. }
  788. // The header counts might have been wrong so we need to update it
  789. dh.Arcount = uint16(len(dns.Extra))
  790. if off != len(msg) {
  791. // TODO(miek) make this an error?
  792. // use PackOpt to let people tell how detailed the error reporting should be?
  793. // println("dns: extra bytes in dns packet", off, "<", len(msg))
  794. } else if dns.Truncated {
  795. // Whether we ran into a an error or not, we want to return that it
  796. // was truncated
  797. err = ErrTruncated
  798. }
  799. return err
  800. }
  801. // Convert a complete message to a string with dig-like output.
  802. func (dns *Msg) String() string {
  803. if dns == nil {
  804. return "<nil> MsgHdr"
  805. }
  806. s := dns.MsgHdr.String() + " "
  807. s += "QUERY: " + strconv.Itoa(len(dns.Question)) + ", "
  808. s += "ANSWER: " + strconv.Itoa(len(dns.Answer)) + ", "
  809. s += "AUTHORITY: " + strconv.Itoa(len(dns.Ns)) + ", "
  810. s += "ADDITIONAL: " + strconv.Itoa(len(dns.Extra)) + "\n"
  811. if len(dns.Question) > 0 {
  812. s += "\n;; QUESTION SECTION:\n"
  813. for i := 0; i < len(dns.Question); i++ {
  814. s += dns.Question[i].String() + "\n"
  815. }
  816. }
  817. if len(dns.Answer) > 0 {
  818. s += "\n;; ANSWER SECTION:\n"
  819. for i := 0; i < len(dns.Answer); i++ {
  820. if dns.Answer[i] != nil {
  821. s += dns.Answer[i].String() + "\n"
  822. }
  823. }
  824. }
  825. if len(dns.Ns) > 0 {
  826. s += "\n;; AUTHORITY SECTION:\n"
  827. for i := 0; i < len(dns.Ns); i++ {
  828. if dns.Ns[i] != nil {
  829. s += dns.Ns[i].String() + "\n"
  830. }
  831. }
  832. }
  833. if len(dns.Extra) > 0 {
  834. s += "\n;; ADDITIONAL SECTION:\n"
  835. for i := 0; i < len(dns.Extra); i++ {
  836. if dns.Extra[i] != nil {
  837. s += dns.Extra[i].String() + "\n"
  838. }
  839. }
  840. }
  841. return s
  842. }
  843. // Len returns the message length when in (un)compressed wire format.
  844. // If dns.Compress is true compression it is taken into account. Len()
  845. // is provided to be a faster way to get the size of the resulting packet,
  846. // than packing it, measuring the size and discarding the buffer.
  847. func (dns *Msg) Len() int { return compressedLen(dns, dns.Compress) }
  848. // compressedLen returns the message length when in compressed wire format
  849. // when compress is true, otherwise the uncompressed length is returned.
  850. func compressedLen(dns *Msg, compress bool) int {
  851. // We always return one more than needed.
  852. l := 12 // Message header is always 12 bytes
  853. compression := map[string]int{}
  854. for i := 0; i < len(dns.Question); i++ {
  855. l += dns.Question[i].len()
  856. if compress {
  857. compressionLenHelper(compression, dns.Question[i].Name)
  858. }
  859. }
  860. for i := 0; i < len(dns.Answer); i++ {
  861. if dns.Answer[i] == nil {
  862. continue
  863. }
  864. l += dns.Answer[i].len()
  865. if compress {
  866. k, ok := compressionLenSearch(compression, dns.Answer[i].Header().Name)
  867. if ok {
  868. l += 1 - k
  869. }
  870. compressionLenHelper(compression, dns.Answer[i].Header().Name)
  871. k, ok = compressionLenSearchType(compression, dns.Answer[i])
  872. if ok {
  873. l += 1 - k
  874. }
  875. compressionLenHelperType(compression, dns.Answer[i])
  876. }
  877. }
  878. for i := 0; i < len(dns.Ns); i++ {
  879. if dns.Ns[i] == nil {
  880. continue
  881. }
  882. l += dns.Ns[i].len()
  883. if compress {
  884. k, ok := compressionLenSearch(compression, dns.Ns[i].Header().Name)
  885. if ok {
  886. l += 1 - k
  887. }
  888. compressionLenHelper(compression, dns.Ns[i].Header().Name)
  889. k, ok = compressionLenSearchType(compression, dns.Ns[i])
  890. if ok {
  891. l += 1 - k
  892. }
  893. compressionLenHelperType(compression, dns.Ns[i])
  894. }
  895. }
  896. for i := 0; i < len(dns.Extra); i++ {
  897. if dns.Extra[i] == nil {
  898. continue
  899. }
  900. l += dns.Extra[i].len()
  901. if compress {
  902. k, ok := compressionLenSearch(compression, dns.Extra[i].Header().Name)
  903. if ok {
  904. l += 1 - k
  905. }
  906. compressionLenHelper(compression, dns.Extra[i].Header().Name)
  907. k, ok = compressionLenSearchType(compression, dns.Extra[i])
  908. if ok {
  909. l += 1 - k
  910. }
  911. compressionLenHelperType(compression, dns.Extra[i])
  912. }
  913. }
  914. return l
  915. }
  916. // Put the parts of the name in the compression map.
  917. func compressionLenHelper(c map[string]int, s string) {
  918. pref := ""
  919. lbs := Split(s)
  920. for j := len(lbs) - 1; j >= 0; j-- {
  921. pref = s[lbs[j]:]
  922. if _, ok := c[pref]; !ok {
  923. c[pref] = len(pref)
  924. }
  925. }
  926. }
  927. // Look for each part in the compression map and returns its length,
  928. // keep on searching so we get the longest match.
  929. func compressionLenSearch(c map[string]int, s string) (int, bool) {
  930. off := 0
  931. end := false
  932. if s == "" { // don't bork on bogus data
  933. return 0, false
  934. }
  935. for {
  936. if _, ok := c[s[off:]]; ok {
  937. return len(s[off:]), true
  938. }
  939. if end {
  940. break
  941. }
  942. off, end = NextLabel(s, off)
  943. }
  944. return 0, false
  945. }
  946. // Copy returns a new RR which is a deep-copy of r.
  947. func Copy(r RR) RR { r1 := r.copy(); return r1 }
  948. // Len returns the length (in octets) of the uncompressed RR in wire format.
  949. func Len(r RR) int { return r.len() }
  950. // Copy returns a new *Msg which is a deep-copy of dns.
  951. func (dns *Msg) Copy() *Msg { return dns.CopyTo(new(Msg)) }
  952. // CopyTo copies the contents to the provided message using a deep-copy and returns the copy.
  953. func (dns *Msg) CopyTo(r1 *Msg) *Msg {
  954. r1.MsgHdr = dns.MsgHdr
  955. r1.Compress = dns.Compress
  956. if len(dns.Question) > 0 {
  957. r1.Question = make([]Question, len(dns.Question))
  958. copy(r1.Question, dns.Question) // TODO(miek): Question is an immutable value, ok to do a shallow-copy
  959. }
  960. rrArr := make([]RR, len(dns.Answer)+len(dns.Ns)+len(dns.Extra))
  961. var rri int
  962. if len(dns.Answer) > 0 {
  963. rrbegin := rri
  964. for i := 0; i < len(dns.Answer); i++ {
  965. rrArr[rri] = dns.Answer[i].copy()
  966. rri++
  967. }
  968. r1.Answer = rrArr[rrbegin:rri:rri]
  969. }
  970. if len(dns.Ns) > 0 {
  971. rrbegin := rri
  972. for i := 0; i < len(dns.Ns); i++ {
  973. rrArr[rri] = dns.Ns[i].copy()
  974. rri++
  975. }
  976. r1.Ns = rrArr[rrbegin:rri:rri]
  977. }
  978. if len(dns.Extra) > 0 {
  979. rrbegin := rri
  980. for i := 0; i < len(dns.Extra); i++ {
  981. rrArr[rri] = dns.Extra[i].copy()
  982. rri++
  983. }
  984. r1.Extra = rrArr[rrbegin:rri:rri]
  985. }
  986. return r1
  987. }
  988. func (q *Question) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
  989. off, err := PackDomainName(q.Name, msg, off, compression, compress)
  990. if err != nil {
  991. return off, err
  992. }
  993. off, err = packUint16(q.Qtype, msg, off)
  994. if err != nil {
  995. return off, err
  996. }
  997. off, err = packUint16(q.Qclass, msg, off)
  998. if err != nil {
  999. return off, err
  1000. }
  1001. return off, nil
  1002. }
  1003. func unpackQuestion(msg []byte, off int) (Question, int, error) {
  1004. var (
  1005. q Question
  1006. err error
  1007. )
  1008. q.Name, off, err = UnpackDomainName(msg, off)
  1009. if err != nil {
  1010. return q, off, err
  1011. }
  1012. if off == len(msg) {
  1013. return q, off, nil
  1014. }
  1015. q.Qtype, off, err = unpackUint16(msg, off)
  1016. if err != nil {
  1017. return q, off, err
  1018. }
  1019. if off == len(msg) {
  1020. return q, off, nil
  1021. }
  1022. q.Qclass, off, err = unpackUint16(msg, off)
  1023. if off == len(msg) {
  1024. return q, off, nil
  1025. }
  1026. return q, off, err
  1027. }
  1028. func (dh *Header) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
  1029. off, err := packUint16(dh.Id, msg, off)
  1030. if err != nil {
  1031. return off, err
  1032. }
  1033. off, err = packUint16(dh.Bits, msg, off)
  1034. if err != nil {
  1035. return off, err
  1036. }
  1037. off, err = packUint16(dh.Qdcount, msg, off)
  1038. if err != nil {
  1039. return off, err
  1040. }
  1041. off, err = packUint16(dh.Ancount, msg, off)
  1042. if err != nil {
  1043. return off, err
  1044. }
  1045. off, err = packUint16(dh.Nscount, msg, off)
  1046. if err != nil {
  1047. return off, err
  1048. }
  1049. off, err = packUint16(dh.Arcount, msg, off)
  1050. return off, err
  1051. }
  1052. func unpackMsgHdr(msg []byte, off int) (Header, int, error) {
  1053. var (
  1054. dh Header
  1055. err error
  1056. )
  1057. dh.Id, off, err = unpackUint16(msg, off)
  1058. if err != nil {
  1059. return dh, off, err
  1060. }
  1061. dh.Bits, off, err = unpackUint16(msg, off)
  1062. if err != nil {
  1063. return dh, off, err
  1064. }
  1065. dh.Qdcount, off, err = unpackUint16(msg, off)
  1066. if err != nil {
  1067. return dh, off, err
  1068. }
  1069. dh.Ancount, off, err = unpackUint16(msg, off)
  1070. if err != nil {
  1071. return dh, off, err
  1072. }
  1073. dh.Nscount, off, err = unpackUint16(msg, off)
  1074. if err != nil {
  1075. return dh, off, err
  1076. }
  1077. dh.Arcount, off, err = unpackUint16(msg, off)
  1078. return dh, off, err
  1079. }