msg.go 31 KB

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