msg.go 33 KB

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