message_test.go 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package dnsmessage
  5. import (
  6. "bytes"
  7. "fmt"
  8. "reflect"
  9. "strings"
  10. "testing"
  11. )
  12. func mustNewName(name string) Name {
  13. n, err := NewName(name)
  14. if err != nil {
  15. panic(err)
  16. }
  17. return n
  18. }
  19. func mustEDNS0ResourceHeader(l int, extrc RCode, do bool) ResourceHeader {
  20. h := ResourceHeader{Class: ClassINET}
  21. if err := h.SetEDNS0(l, extrc, do); err != nil {
  22. panic(err)
  23. }
  24. return h
  25. }
  26. func (m *Message) String() string {
  27. s := fmt.Sprintf("Message: %#v\n", &m.Header)
  28. if len(m.Questions) > 0 {
  29. s += "-- Questions\n"
  30. for _, q := range m.Questions {
  31. s += fmt.Sprintf("%#v\n", q)
  32. }
  33. }
  34. if len(m.Answers) > 0 {
  35. s += "-- Answers\n"
  36. for _, a := range m.Answers {
  37. s += fmt.Sprintf("%#v\n", a)
  38. }
  39. }
  40. if len(m.Authorities) > 0 {
  41. s += "-- Authorities\n"
  42. for _, ns := range m.Authorities {
  43. s += fmt.Sprintf("%#v\n", ns)
  44. }
  45. }
  46. if len(m.Additionals) > 0 {
  47. s += "-- Additionals\n"
  48. for _, e := range m.Additionals {
  49. s += fmt.Sprintf("%#v\n", e)
  50. }
  51. }
  52. return s
  53. }
  54. func TestNameString(t *testing.T) {
  55. want := "foo"
  56. name := mustNewName(want)
  57. if got := fmt.Sprint(name); got != want {
  58. t.Errorf("got fmt.Sprint(%#v) = %s, want = %s", name, got, want)
  59. }
  60. }
  61. func TestQuestionPackUnpack(t *testing.T) {
  62. want := Question{
  63. Name: mustNewName("."),
  64. Type: TypeA,
  65. Class: ClassINET,
  66. }
  67. buf, err := want.pack(make([]byte, 1, 50), map[string]int{}, 1)
  68. if err != nil {
  69. t.Fatal("Question.pack() =", err)
  70. }
  71. var p Parser
  72. p.msg = buf
  73. p.header.questions = 1
  74. p.section = sectionQuestions
  75. p.off = 1
  76. got, err := p.Question()
  77. if err != nil {
  78. t.Fatalf("Parser{%q}.Question() = %v", string(buf[1:]), err)
  79. }
  80. if p.off != len(buf) {
  81. t.Errorf("unpacked different amount than packed: got = %d, want = %d", p.off, len(buf))
  82. }
  83. if !reflect.DeepEqual(got, want) {
  84. t.Errorf("got from Parser.Question() = %+v, want = %+v", got, want)
  85. }
  86. }
  87. func TestName(t *testing.T) {
  88. tests := []string{
  89. "",
  90. ".",
  91. "google..com",
  92. "google.com",
  93. "google..com.",
  94. "google.com.",
  95. ".google.com.",
  96. "www..google.com.",
  97. "www.google.com.",
  98. }
  99. for _, test := range tests {
  100. n, err := NewName(test)
  101. if err != nil {
  102. t.Errorf("NewName(%q) = %v", test, err)
  103. continue
  104. }
  105. if ns := n.String(); ns != test {
  106. t.Errorf("got %#v.String() = %q, want = %q", n, ns, test)
  107. continue
  108. }
  109. }
  110. }
  111. func TestNamePackUnpack(t *testing.T) {
  112. tests := []struct {
  113. in string
  114. want string
  115. err error
  116. }{
  117. {"", "", errNonCanonicalName},
  118. {".", ".", nil},
  119. {"google..com", "", errNonCanonicalName},
  120. {"google.com", "", errNonCanonicalName},
  121. {"google..com.", "", errZeroSegLen},
  122. {"google.com.", "google.com.", nil},
  123. {".google.com.", "", errZeroSegLen},
  124. {"www..google.com.", "", errZeroSegLen},
  125. {"www.google.com.", "www.google.com.", nil},
  126. }
  127. for _, test := range tests {
  128. in := mustNewName(test.in)
  129. want := mustNewName(test.want)
  130. buf, err := in.pack(make([]byte, 0, 30), map[string]int{}, 0)
  131. if err != test.err {
  132. t.Errorf("got %q.pack() = %v, want = %v", test.in, err, test.err)
  133. continue
  134. }
  135. if test.err != nil {
  136. continue
  137. }
  138. var got Name
  139. n, err := got.unpack(buf, 0)
  140. if err != nil {
  141. t.Errorf("%q.unpack() = %v", test.in, err)
  142. continue
  143. }
  144. if n != len(buf) {
  145. t.Errorf(
  146. "unpacked different amount than packed for %q: got = %d, want = %d",
  147. test.in,
  148. n,
  149. len(buf),
  150. )
  151. }
  152. if got != want {
  153. t.Errorf("unpacking packing of %q: got = %#v, want = %#v", test.in, got, want)
  154. }
  155. }
  156. }
  157. func TestIncompressibleName(t *testing.T) {
  158. name := mustNewName("example.com.")
  159. compression := map[string]int{}
  160. buf, err := name.pack(make([]byte, 0, 100), compression, 0)
  161. if err != nil {
  162. t.Fatal("first Name.pack() =", err)
  163. }
  164. buf, err = name.pack(buf, compression, 0)
  165. if err != nil {
  166. t.Fatal("second Name.pack() =", err)
  167. }
  168. var n1 Name
  169. off, err := n1.unpackCompressed(buf, 0, false /* allowCompression */)
  170. if err != nil {
  171. t.Fatal("unpacking incompressible name without pointers failed:", err)
  172. }
  173. var n2 Name
  174. if _, err := n2.unpackCompressed(buf, off, false /* allowCompression */); err != errCompressedSRV {
  175. t.Errorf("unpacking compressed incompressible name with pointers: got %v, want = %v", err, errCompressedSRV)
  176. }
  177. }
  178. func checkErrorPrefix(err error, prefix string) bool {
  179. e, ok := err.(*nestedError)
  180. return ok && e.s == prefix
  181. }
  182. func TestHeaderUnpackError(t *testing.T) {
  183. wants := []string{
  184. "id",
  185. "bits",
  186. "questions",
  187. "answers",
  188. "authorities",
  189. "additionals",
  190. }
  191. var buf []byte
  192. var h header
  193. for _, want := range wants {
  194. n, err := h.unpack(buf, 0)
  195. if n != 0 || !checkErrorPrefix(err, want) {
  196. t.Errorf("got header.unpack([%d]byte, 0) = %d, %v, want = 0, %s", len(buf), n, err, want)
  197. }
  198. buf = append(buf, 0, 0)
  199. }
  200. }
  201. func TestParserStart(t *testing.T) {
  202. const want = "unpacking header"
  203. var p Parser
  204. for i := 0; i <= 1; i++ {
  205. _, err := p.Start([]byte{})
  206. if !checkErrorPrefix(err, want) {
  207. t.Errorf("got Parser.Start(nil) = _, %v, want = _, %s", err, want)
  208. }
  209. }
  210. }
  211. func TestResourceNotStarted(t *testing.T) {
  212. tests := []struct {
  213. name string
  214. fn func(*Parser) error
  215. }{
  216. {"CNAMEResource", func(p *Parser) error { _, err := p.CNAMEResource(); return err }},
  217. {"MXResource", func(p *Parser) error { _, err := p.MXResource(); return err }},
  218. {"NSResource", func(p *Parser) error { _, err := p.NSResource(); return err }},
  219. {"PTRResource", func(p *Parser) error { _, err := p.PTRResource(); return err }},
  220. {"SOAResource", func(p *Parser) error { _, err := p.SOAResource(); return err }},
  221. {"TXTResource", func(p *Parser) error { _, err := p.TXTResource(); return err }},
  222. {"SRVResource", func(p *Parser) error { _, err := p.SRVResource(); return err }},
  223. {"AResource", func(p *Parser) error { _, err := p.AResource(); return err }},
  224. {"AAAAResource", func(p *Parser) error { _, err := p.AAAAResource(); return err }},
  225. }
  226. for _, test := range tests {
  227. if err := test.fn(&Parser{}); err != ErrNotStarted {
  228. t.Errorf("got Parser.%s() = _ , %v, want = _, %v", test.name, err, ErrNotStarted)
  229. }
  230. }
  231. }
  232. func TestDNSPackUnpack(t *testing.T) {
  233. wants := []Message{
  234. {
  235. Questions: []Question{
  236. {
  237. Name: mustNewName("."),
  238. Type: TypeAAAA,
  239. Class: ClassINET,
  240. },
  241. },
  242. Answers: []Resource{},
  243. Authorities: []Resource{},
  244. Additionals: []Resource{},
  245. },
  246. largeTestMsg(),
  247. }
  248. for i, want := range wants {
  249. b, err := want.Pack()
  250. if err != nil {
  251. t.Fatalf("%d: Message.Pack() = %v", i, err)
  252. }
  253. var got Message
  254. err = got.Unpack(b)
  255. if err != nil {
  256. t.Fatalf("%d: Message.Unapck() = %v", i, err)
  257. }
  258. if !reflect.DeepEqual(got, want) {
  259. t.Errorf("%d: Message.Pack/Unpack() roundtrip: got = %+v, want = %+v", i, &got, &want)
  260. }
  261. }
  262. }
  263. func TestDNSAppendPackUnpack(t *testing.T) {
  264. wants := []Message{
  265. {
  266. Questions: []Question{
  267. {
  268. Name: mustNewName("."),
  269. Type: TypeAAAA,
  270. Class: ClassINET,
  271. },
  272. },
  273. Answers: []Resource{},
  274. Authorities: []Resource{},
  275. Additionals: []Resource{},
  276. },
  277. largeTestMsg(),
  278. }
  279. for i, want := range wants {
  280. b := make([]byte, 2, 514)
  281. b, err := want.AppendPack(b)
  282. if err != nil {
  283. t.Fatalf("%d: Message.AppendPack() = %v", i, err)
  284. }
  285. b = b[2:]
  286. var got Message
  287. err = got.Unpack(b)
  288. if err != nil {
  289. t.Fatalf("%d: Message.Unapck() = %v", i, err)
  290. }
  291. if !reflect.DeepEqual(got, want) {
  292. t.Errorf("%d: Message.AppendPack/Unpack() roundtrip: got = %+v, want = %+v", i, &got, &want)
  293. }
  294. }
  295. }
  296. func TestSkipAll(t *testing.T) {
  297. msg := largeTestMsg()
  298. buf, err := msg.Pack()
  299. if err != nil {
  300. t.Fatal("Message.Pack() =", err)
  301. }
  302. var p Parser
  303. if _, err := p.Start(buf); err != nil {
  304. t.Fatal("Parser.Start(non-nil) =", err)
  305. }
  306. tests := []struct {
  307. name string
  308. f func() error
  309. }{
  310. {"SkipAllQuestions", p.SkipAllQuestions},
  311. {"SkipAllAnswers", p.SkipAllAnswers},
  312. {"SkipAllAuthorities", p.SkipAllAuthorities},
  313. {"SkipAllAdditionals", p.SkipAllAdditionals},
  314. }
  315. for _, test := range tests {
  316. for i := 1; i <= 3; i++ {
  317. if err := test.f(); err != nil {
  318. t.Errorf("%d: Parser.%s() = %v", i, test.name, err)
  319. }
  320. }
  321. }
  322. }
  323. func TestSkipEach(t *testing.T) {
  324. msg := smallTestMsg()
  325. buf, err := msg.Pack()
  326. if err != nil {
  327. t.Fatal("Message.Pack() =", err)
  328. }
  329. var p Parser
  330. if _, err := p.Start(buf); err != nil {
  331. t.Fatal("Parser.Start(non-nil) =", err)
  332. }
  333. tests := []struct {
  334. name string
  335. f func() error
  336. }{
  337. {"SkipQuestion", p.SkipQuestion},
  338. {"SkipAnswer", p.SkipAnswer},
  339. {"SkipAuthority", p.SkipAuthority},
  340. {"SkipAdditional", p.SkipAdditional},
  341. }
  342. for _, test := range tests {
  343. if err := test.f(); err != nil {
  344. t.Errorf("first Parser.%s() = %v, want = nil", test.name, err)
  345. }
  346. if err := test.f(); err != ErrSectionDone {
  347. t.Errorf("second Parser.%s() = %v, want = %v", test.name, err, ErrSectionDone)
  348. }
  349. }
  350. }
  351. func TestSkipAfterRead(t *testing.T) {
  352. msg := smallTestMsg()
  353. buf, err := msg.Pack()
  354. if err != nil {
  355. t.Fatal("Message.Pack() =", err)
  356. }
  357. var p Parser
  358. if _, err := p.Start(buf); err != nil {
  359. t.Fatal("Parser.Srart(non-nil) =", err)
  360. }
  361. tests := []struct {
  362. name string
  363. skip func() error
  364. read func() error
  365. }{
  366. {"Question", p.SkipQuestion, func() error { _, err := p.Question(); return err }},
  367. {"Answer", p.SkipAnswer, func() error { _, err := p.Answer(); return err }},
  368. {"Authority", p.SkipAuthority, func() error { _, err := p.Authority(); return err }},
  369. {"Additional", p.SkipAdditional, func() error { _, err := p.Additional(); return err }},
  370. }
  371. for _, test := range tests {
  372. if err := test.read(); err != nil {
  373. t.Errorf("got Parser.%s() = _, %v, want = _, nil", test.name, err)
  374. }
  375. if err := test.skip(); err != ErrSectionDone {
  376. t.Errorf("got Parser.Skip%s() = %v, want = %v", test.name, err, ErrSectionDone)
  377. }
  378. }
  379. }
  380. func TestSkipNotStarted(t *testing.T) {
  381. var p Parser
  382. tests := []struct {
  383. name string
  384. f func() error
  385. }{
  386. {"SkipAllQuestions", p.SkipAllQuestions},
  387. {"SkipAllAnswers", p.SkipAllAnswers},
  388. {"SkipAllAuthorities", p.SkipAllAuthorities},
  389. {"SkipAllAdditionals", p.SkipAllAdditionals},
  390. }
  391. for _, test := range tests {
  392. if err := test.f(); err != ErrNotStarted {
  393. t.Errorf("got Parser.%s() = %v, want = %v", test.name, err, ErrNotStarted)
  394. }
  395. }
  396. }
  397. func TestTooManyRecords(t *testing.T) {
  398. const recs = int(^uint16(0)) + 1
  399. tests := []struct {
  400. name string
  401. msg Message
  402. want error
  403. }{
  404. {
  405. "Questions",
  406. Message{
  407. Questions: make([]Question, recs),
  408. },
  409. errTooManyQuestions,
  410. },
  411. {
  412. "Answers",
  413. Message{
  414. Answers: make([]Resource, recs),
  415. },
  416. errTooManyAnswers,
  417. },
  418. {
  419. "Authorities",
  420. Message{
  421. Authorities: make([]Resource, recs),
  422. },
  423. errTooManyAuthorities,
  424. },
  425. {
  426. "Additionals",
  427. Message{
  428. Additionals: make([]Resource, recs),
  429. },
  430. errTooManyAdditionals,
  431. },
  432. }
  433. for _, test := range tests {
  434. if _, got := test.msg.Pack(); got != test.want {
  435. t.Errorf("got Message.Pack() for %d %s = %v, want = %v", recs, test.name, got, test.want)
  436. }
  437. }
  438. }
  439. func TestVeryLongTxt(t *testing.T) {
  440. want := Resource{
  441. ResourceHeader{
  442. Name: mustNewName("foo.bar.example.com."),
  443. Type: TypeTXT,
  444. Class: ClassINET,
  445. },
  446. &TXTResource{[]string{
  447. "",
  448. "",
  449. "foo bar",
  450. "",
  451. "www.example.com",
  452. "www.example.com.",
  453. strings.Repeat(".", 255),
  454. }},
  455. }
  456. buf, err := want.pack(make([]byte, 0, 8000), map[string]int{}, 0)
  457. if err != nil {
  458. t.Fatal("Resource.pack() =", err)
  459. }
  460. var got Resource
  461. off, err := got.Header.unpack(buf, 0)
  462. if err != nil {
  463. t.Fatal("ResourceHeader.unpack() =", err)
  464. }
  465. body, n, err := unpackResourceBody(buf, off, got.Header)
  466. if err != nil {
  467. t.Fatal("unpackResourceBody() =", err)
  468. }
  469. got.Body = body
  470. if n != len(buf) {
  471. t.Errorf("unpacked different amount than packed: got = %d, want = %d", n, len(buf))
  472. }
  473. if !reflect.DeepEqual(got, want) {
  474. t.Errorf("Resource.pack/unpack() roundtrip: got = %#v, want = %#v", got, want)
  475. }
  476. }
  477. func TestTooLongTxt(t *testing.T) {
  478. rb := TXTResource{[]string{strings.Repeat(".", 256)}}
  479. if _, err := rb.pack(make([]byte, 0, 8000), map[string]int{}, 0); err != errStringTooLong {
  480. t.Errorf("packing TXTResource with 256 character string: got err = %v, want = %v", err, errStringTooLong)
  481. }
  482. }
  483. func TestStartAppends(t *testing.T) {
  484. buf := make([]byte, 2, 514)
  485. wantBuf := []byte{4, 44}
  486. copy(buf, wantBuf)
  487. b := NewBuilder(buf, Header{})
  488. b.EnableCompression()
  489. buf, err := b.Finish()
  490. if err != nil {
  491. t.Fatal("Builder.Finish() =", err)
  492. }
  493. if got, want := len(buf), headerLen+2; got != want {
  494. t.Errorf("got len(buf) = %d, want = %d", got, want)
  495. }
  496. if string(buf[:2]) != string(wantBuf) {
  497. t.Errorf("original data not preserved, got = %#v, want = %#v", buf[:2], wantBuf)
  498. }
  499. }
  500. func TestStartError(t *testing.T) {
  501. tests := []struct {
  502. name string
  503. fn func(*Builder) error
  504. }{
  505. {"Questions", func(b *Builder) error { return b.StartQuestions() }},
  506. {"Answers", func(b *Builder) error { return b.StartAnswers() }},
  507. {"Authorities", func(b *Builder) error { return b.StartAuthorities() }},
  508. {"Additionals", func(b *Builder) error { return b.StartAdditionals() }},
  509. }
  510. envs := []struct {
  511. name string
  512. fn func() *Builder
  513. want error
  514. }{
  515. {"sectionNotStarted", func() *Builder { return &Builder{section: sectionNotStarted} }, ErrNotStarted},
  516. {"sectionDone", func() *Builder { return &Builder{section: sectionDone} }, ErrSectionDone},
  517. }
  518. for _, env := range envs {
  519. for _, test := range tests {
  520. if got := test.fn(env.fn()); got != env.want {
  521. t.Errorf("got Builder{%s}.Start%s() = %v, want = %v", env.name, test.name, got, env.want)
  522. }
  523. }
  524. }
  525. }
  526. func TestBuilderResourceError(t *testing.T) {
  527. tests := []struct {
  528. name string
  529. fn func(*Builder) error
  530. }{
  531. {"CNAMEResource", func(b *Builder) error { return b.CNAMEResource(ResourceHeader{}, CNAMEResource{}) }},
  532. {"MXResource", func(b *Builder) error { return b.MXResource(ResourceHeader{}, MXResource{}) }},
  533. {"NSResource", func(b *Builder) error { return b.NSResource(ResourceHeader{}, NSResource{}) }},
  534. {"PTRResource", func(b *Builder) error { return b.PTRResource(ResourceHeader{}, PTRResource{}) }},
  535. {"SOAResource", func(b *Builder) error { return b.SOAResource(ResourceHeader{}, SOAResource{}) }},
  536. {"TXTResource", func(b *Builder) error { return b.TXTResource(ResourceHeader{}, TXTResource{}) }},
  537. {"SRVResource", func(b *Builder) error { return b.SRVResource(ResourceHeader{}, SRVResource{}) }},
  538. {"AResource", func(b *Builder) error { return b.AResource(ResourceHeader{}, AResource{}) }},
  539. {"AAAAResource", func(b *Builder) error { return b.AAAAResource(ResourceHeader{}, AAAAResource{}) }},
  540. {"OPTResource", func(b *Builder) error { return b.OPTResource(ResourceHeader{}, OPTResource{}) }},
  541. }
  542. envs := []struct {
  543. name string
  544. fn func() *Builder
  545. want error
  546. }{
  547. {"sectionNotStarted", func() *Builder { return &Builder{section: sectionNotStarted} }, ErrNotStarted},
  548. {"sectionHeader", func() *Builder { return &Builder{section: sectionHeader} }, ErrNotStarted},
  549. {"sectionQuestions", func() *Builder { return &Builder{section: sectionQuestions} }, ErrNotStarted},
  550. {"sectionDone", func() *Builder { return &Builder{section: sectionDone} }, ErrSectionDone},
  551. }
  552. for _, env := range envs {
  553. for _, test := range tests {
  554. if got := test.fn(env.fn()); got != env.want {
  555. t.Errorf("got Builder{%s}.%s() = %v, want = %v", env.name, test.name, got, env.want)
  556. }
  557. }
  558. }
  559. }
  560. func TestFinishError(t *testing.T) {
  561. var b Builder
  562. want := ErrNotStarted
  563. if _, got := b.Finish(); got != want {
  564. t.Errorf("got Builder.Finish() = %v, want = %v", got, want)
  565. }
  566. }
  567. func TestBuilder(t *testing.T) {
  568. msg := largeTestMsg()
  569. want, err := msg.Pack()
  570. if err != nil {
  571. t.Fatal("Message.Pack() =", err)
  572. }
  573. b := NewBuilder(nil, msg.Header)
  574. b.EnableCompression()
  575. if err := b.StartQuestions(); err != nil {
  576. t.Fatal("Builder.StartQuestions() =", err)
  577. }
  578. for _, q := range msg.Questions {
  579. if err := b.Question(q); err != nil {
  580. t.Fatalf("Builder.Question(%#v) = %v", q, err)
  581. }
  582. }
  583. if err := b.StartAnswers(); err != nil {
  584. t.Fatal("Builder.StartAnswers() =", err)
  585. }
  586. for _, a := range msg.Answers {
  587. switch a.Header.Type {
  588. case TypeA:
  589. if err := b.AResource(a.Header, *a.Body.(*AResource)); err != nil {
  590. t.Fatalf("Builder.AResource(%#v) = %v", a, err)
  591. }
  592. case TypeNS:
  593. if err := b.NSResource(a.Header, *a.Body.(*NSResource)); err != nil {
  594. t.Fatalf("Builder.NSResource(%#v) = %v", a, err)
  595. }
  596. case TypeCNAME:
  597. if err := b.CNAMEResource(a.Header, *a.Body.(*CNAMEResource)); err != nil {
  598. t.Fatalf("Builder.CNAMEResource(%#v) = %v", a, err)
  599. }
  600. case TypeSOA:
  601. if err := b.SOAResource(a.Header, *a.Body.(*SOAResource)); err != nil {
  602. t.Fatalf("Builder.SOAResource(%#v) = %v", a, err)
  603. }
  604. case TypePTR:
  605. if err := b.PTRResource(a.Header, *a.Body.(*PTRResource)); err != nil {
  606. t.Fatalf("Builder.PTRResource(%#v) = %v", a, err)
  607. }
  608. case TypeMX:
  609. if err := b.MXResource(a.Header, *a.Body.(*MXResource)); err != nil {
  610. t.Fatalf("Builder.MXResource(%#v) = %v", a, err)
  611. }
  612. case TypeTXT:
  613. if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
  614. t.Fatalf("Builder.TXTResource(%#v) = %v", a, err)
  615. }
  616. case TypeAAAA:
  617. if err := b.AAAAResource(a.Header, *a.Body.(*AAAAResource)); err != nil {
  618. t.Fatalf("Builder.AAAAResource(%#v) = %v", a, err)
  619. }
  620. case TypeSRV:
  621. if err := b.SRVResource(a.Header, *a.Body.(*SRVResource)); err != nil {
  622. t.Fatalf("Builder.SRVResource(%#v) = %v", a, err)
  623. }
  624. }
  625. }
  626. if err := b.StartAuthorities(); err != nil {
  627. t.Fatal("Builder.StartAuthorities() =", err)
  628. }
  629. for _, a := range msg.Authorities {
  630. if err := b.NSResource(a.Header, *a.Body.(*NSResource)); err != nil {
  631. t.Fatalf("Builder.NSResource(%#v) = %v", a, err)
  632. }
  633. }
  634. if err := b.StartAdditionals(); err != nil {
  635. t.Fatal("Builder.StartAdditionals() =", err)
  636. }
  637. for _, a := range msg.Additionals {
  638. switch a.Body.(type) {
  639. case *TXTResource:
  640. if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
  641. t.Fatalf("Builder.TXTResource(%#v) = %v", a, err)
  642. }
  643. case *OPTResource:
  644. if err := b.OPTResource(a.Header, *a.Body.(*OPTResource)); err != nil {
  645. t.Fatalf("Builder.OPTResource(%#v) = %v", a, err)
  646. }
  647. }
  648. }
  649. got, err := b.Finish()
  650. if err != nil {
  651. t.Fatal("Builder.Finish() =", err)
  652. }
  653. if !bytes.Equal(got, want) {
  654. t.Fatalf("got from Builder.Finish() = %#v\nwant = %#v", got, want)
  655. }
  656. }
  657. func TestResourcePack(t *testing.T) {
  658. for _, tt := range []struct {
  659. m Message
  660. err error
  661. }{
  662. {
  663. Message{
  664. Questions: []Question{
  665. {
  666. Name: mustNewName("."),
  667. Type: TypeAAAA,
  668. Class: ClassINET,
  669. },
  670. },
  671. Answers: []Resource{{ResourceHeader{}, nil}},
  672. },
  673. &nestedError{"packing Answer", errNilResouceBody},
  674. },
  675. {
  676. Message{
  677. Questions: []Question{
  678. {
  679. Name: mustNewName("."),
  680. Type: TypeAAAA,
  681. Class: ClassINET,
  682. },
  683. },
  684. Authorities: []Resource{{ResourceHeader{}, (*NSResource)(nil)}},
  685. },
  686. &nestedError{"packing Authority",
  687. &nestedError{"ResourceHeader",
  688. &nestedError{"Name", errNonCanonicalName},
  689. },
  690. },
  691. },
  692. {
  693. Message{
  694. Questions: []Question{
  695. {
  696. Name: mustNewName("."),
  697. Type: TypeA,
  698. Class: ClassINET,
  699. },
  700. },
  701. Additionals: []Resource{{ResourceHeader{}, nil}},
  702. },
  703. &nestedError{"packing Additional", errNilResouceBody},
  704. },
  705. } {
  706. _, err := tt.m.Pack()
  707. if !reflect.DeepEqual(err, tt.err) {
  708. t.Errorf("got Message{%v}.Pack() = %v, want %v", tt.m, err, tt.err)
  709. }
  710. }
  711. }
  712. func TestOptionPackUnpack(t *testing.T) {
  713. for _, tt := range []struct {
  714. name string
  715. w []byte // wire format of m.Additionals
  716. m Message
  717. dnssecOK bool
  718. extRCode RCode
  719. }{
  720. {
  721. name: "without EDNS(0) options",
  722. w: []byte{
  723. 0x00, 0x00, 0x29, 0x10, 0x00, 0xfe, 0x00, 0x80,
  724. 0x00, 0x00, 0x00,
  725. },
  726. m: Message{
  727. Header: Header{RCode: RCodeFormatError},
  728. Questions: []Question{
  729. {
  730. Name: mustNewName("."),
  731. Type: TypeA,
  732. Class: ClassINET,
  733. },
  734. },
  735. Additionals: []Resource{
  736. {
  737. mustEDNS0ResourceHeader(4096, 0xfe0|RCodeFormatError, true),
  738. &OPTResource{},
  739. },
  740. },
  741. },
  742. dnssecOK: true,
  743. extRCode: 0xfe0 | RCodeFormatError,
  744. },
  745. {
  746. name: "with EDNS(0) options",
  747. w: []byte{
  748. 0x00, 0x00, 0x29, 0x10, 0x00, 0xff, 0x00, 0x00,
  749. 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x02, 0x00,
  750. 0x00, 0x00, 0x0b, 0x00, 0x02, 0x12, 0x34,
  751. },
  752. m: Message{
  753. Header: Header{RCode: RCodeServerFailure},
  754. Questions: []Question{
  755. {
  756. Name: mustNewName("."),
  757. Type: TypeAAAA,
  758. Class: ClassINET,
  759. },
  760. },
  761. Additionals: []Resource{
  762. {
  763. mustEDNS0ResourceHeader(4096, 0xff0|RCodeServerFailure, false),
  764. &OPTResource{
  765. Options: []Option{
  766. {
  767. Code: 12, // see RFC 7828
  768. Data: []byte{0x00, 0x00},
  769. },
  770. {
  771. Code: 11, // see RFC 7830
  772. Data: []byte{0x12, 0x34},
  773. },
  774. },
  775. },
  776. },
  777. },
  778. },
  779. dnssecOK: false,
  780. extRCode: 0xff0 | RCodeServerFailure,
  781. },
  782. {
  783. // Containing multiple OPT resources in a
  784. // message is invalid, but it's necessary for
  785. // protocol conformance testing.
  786. name: "with multiple OPT resources",
  787. w: []byte{
  788. 0x00, 0x00, 0x29, 0x10, 0x00, 0xff, 0x00, 0x00,
  789. 0x00, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x02, 0x12,
  790. 0x34, 0x00, 0x00, 0x29, 0x10, 0x00, 0xff, 0x00,
  791. 0x00, 0x00, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x02,
  792. 0x00, 0x00,
  793. },
  794. m: Message{
  795. Header: Header{RCode: RCodeNameError},
  796. Questions: []Question{
  797. {
  798. Name: mustNewName("."),
  799. Type: TypeAAAA,
  800. Class: ClassINET,
  801. },
  802. },
  803. Additionals: []Resource{
  804. {
  805. mustEDNS0ResourceHeader(4096, 0xff0|RCodeNameError, false),
  806. &OPTResource{
  807. Options: []Option{
  808. {
  809. Code: 11, // see RFC 7830
  810. Data: []byte{0x12, 0x34},
  811. },
  812. },
  813. },
  814. },
  815. {
  816. mustEDNS0ResourceHeader(4096, 0xff0|RCodeNameError, false),
  817. &OPTResource{
  818. Options: []Option{
  819. {
  820. Code: 12, // see RFC 7828
  821. Data: []byte{0x00, 0x00},
  822. },
  823. },
  824. },
  825. },
  826. },
  827. },
  828. },
  829. } {
  830. w, err := tt.m.Pack()
  831. if err != nil {
  832. t.Errorf("Message.Pack() for %s = %v", tt.name, err)
  833. continue
  834. }
  835. if !bytes.Equal(w[len(w)-len(tt.w):], tt.w) {
  836. t.Errorf("got Message.Pack() for %s = %#v, want %#v", tt.name, w[len(w)-len(tt.w):], tt.w)
  837. continue
  838. }
  839. var m Message
  840. if err := m.Unpack(w); err != nil {
  841. t.Errorf("Message.Unpack() for %s = %v", tt.name, err)
  842. continue
  843. }
  844. if !reflect.DeepEqual(m.Additionals, tt.m.Additionals) {
  845. t.Errorf("got Message.Pack/Unpack() roundtrip for %s = %+v, want %+v", tt.name, m, tt.m)
  846. continue
  847. }
  848. }
  849. }
  850. func benchmarkParsingSetup() ([]byte, error) {
  851. name := mustNewName("foo.bar.example.com.")
  852. msg := Message{
  853. Header: Header{Response: true, Authoritative: true},
  854. Questions: []Question{
  855. {
  856. Name: name,
  857. Type: TypeA,
  858. Class: ClassINET,
  859. },
  860. },
  861. Answers: []Resource{
  862. {
  863. ResourceHeader{
  864. Name: name,
  865. Class: ClassINET,
  866. },
  867. &AResource{[4]byte{}},
  868. },
  869. {
  870. ResourceHeader{
  871. Name: name,
  872. Class: ClassINET,
  873. },
  874. &AAAAResource{[16]byte{}},
  875. },
  876. {
  877. ResourceHeader{
  878. Name: name,
  879. Class: ClassINET,
  880. },
  881. &CNAMEResource{name},
  882. },
  883. {
  884. ResourceHeader{
  885. Name: name,
  886. Class: ClassINET,
  887. },
  888. &NSResource{name},
  889. },
  890. },
  891. }
  892. buf, err := msg.Pack()
  893. if err != nil {
  894. return nil, fmt.Errorf("Message.Pack() = %v", err)
  895. }
  896. return buf, nil
  897. }
  898. func benchmarkParsing(tb testing.TB, buf []byte) {
  899. var p Parser
  900. if _, err := p.Start(buf); err != nil {
  901. tb.Fatal("Parser.Start(non-nil) =", err)
  902. }
  903. for {
  904. _, err := p.Question()
  905. if err == ErrSectionDone {
  906. break
  907. }
  908. if err != nil {
  909. tb.Fatal("Parser.Question() =", err)
  910. }
  911. }
  912. for {
  913. h, err := p.AnswerHeader()
  914. if err == ErrSectionDone {
  915. break
  916. }
  917. if err != nil {
  918. tb.Fatal("Parser.AnswerHeader() =", err)
  919. }
  920. switch h.Type {
  921. case TypeA:
  922. if _, err := p.AResource(); err != nil {
  923. tb.Fatal("Parser.AResource() =", err)
  924. }
  925. case TypeAAAA:
  926. if _, err := p.AAAAResource(); err != nil {
  927. tb.Fatal("Parser.AAAAResource() =", err)
  928. }
  929. case TypeCNAME:
  930. if _, err := p.CNAMEResource(); err != nil {
  931. tb.Fatal("Parser.CNAMEResource() =", err)
  932. }
  933. case TypeNS:
  934. if _, err := p.NSResource(); err != nil {
  935. tb.Fatal("Parser.NSResource() =", err)
  936. }
  937. case TypeOPT:
  938. if _, err := p.OPTResource(); err != nil {
  939. tb.Fatal("Parser.OPTResource() =", err)
  940. }
  941. default:
  942. tb.Fatalf("got unknown type: %T", h)
  943. }
  944. }
  945. }
  946. func BenchmarkParsing(b *testing.B) {
  947. buf, err := benchmarkParsingSetup()
  948. if err != nil {
  949. b.Fatal(err)
  950. }
  951. b.ReportAllocs()
  952. for i := 0; i < b.N; i++ {
  953. benchmarkParsing(b, buf)
  954. }
  955. }
  956. func TestParsingAllocs(t *testing.T) {
  957. buf, err := benchmarkParsingSetup()
  958. if err != nil {
  959. t.Fatal(err)
  960. }
  961. if allocs := testing.AllocsPerRun(100, func() { benchmarkParsing(t, buf) }); allocs > 0.5 {
  962. t.Errorf("allocations during parsing: got = %f, want ~0", allocs)
  963. }
  964. }
  965. func benchmarkBuildingSetup() (Name, []byte) {
  966. name := mustNewName("foo.bar.example.com.")
  967. buf := make([]byte, 0, packStartingCap)
  968. return name, buf
  969. }
  970. func benchmarkBuilding(tb testing.TB, name Name, buf []byte) {
  971. bld := NewBuilder(buf, Header{Response: true, Authoritative: true})
  972. if err := bld.StartQuestions(); err != nil {
  973. tb.Fatal("Builder.StartQuestions() =", err)
  974. }
  975. q := Question{
  976. Name: name,
  977. Type: TypeA,
  978. Class: ClassINET,
  979. }
  980. if err := bld.Question(q); err != nil {
  981. tb.Fatalf("Builder.Question(%+v) = %v", q, err)
  982. }
  983. hdr := ResourceHeader{
  984. Name: name,
  985. Class: ClassINET,
  986. }
  987. if err := bld.StartAnswers(); err != nil {
  988. tb.Fatal("Builder.StartQuestions() =", err)
  989. }
  990. ar := AResource{[4]byte{}}
  991. if err := bld.AResource(hdr, ar); err != nil {
  992. tb.Fatalf("Builder.AResource(%+v, %+v) = %v", hdr, ar, err)
  993. }
  994. aaar := AAAAResource{[16]byte{}}
  995. if err := bld.AAAAResource(hdr, aaar); err != nil {
  996. tb.Fatalf("Builder.AAAAResource(%+v, %+v) = %v", hdr, aaar, err)
  997. }
  998. cnr := CNAMEResource{name}
  999. if err := bld.CNAMEResource(hdr, cnr); err != nil {
  1000. tb.Fatalf("Builder.CNAMEResource(%+v, %+v) = %v", hdr, cnr, err)
  1001. }
  1002. nsr := NSResource{name}
  1003. if err := bld.NSResource(hdr, nsr); err != nil {
  1004. tb.Fatalf("Builder.NSResource(%+v, %+v) = %v", hdr, nsr, err)
  1005. }
  1006. extrc := 0xfe0 | RCodeNotImplemented
  1007. if err := (&hdr).SetEDNS0(4096, extrc, true); err != nil {
  1008. tb.Fatalf("ResourceHeader.SetEDNS0(4096, %#x, true) = %v", extrc, err)
  1009. }
  1010. optr := OPTResource{}
  1011. if err := bld.OPTResource(hdr, optr); err != nil {
  1012. tb.Fatalf("Builder.OPTResource(%+v, %+v) = %v", hdr, optr, err)
  1013. }
  1014. if _, err := bld.Finish(); err != nil {
  1015. tb.Fatal("Builder.Finish() =", err)
  1016. }
  1017. }
  1018. func BenchmarkBuilding(b *testing.B) {
  1019. name, buf := benchmarkBuildingSetup()
  1020. b.ReportAllocs()
  1021. for i := 0; i < b.N; i++ {
  1022. benchmarkBuilding(b, name, buf)
  1023. }
  1024. }
  1025. func TestBuildingAllocs(t *testing.T) {
  1026. name, buf := benchmarkBuildingSetup()
  1027. if allocs := testing.AllocsPerRun(100, func() { benchmarkBuilding(t, name, buf) }); allocs > 0.5 {
  1028. t.Errorf("allocations during building: got = %f, want ~0", allocs)
  1029. }
  1030. }
  1031. func smallTestMsg() Message {
  1032. name := mustNewName("example.com.")
  1033. return Message{
  1034. Header: Header{Response: true, Authoritative: true},
  1035. Questions: []Question{
  1036. {
  1037. Name: name,
  1038. Type: TypeA,
  1039. Class: ClassINET,
  1040. },
  1041. },
  1042. Answers: []Resource{
  1043. {
  1044. ResourceHeader{
  1045. Name: name,
  1046. Type: TypeA,
  1047. Class: ClassINET,
  1048. },
  1049. &AResource{[4]byte{127, 0, 0, 1}},
  1050. },
  1051. },
  1052. Authorities: []Resource{
  1053. {
  1054. ResourceHeader{
  1055. Name: name,
  1056. Type: TypeA,
  1057. Class: ClassINET,
  1058. },
  1059. &AResource{[4]byte{127, 0, 0, 1}},
  1060. },
  1061. },
  1062. Additionals: []Resource{
  1063. {
  1064. ResourceHeader{
  1065. Name: name,
  1066. Type: TypeA,
  1067. Class: ClassINET,
  1068. },
  1069. &AResource{[4]byte{127, 0, 0, 1}},
  1070. },
  1071. },
  1072. }
  1073. }
  1074. func BenchmarkPack(b *testing.B) {
  1075. msg := largeTestMsg()
  1076. b.ReportAllocs()
  1077. for i := 0; i < b.N; i++ {
  1078. if _, err := msg.Pack(); err != nil {
  1079. b.Fatal("Message.Pack() =", err)
  1080. }
  1081. }
  1082. }
  1083. func BenchmarkAppendPack(b *testing.B) {
  1084. msg := largeTestMsg()
  1085. buf := make([]byte, 0, packStartingCap)
  1086. b.ReportAllocs()
  1087. for i := 0; i < b.N; i++ {
  1088. if _, err := msg.AppendPack(buf[:0]); err != nil {
  1089. b.Fatal("Message.AppendPack() = ", err)
  1090. }
  1091. }
  1092. }
  1093. func largeTestMsg() Message {
  1094. name := mustNewName("foo.bar.example.com.")
  1095. return Message{
  1096. Header: Header{Response: true, Authoritative: true},
  1097. Questions: []Question{
  1098. {
  1099. Name: name,
  1100. Type: TypeA,
  1101. Class: ClassINET,
  1102. },
  1103. },
  1104. Answers: []Resource{
  1105. {
  1106. ResourceHeader{
  1107. Name: name,
  1108. Type: TypeA,
  1109. Class: ClassINET,
  1110. },
  1111. &AResource{[4]byte{127, 0, 0, 1}},
  1112. },
  1113. {
  1114. ResourceHeader{
  1115. Name: name,
  1116. Type: TypeA,
  1117. Class: ClassINET,
  1118. },
  1119. &AResource{[4]byte{127, 0, 0, 2}},
  1120. },
  1121. {
  1122. ResourceHeader{
  1123. Name: name,
  1124. Type: TypeAAAA,
  1125. Class: ClassINET,
  1126. },
  1127. &AAAAResource{[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}},
  1128. },
  1129. {
  1130. ResourceHeader{
  1131. Name: name,
  1132. Type: TypeCNAME,
  1133. Class: ClassINET,
  1134. },
  1135. &CNAMEResource{mustNewName("alias.example.com.")},
  1136. },
  1137. {
  1138. ResourceHeader{
  1139. Name: name,
  1140. Type: TypeSOA,
  1141. Class: ClassINET,
  1142. },
  1143. &SOAResource{
  1144. NS: mustNewName("ns1.example.com."),
  1145. MBox: mustNewName("mb.example.com."),
  1146. Serial: 1,
  1147. Refresh: 2,
  1148. Retry: 3,
  1149. Expire: 4,
  1150. MinTTL: 5,
  1151. },
  1152. },
  1153. {
  1154. ResourceHeader{
  1155. Name: name,
  1156. Type: TypePTR,
  1157. Class: ClassINET,
  1158. },
  1159. &PTRResource{mustNewName("ptr.example.com.")},
  1160. },
  1161. {
  1162. ResourceHeader{
  1163. Name: name,
  1164. Type: TypeMX,
  1165. Class: ClassINET,
  1166. },
  1167. &MXResource{
  1168. 7,
  1169. mustNewName("mx.example.com."),
  1170. },
  1171. },
  1172. {
  1173. ResourceHeader{
  1174. Name: name,
  1175. Type: TypeSRV,
  1176. Class: ClassINET,
  1177. },
  1178. &SRVResource{
  1179. 8,
  1180. 9,
  1181. 11,
  1182. mustNewName("srv.example.com."),
  1183. },
  1184. },
  1185. },
  1186. Authorities: []Resource{
  1187. {
  1188. ResourceHeader{
  1189. Name: name,
  1190. Type: TypeNS,
  1191. Class: ClassINET,
  1192. },
  1193. &NSResource{mustNewName("ns1.example.com.")},
  1194. },
  1195. {
  1196. ResourceHeader{
  1197. Name: name,
  1198. Type: TypeNS,
  1199. Class: ClassINET,
  1200. },
  1201. &NSResource{mustNewName("ns2.example.com.")},
  1202. },
  1203. },
  1204. Additionals: []Resource{
  1205. {
  1206. ResourceHeader{
  1207. Name: name,
  1208. Type: TypeTXT,
  1209. Class: ClassINET,
  1210. },
  1211. &TXTResource{[]string{"So Long, and Thanks for All the Fish"}},
  1212. },
  1213. {
  1214. ResourceHeader{
  1215. Name: name,
  1216. Type: TypeTXT,
  1217. Class: ClassINET,
  1218. },
  1219. &TXTResource{[]string{"Hamster Huey and the Gooey Kablooie"}},
  1220. },
  1221. {
  1222. mustEDNS0ResourceHeader(4096, 0xfe0|RCodeSuccess, false),
  1223. &OPTResource{
  1224. Options: []Option{
  1225. {
  1226. Code: 10, // see RFC 7873
  1227. Data: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
  1228. },
  1229. },
  1230. },
  1231. },
  1232. },
  1233. }
  1234. }