message_test.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  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. "testing"
  10. )
  11. func mustNewName(name string) Name {
  12. n, err := NewName(name)
  13. if err != nil {
  14. panic(err)
  15. }
  16. return n
  17. }
  18. func (m *Message) String() string {
  19. s := fmt.Sprintf("Message: %#v\n", &m.Header)
  20. if len(m.Questions) > 0 {
  21. s += "-- Questions\n"
  22. for _, q := range m.Questions {
  23. s += fmt.Sprintf("%#v\n", q)
  24. }
  25. }
  26. if len(m.Answers) > 0 {
  27. s += "-- Answers\n"
  28. for _, a := range m.Answers {
  29. s += fmt.Sprintf("%#v\n", a)
  30. }
  31. }
  32. if len(m.Authorities) > 0 {
  33. s += "-- Authorities\n"
  34. for _, ns := range m.Authorities {
  35. s += fmt.Sprintf("%#v\n", ns)
  36. }
  37. }
  38. if len(m.Additionals) > 0 {
  39. s += "-- Additionals\n"
  40. for _, e := range m.Additionals {
  41. s += fmt.Sprintf("%#v\n", e)
  42. }
  43. }
  44. return s
  45. }
  46. func TestNameString(t *testing.T) {
  47. want := "foo"
  48. name := mustNewName(want)
  49. if got := fmt.Sprint(name); got != want {
  50. t.Errorf("got fmt.Sprint(%#v) = %s, want = %s", name, got, want)
  51. }
  52. }
  53. func TestQuestionPackUnpack(t *testing.T) {
  54. want := Question{
  55. Name: mustNewName("."),
  56. Type: TypeA,
  57. Class: ClassINET,
  58. }
  59. buf, err := want.pack(make([]byte, 1, 50), map[string]int{})
  60. if err != nil {
  61. t.Fatal("Packing failed:", err)
  62. }
  63. var p Parser
  64. p.msg = buf
  65. p.header.questions = 1
  66. p.section = sectionQuestions
  67. p.off = 1
  68. got, err := p.Question()
  69. if err != nil {
  70. t.Fatalf("Unpacking failed: %v\n%s", err, string(buf[1:]))
  71. }
  72. if p.off != len(buf) {
  73. t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", p.off, len(buf))
  74. }
  75. if !reflect.DeepEqual(got, want) {
  76. t.Errorf("Got = %+v, want = %+v", got, want)
  77. }
  78. }
  79. func TestName(t *testing.T) {
  80. tests := []string{
  81. "",
  82. ".",
  83. "google..com",
  84. "google.com",
  85. "google..com.",
  86. "google.com.",
  87. ".google.com.",
  88. "www..google.com.",
  89. "www.google.com.",
  90. }
  91. for _, test := range tests {
  92. n, err := NewName(test)
  93. if err != nil {
  94. t.Errorf("Creating name for %q: %v", test, err)
  95. continue
  96. }
  97. if ns := n.String(); ns != test {
  98. t.Errorf("Got %#v.String() = %q, want = %q", n, ns, test)
  99. continue
  100. }
  101. }
  102. }
  103. func TestNamePackUnpack(t *testing.T) {
  104. tests := []struct {
  105. in string
  106. want string
  107. err error
  108. }{
  109. {"", "", errNonCanonicalName},
  110. {".", ".", nil},
  111. {"google..com", "", errNonCanonicalName},
  112. {"google.com", "", errNonCanonicalName},
  113. {"google..com.", "", errZeroSegLen},
  114. {"google.com.", "google.com.", nil},
  115. {".google.com.", "", errZeroSegLen},
  116. {"www..google.com.", "", errZeroSegLen},
  117. {"www.google.com.", "www.google.com.", nil},
  118. }
  119. for _, test := range tests {
  120. in := mustNewName(test.in)
  121. want := mustNewName(test.want)
  122. buf, err := in.pack(make([]byte, 0, 30), map[string]int{})
  123. if err != test.err {
  124. t.Errorf("Packing of %q: got err = %v, want err = %v", test.in, err, test.err)
  125. continue
  126. }
  127. if test.err != nil {
  128. continue
  129. }
  130. var got Name
  131. n, err := got.unpack(buf, 0)
  132. if err != nil {
  133. t.Errorf("Unpacking for %q failed: %v", test.in, err)
  134. continue
  135. }
  136. if n != len(buf) {
  137. t.Errorf(
  138. "Unpacked different amount than packed for %q: got n = %d, want = %d",
  139. test.in,
  140. n,
  141. len(buf),
  142. )
  143. }
  144. if got != want {
  145. t.Errorf("Unpacking packing of %q: got = %#v, want = %#v", test.in, got, want)
  146. }
  147. }
  148. }
  149. func checkErrorPrefix(err error, prefix string) bool {
  150. e, ok := err.(*nestedError)
  151. return ok && e.s == prefix
  152. }
  153. func TestHeaderUnpackError(t *testing.T) {
  154. wants := []string{
  155. "id",
  156. "bits",
  157. "questions",
  158. "answers",
  159. "authorities",
  160. "additionals",
  161. }
  162. var buf []byte
  163. var h header
  164. for _, want := range wants {
  165. n, err := h.unpack(buf, 0)
  166. if n != 0 || !checkErrorPrefix(err, want) {
  167. t.Errorf("got h.unpack([%d]byte, 0) = %d, %v, want = 0, %s", len(buf), n, err, want)
  168. }
  169. buf = append(buf, 0, 0)
  170. }
  171. }
  172. func TestParserStart(t *testing.T) {
  173. const want = "unpacking header"
  174. var p Parser
  175. for i := 0; i <= 1; i++ {
  176. _, err := p.Start([]byte{})
  177. if !checkErrorPrefix(err, want) {
  178. t.Errorf("got p.Start(nil) = _, %v, want = _, %s", err, want)
  179. }
  180. }
  181. }
  182. func TestResourceNotStarted(t *testing.T) {
  183. tests := []struct {
  184. name string
  185. fn func(*Parser) error
  186. }{
  187. {"CNAMEResource", func(p *Parser) error { _, err := p.CNAMEResource(); return err }},
  188. {"MXResource", func(p *Parser) error { _, err := p.MXResource(); return err }},
  189. {"NSResource", func(p *Parser) error { _, err := p.NSResource(); return err }},
  190. {"PTRResource", func(p *Parser) error { _, err := p.PTRResource(); return err }},
  191. {"SOAResource", func(p *Parser) error { _, err := p.SOAResource(); return err }},
  192. {"TXTResource", func(p *Parser) error { _, err := p.TXTResource(); return err }},
  193. {"SRVResource", func(p *Parser) error { _, err := p.SRVResource(); return err }},
  194. {"AResource", func(p *Parser) error { _, err := p.AResource(); return err }},
  195. {"AAAAResource", func(p *Parser) error { _, err := p.AAAAResource(); return err }},
  196. }
  197. for _, test := range tests {
  198. if err := test.fn(&Parser{}); err != ErrNotStarted {
  199. t.Errorf("got _, %v = p.%s(), want = _, %v", err, test.name, ErrNotStarted)
  200. }
  201. }
  202. }
  203. func TestDNSPackUnpack(t *testing.T) {
  204. wants := []Message{
  205. {
  206. Questions: []Question{
  207. {
  208. Name: mustNewName("."),
  209. Type: TypeAAAA,
  210. Class: ClassINET,
  211. },
  212. },
  213. Answers: []Resource{},
  214. Authorities: []Resource{},
  215. Additionals: []Resource{},
  216. },
  217. largeTestMsg(),
  218. }
  219. for i, want := range wants {
  220. b, err := want.Pack()
  221. if err != nil {
  222. t.Fatalf("%d: packing failed: %v", i, err)
  223. }
  224. var got Message
  225. err = got.Unpack(b)
  226. if err != nil {
  227. t.Fatalf("%d: unpacking failed: %v", i, err)
  228. }
  229. if !reflect.DeepEqual(got, want) {
  230. t.Errorf("%d: got = %+v, want = %+v", i, &got, &want)
  231. }
  232. }
  233. }
  234. func TestSkipAll(t *testing.T) {
  235. msg := largeTestMsg()
  236. buf, err := msg.Pack()
  237. if err != nil {
  238. t.Fatal("Packing large test message:", err)
  239. }
  240. var p Parser
  241. if _, err := p.Start(buf); err != nil {
  242. t.Fatal(err)
  243. }
  244. tests := []struct {
  245. name string
  246. f func() error
  247. }{
  248. {"SkipAllQuestions", p.SkipAllQuestions},
  249. {"SkipAllAnswers", p.SkipAllAnswers},
  250. {"SkipAllAuthorities", p.SkipAllAuthorities},
  251. {"SkipAllAdditionals", p.SkipAllAdditionals},
  252. }
  253. for _, test := range tests {
  254. for i := 1; i <= 3; i++ {
  255. if err := test.f(); err != nil {
  256. t.Errorf("Call #%d to %s(): %v", i, test.name, err)
  257. }
  258. }
  259. }
  260. }
  261. func TestSkipNotStarted(t *testing.T) {
  262. var p Parser
  263. tests := []struct {
  264. name string
  265. f func() error
  266. }{
  267. {"SkipAllQuestions", p.SkipAllQuestions},
  268. {"SkipAllAnswers", p.SkipAllAnswers},
  269. {"SkipAllAuthorities", p.SkipAllAuthorities},
  270. {"SkipAllAdditionals", p.SkipAllAdditionals},
  271. }
  272. for _, test := range tests {
  273. if err := test.f(); err != ErrNotStarted {
  274. t.Errorf("Got %s() = %v, want = %v", test.name, err, ErrNotStarted)
  275. }
  276. }
  277. }
  278. func TestTooManyRecords(t *testing.T) {
  279. const recs = int(^uint16(0)) + 1
  280. tests := []struct {
  281. name string
  282. msg Message
  283. want error
  284. }{
  285. {
  286. "Questions",
  287. Message{
  288. Questions: make([]Question, recs),
  289. },
  290. errTooManyQuestions,
  291. },
  292. {
  293. "Answers",
  294. Message{
  295. Answers: make([]Resource, recs),
  296. },
  297. errTooManyAnswers,
  298. },
  299. {
  300. "Authorities",
  301. Message{
  302. Authorities: make([]Resource, recs),
  303. },
  304. errTooManyAuthorities,
  305. },
  306. {
  307. "Additionals",
  308. Message{
  309. Additionals: make([]Resource, recs),
  310. },
  311. errTooManyAdditionals,
  312. },
  313. }
  314. for _, test := range tests {
  315. if _, got := test.msg.Pack(); got != test.want {
  316. t.Errorf("Packing %d %s: got = %v, want = %v", recs, test.name, got, test.want)
  317. }
  318. }
  319. }
  320. func TestVeryLongTxt(t *testing.T) {
  321. want := Resource{
  322. ResourceHeader{
  323. Name: mustNewName("foo.bar.example.com."),
  324. Type: TypeTXT,
  325. Class: ClassINET,
  326. },
  327. &TXTResource{loremIpsum},
  328. }
  329. buf, err := want.pack(make([]byte, 0, 8000), map[string]int{})
  330. if err != nil {
  331. t.Fatal("Packing failed:", err)
  332. }
  333. var got Resource
  334. off, err := got.Header.unpack(buf, 0)
  335. if err != nil {
  336. t.Fatal("Unpacking ResourceHeader failed:", err)
  337. }
  338. body, n, err := unpackResourceBody(buf, off, got.Header)
  339. if err != nil {
  340. t.Fatal("Unpacking failed:", err)
  341. }
  342. got.Body = body
  343. if n != len(buf) {
  344. t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", n, len(buf))
  345. }
  346. if !reflect.DeepEqual(got, want) {
  347. t.Errorf("Got = %#v, want = %#v", got, want)
  348. }
  349. }
  350. func TestStartError(t *testing.T) {
  351. tests := []struct {
  352. name string
  353. fn func(*Builder) error
  354. }{
  355. {"Questions", func(b *Builder) error { return b.StartQuestions() }},
  356. {"Answers", func(b *Builder) error { return b.StartAnswers() }},
  357. {"Authorities", func(b *Builder) error { return b.StartAuthorities() }},
  358. {"Additionals", func(b *Builder) error { return b.StartAdditionals() }},
  359. }
  360. envs := []struct {
  361. name string
  362. fn func() *Builder
  363. want error
  364. }{
  365. {"sectionNotStarted", func() *Builder { return &Builder{section: sectionNotStarted} }, ErrNotStarted},
  366. {"sectionDone", func() *Builder { return &Builder{section: sectionDone} }, ErrSectionDone},
  367. }
  368. for _, env := range envs {
  369. for _, test := range tests {
  370. if got := test.fn(env.fn()); got != env.want {
  371. t.Errorf("got Builder{%s}.Start%s = %v, want = %v", env.name, test.name, got, env.want)
  372. }
  373. }
  374. }
  375. }
  376. func TestBuilderResourceError(t *testing.T) {
  377. tests := []struct {
  378. name string
  379. fn func(*Builder) error
  380. }{
  381. {"CNAMEResource", func(b *Builder) error { return b.CNAMEResource(ResourceHeader{}, CNAMEResource{}) }},
  382. {"MXResource", func(b *Builder) error { return b.MXResource(ResourceHeader{}, MXResource{}) }},
  383. {"NSResource", func(b *Builder) error { return b.NSResource(ResourceHeader{}, NSResource{}) }},
  384. {"PTRResource", func(b *Builder) error { return b.PTRResource(ResourceHeader{}, PTRResource{}) }},
  385. {"SOAResource", func(b *Builder) error { return b.SOAResource(ResourceHeader{}, SOAResource{}) }},
  386. {"TXTResource", func(b *Builder) error { return b.TXTResource(ResourceHeader{}, TXTResource{}) }},
  387. {"SRVResource", func(b *Builder) error { return b.SRVResource(ResourceHeader{}, SRVResource{}) }},
  388. {"AResource", func(b *Builder) error { return b.AResource(ResourceHeader{}, AResource{}) }},
  389. {"AAAAResource", func(b *Builder) error { return b.AAAAResource(ResourceHeader{}, AAAAResource{}) }},
  390. }
  391. envs := []struct {
  392. name string
  393. fn func() *Builder
  394. want error
  395. }{
  396. {"sectionNotStarted", func() *Builder { return &Builder{section: sectionNotStarted} }, ErrNotStarted},
  397. {"sectionHeader", func() *Builder { return &Builder{section: sectionHeader} }, ErrNotStarted},
  398. {"sectionQuestions", func() *Builder { return &Builder{section: sectionQuestions} }, ErrNotStarted},
  399. {"sectionDone", func() *Builder { return &Builder{section: sectionDone} }, ErrSectionDone},
  400. }
  401. for _, env := range envs {
  402. for _, test := range tests {
  403. if got := test.fn(env.fn()); got != env.want {
  404. t.Errorf("got Builder{%s}.%s = %v, want = %v", env.name, test.name, got, env.want)
  405. }
  406. }
  407. }
  408. }
  409. func TestFinishError(t *testing.T) {
  410. var b Builder
  411. want := ErrNotStarted
  412. if _, got := b.Finish(); got != want {
  413. t.Errorf("got Builder{}.Finish() = %v, want = %v", got, want)
  414. }
  415. }
  416. func TestBuilder(t *testing.T) {
  417. msg := largeTestMsg()
  418. want, err := msg.Pack()
  419. if err != nil {
  420. t.Fatal("Packing without builder:", err)
  421. }
  422. var b Builder
  423. b.Start(nil, msg.Header)
  424. if err := b.StartQuestions(); err != nil {
  425. t.Fatal("b.StartQuestions():", err)
  426. }
  427. for _, q := range msg.Questions {
  428. if err := b.Question(q); err != nil {
  429. t.Fatalf("b.Question(%#v): %v", q, err)
  430. }
  431. }
  432. if err := b.StartAnswers(); err != nil {
  433. t.Fatal("b.StartAnswers():", err)
  434. }
  435. for _, a := range msg.Answers {
  436. switch a.Header.Type {
  437. case TypeA:
  438. if err := b.AResource(a.Header, *a.Body.(*AResource)); err != nil {
  439. t.Fatalf("b.AResource(%#v): %v", a, err)
  440. }
  441. case TypeNS:
  442. if err := b.NSResource(a.Header, *a.Body.(*NSResource)); err != nil {
  443. t.Fatalf("b.NSResource(%#v): %v", a, err)
  444. }
  445. case TypeCNAME:
  446. if err := b.CNAMEResource(a.Header, *a.Body.(*CNAMEResource)); err != nil {
  447. t.Fatalf("b.CNAMEResource(%#v): %v", a, err)
  448. }
  449. case TypeSOA:
  450. if err := b.SOAResource(a.Header, *a.Body.(*SOAResource)); err != nil {
  451. t.Fatalf("b.SOAResource(%#v): %v", a, err)
  452. }
  453. case TypePTR:
  454. if err := b.PTRResource(a.Header, *a.Body.(*PTRResource)); err != nil {
  455. t.Fatalf("b.PTRResource(%#v): %v", a, err)
  456. }
  457. case TypeMX:
  458. if err := b.MXResource(a.Header, *a.Body.(*MXResource)); err != nil {
  459. t.Fatalf("b.MXResource(%#v): %v", a, err)
  460. }
  461. case TypeTXT:
  462. if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
  463. t.Fatalf("b.TXTResource(%#v): %v", a, err)
  464. }
  465. case TypeAAAA:
  466. if err := b.AAAAResource(a.Header, *a.Body.(*AAAAResource)); err != nil {
  467. t.Fatalf("b.AAAAResource(%#v): %v", a, err)
  468. }
  469. case TypeSRV:
  470. if err := b.SRVResource(a.Header, *a.Body.(*SRVResource)); err != nil {
  471. t.Fatalf("b.SRVResource(%#v): %v", a, err)
  472. }
  473. }
  474. }
  475. if err := b.StartAuthorities(); err != nil {
  476. t.Fatal("b.StartAuthorities():", err)
  477. }
  478. for _, a := range msg.Authorities {
  479. if err := b.NSResource(a.Header, *a.Body.(*NSResource)); err != nil {
  480. t.Fatalf("b.NSResource(%#v): %v", a, err)
  481. }
  482. }
  483. if err := b.StartAdditionals(); err != nil {
  484. t.Fatal("b.StartAdditionals():", err)
  485. }
  486. for _, a := range msg.Additionals {
  487. if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
  488. t.Fatalf("b.TXTResource(%#v): %v", a, err)
  489. }
  490. }
  491. got, err := b.Finish()
  492. if err != nil {
  493. t.Fatal("b.Finish():", err)
  494. }
  495. if !bytes.Equal(got, want) {
  496. t.Fatalf("Got from Builder: %#v\nwant = %#v", got, want)
  497. }
  498. }
  499. func TestResourcePack(t *testing.T) {
  500. for _, m := range []Message{
  501. {
  502. Questions: []Question{
  503. {
  504. Name: mustNewName("."),
  505. Type: TypeAAAA,
  506. Class: ClassINET,
  507. },
  508. },
  509. Answers: []Resource{{ResourceHeader{}, nil}},
  510. },
  511. {
  512. Questions: []Question{
  513. {
  514. Name: mustNewName("."),
  515. Type: TypeAAAA,
  516. Class: ClassINET,
  517. },
  518. },
  519. Authorities: []Resource{{ResourceHeader{}, (*NSResource)(nil)}},
  520. },
  521. {
  522. Questions: []Question{
  523. {
  524. Name: mustNewName("."),
  525. Type: TypeA,
  526. Class: ClassINET,
  527. },
  528. },
  529. Additionals: []Resource{{ResourceHeader{}, nil}},
  530. },
  531. } {
  532. if _, err := m.Pack(); err == nil {
  533. t.Errorf("should fail: %v", m)
  534. }
  535. }
  536. }
  537. func BenchmarkParsing(b *testing.B) {
  538. b.ReportAllocs()
  539. name := mustNewName("foo.bar.example.com.")
  540. msg := Message{
  541. Header: Header{Response: true, Authoritative: true},
  542. Questions: []Question{
  543. {
  544. Name: name,
  545. Type: TypeA,
  546. Class: ClassINET,
  547. },
  548. },
  549. Answers: []Resource{
  550. {
  551. ResourceHeader{
  552. Name: name,
  553. Class: ClassINET,
  554. },
  555. &AResource{[4]byte{}},
  556. },
  557. {
  558. ResourceHeader{
  559. Name: name,
  560. Class: ClassINET,
  561. },
  562. &AAAAResource{[16]byte{}},
  563. },
  564. {
  565. ResourceHeader{
  566. Name: name,
  567. Class: ClassINET,
  568. },
  569. &CNAMEResource{name},
  570. },
  571. {
  572. ResourceHeader{
  573. Name: name,
  574. Class: ClassINET,
  575. },
  576. &NSResource{name},
  577. },
  578. },
  579. }
  580. buf, err := msg.Pack()
  581. if err != nil {
  582. b.Fatal("msg.Pack():", err)
  583. }
  584. for i := 0; i < b.N; i++ {
  585. var p Parser
  586. if _, err := p.Start(buf); err != nil {
  587. b.Fatal("p.Start(buf):", err)
  588. }
  589. for {
  590. _, err := p.Question()
  591. if err == ErrSectionDone {
  592. break
  593. }
  594. if err != nil {
  595. b.Fatal("p.Question():", err)
  596. }
  597. }
  598. for {
  599. h, err := p.AnswerHeader()
  600. if err == ErrSectionDone {
  601. break
  602. }
  603. if err != nil {
  604. panic(err)
  605. }
  606. switch h.Type {
  607. case TypeA:
  608. if _, err := p.AResource(); err != nil {
  609. b.Fatal("p.AResource():", err)
  610. }
  611. case TypeAAAA:
  612. if _, err := p.AAAAResource(); err != nil {
  613. b.Fatal("p.AAAAResource():", err)
  614. }
  615. case TypeCNAME:
  616. if _, err := p.CNAMEResource(); err != nil {
  617. b.Fatal("p.CNAMEResource():", err)
  618. }
  619. case TypeNS:
  620. if _, err := p.NSResource(); err != nil {
  621. b.Fatal("p.NSResource():", err)
  622. }
  623. default:
  624. b.Fatalf("unknown type: %T", h)
  625. }
  626. }
  627. }
  628. }
  629. func BenchmarkBuilding(b *testing.B) {
  630. b.ReportAllocs()
  631. name := mustNewName("foo.bar.example.com.")
  632. buf := make([]byte, 0, packStartingCap)
  633. for i := 0; i < b.N; i++ {
  634. var bld Builder
  635. bld.StartWithoutCompression(buf, Header{Response: true, Authoritative: true})
  636. if err := bld.StartQuestions(); err != nil {
  637. b.Fatal("bld.StartQuestions():", err)
  638. }
  639. q := Question{
  640. Name: name,
  641. Type: TypeA,
  642. Class: ClassINET,
  643. }
  644. if err := bld.Question(q); err != nil {
  645. b.Fatalf("bld.Question(%+v): %v", q, err)
  646. }
  647. hdr := ResourceHeader{
  648. Name: name,
  649. Class: ClassINET,
  650. }
  651. if err := bld.StartAnswers(); err != nil {
  652. b.Fatal("bld.StartQuestions():", err)
  653. }
  654. ar := AResource{[4]byte{}}
  655. if err := bld.AResource(hdr, ar); err != nil {
  656. b.Fatalf("bld.AResource(%+v, %+v): %v", hdr, ar, err)
  657. }
  658. aaar := AAAAResource{[16]byte{}}
  659. if err := bld.AAAAResource(hdr, aaar); err != nil {
  660. b.Fatalf("bld.AAAAResource(%+v, %+v): %v", hdr, aaar, err)
  661. }
  662. cnr := CNAMEResource{name}
  663. if err := bld.CNAMEResource(hdr, cnr); err != nil {
  664. b.Fatalf("bld.CNAMEResource(%+v, %+v): %v", hdr, cnr, err)
  665. }
  666. nsr := NSResource{name}
  667. if err := bld.NSResource(hdr, nsr); err != nil {
  668. b.Fatalf("bld.NSResource(%+v, %+v): %v", hdr, nsr, err)
  669. }
  670. if _, err := bld.Finish(); err != nil {
  671. b.Fatal("bld.Finish():", err)
  672. }
  673. }
  674. }
  675. func largeTestMsg() Message {
  676. name := mustNewName("foo.bar.example.com.")
  677. return Message{
  678. Header: Header{Response: true, Authoritative: true},
  679. Questions: []Question{
  680. {
  681. Name: name,
  682. Type: TypeA,
  683. Class: ClassINET,
  684. },
  685. },
  686. Answers: []Resource{
  687. {
  688. ResourceHeader{
  689. Name: name,
  690. Type: TypeA,
  691. Class: ClassINET,
  692. },
  693. &AResource{[4]byte{127, 0, 0, 1}},
  694. },
  695. {
  696. ResourceHeader{
  697. Name: name,
  698. Type: TypeA,
  699. Class: ClassINET,
  700. },
  701. &AResource{[4]byte{127, 0, 0, 2}},
  702. },
  703. {
  704. ResourceHeader{
  705. Name: name,
  706. Type: TypeAAAA,
  707. Class: ClassINET,
  708. },
  709. &AAAAResource{[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}},
  710. },
  711. {
  712. ResourceHeader{
  713. Name: name,
  714. Type: TypeCNAME,
  715. Class: ClassINET,
  716. },
  717. &CNAMEResource{mustNewName("alias.example.com.")},
  718. },
  719. {
  720. ResourceHeader{
  721. Name: name,
  722. Type: TypeSOA,
  723. Class: ClassINET,
  724. },
  725. &SOAResource{
  726. NS: mustNewName("ns1.example.com."),
  727. MBox: mustNewName("mb.example.com."),
  728. Serial: 1,
  729. Refresh: 2,
  730. Retry: 3,
  731. Expire: 4,
  732. MinTTL: 5,
  733. },
  734. },
  735. {
  736. ResourceHeader{
  737. Name: name,
  738. Type: TypePTR,
  739. Class: ClassINET,
  740. },
  741. &PTRResource{mustNewName("ptr.example.com.")},
  742. },
  743. {
  744. ResourceHeader{
  745. Name: name,
  746. Type: TypeMX,
  747. Class: ClassINET,
  748. },
  749. &MXResource{
  750. 7,
  751. mustNewName("mx.example.com."),
  752. },
  753. },
  754. {
  755. ResourceHeader{
  756. Name: name,
  757. Type: TypeSRV,
  758. Class: ClassINET,
  759. },
  760. &SRVResource{
  761. 8,
  762. 9,
  763. 11,
  764. mustNewName("srv.example.com."),
  765. },
  766. },
  767. },
  768. Authorities: []Resource{
  769. {
  770. ResourceHeader{
  771. Name: name,
  772. Type: TypeNS,
  773. Class: ClassINET,
  774. },
  775. &NSResource{mustNewName("ns1.example.com.")},
  776. },
  777. {
  778. ResourceHeader{
  779. Name: name,
  780. Type: TypeNS,
  781. Class: ClassINET,
  782. },
  783. &NSResource{mustNewName("ns2.example.com.")},
  784. },
  785. },
  786. Additionals: []Resource{
  787. {
  788. ResourceHeader{
  789. Name: name,
  790. Type: TypeTXT,
  791. Class: ClassINET,
  792. },
  793. &TXTResource{"So Long, and Thanks for All the Fish"},
  794. },
  795. {
  796. ResourceHeader{
  797. Name: name,
  798. Type: TypeTXT,
  799. Class: ClassINET,
  800. },
  801. &TXTResource{"Hamster Huey and the Gooey Kablooie"},
  802. },
  803. },
  804. }
  805. }
  806. const loremIpsum = `
  807. Lorem ipsum dolor sit amet, nec enim antiopam id, an ullum choro
  808. nonumes qui, pro eu debet honestatis mediocritatem. No alia enim eos,
  809. magna signiferumque ex vis. Mei no aperiri dissentias, cu vel quas
  810. regione. Malorum quaeque vim ut, eum cu semper aliquid invidunt, ei
  811. nam ipsum assentior.
  812. Nostrum appellantur usu no, vis ex probatus adipiscing. Cu usu illum
  813. facilis eleifend. Iusto conceptam complectitur vim id. Tale omnesque
  814. no usu, ei oblique sadipscing vim. At nullam voluptua usu, mei laudem
  815. reformidans et. Qui ei eros porro reformidans, ius suas veritus
  816. torquatos ex. Mea te facer alterum consequat.
  817. Soleat torquatos democritum sed et, no mea congue appareat, facer
  818. aliquam nec in. Has te ipsum tritani. At justo dicta option nec, movet
  819. phaedrum ad nam. Ea detracto verterem liberavisse has, delectus
  820. suscipiantur in mei. Ex nam meliore complectitur. Ut nam omnis
  821. honestatis quaerendum, ea mea nihil affert detracto, ad vix rebum
  822. mollis.
  823. Ut epicurei praesent neglegentur pri, prima fuisset intellegebat ad
  824. vim. An habemus comprehensam usu, at enim dignissim pro. Eam reque
  825. vivendum adipisci ea. Vel ne odio choro minimum. Sea admodum
  826. dissentiet ex. Mundi tamquam evertitur ius cu. Homero postea iisque ut
  827. pro, vel ne saepe senserit consetetur.
  828. Nulla utamur facilisis ius ea, in viderer diceret pertinax eum. Mei no
  829. enim quodsi facilisi, ex sed aeterno appareat mediocritatem, eum
  830. sententiae deterruisset ut. At suas timeam euismod cum, offendit
  831. appareat interpretaris ne vix. Vel ea civibus albucius, ex vim quidam
  832. accusata intellegebat, noluisse instructior sea id. Nec te nonumes
  833. habemus appellantur, quis dignissim vituperata eu nam.
  834. At vix apeirian patrioque vituperatoribus, an usu agam assum. Debet
  835. iisque an mea. Per eu dicant ponderum accommodare. Pri alienum
  836. placerat senserit an, ne eum ferri abhorreant vituperatoribus. Ut mea
  837. eligendi disputationi. Ius no tation everti impedit, ei magna quidam
  838. mediocritatem pri.
  839. Legendos perpetua iracundia ne usu, no ius ullum epicurei intellegam,
  840. ad modus epicuri lucilius eam. In unum quaerendum usu. Ne diam paulo
  841. has, ea veri virtute sed. Alia honestatis conclusionemque mea eu, ut
  842. iudico albucius his.
  843. Usu essent probatus eu, sed omnis dolor delicatissimi ex. No qui augue
  844. dissentias dissentiet. Laudem recteque no usu, vel an velit noluisse,
  845. an sed utinam eirmod appetere. Ne mea fuisset inimicus ocurreret. At
  846. vis dicant abhorreant, utinam forensibus nec ne, mei te docendi
  847. consequat. Brute inermis persecuti cum id. Ut ipsum munere propriae
  848. usu, dicit graeco disputando id has.
  849. Eros dolore quaerendum nam ei. Timeam ornatus inciderint pro id. Nec
  850. torquatos sadipscing ei, ancillae molestie per in. Malis principes duo
  851. ea, usu liber postulant ei.
  852. Graece timeam voluptatibus eu eam. Alia probatus quo no, ea scripta
  853. feugiat duo. Congue option meliore ex qui, noster invenire appellantur
  854. ea vel. Eu exerci legendos vel. Consetetur repudiandae vim ut. Vix an
  855. probo minimum, et nam illud falli tempor.
  856. Cum dico signiferumque eu. Sed ut regione maiorum, id veritus insolens
  857. tacimates vix. Eu mel sint tamquam lucilius, duo no oporteat
  858. tacimates. Atqui augue concludaturque vix ei, id mel utroque menandri.
  859. Ad oratio blandit aliquando pro. Vis et dolorum rationibus
  860. philosophia, ad cum nulla molestie. Hinc fuisset adversarium eum et,
  861. ne qui nisl verear saperet, vel te quaestio forensibus. Per odio
  862. option delenit an. Alii placerat has no, in pri nihil platonem
  863. cotidieque. Est ut elit copiosae scaevola, debet tollit maluisset sea
  864. an.
  865. Te sea hinc debet pericula, liber ridens fabulas cu sed, quem mutat
  866. accusam mea et. Elitr labitur albucius et pri, an labore feugait mel.
  867. Velit zril melius usu ea. Ad stet putent interpretaris qui. Mel no
  868. error volumus scripserit. In pro paulo iudico, quo ei dolorem
  869. verterem, affert fabellas dissentiet ea vix.
  870. Vis quot deserunt te. Error aliquid detraxit eu usu, vis alia eruditi
  871. salutatus cu. Est nostrud bonorum an, ei usu alii salutatus. Vel at
  872. nisl primis, eum ex aperiri noluisse reformidans. Ad veri velit
  873. utroque vis, ex equidem detraxit temporibus has.
  874. Inermis appareat usu ne. Eros placerat periculis mea ad, in dictas
  875. pericula pro. Errem postulant at usu, ea nec amet ornatus mentitum. Ad
  876. mazim graeco eum, vel ex percipit volutpat iudicabit, sit ne delicata
  877. interesset. Mel sapientem prodesset abhorreant et, oblique suscipit
  878. eam id.
  879. An maluisset disputando mea, vidit mnesarchum pri et. Malis insolens
  880. inciderint no sea. Ea persius maluisset vix, ne vim appellantur
  881. instructior, consul quidam definiebas pri id. Cum integre feugiat
  882. pericula in, ex sed persius similique, mel ne natum dicit percipitur.
  883. Primis discere ne pri, errem putent definitionem at vis. Ei mel dolore
  884. neglegentur, mei tincidunt percipitur ei. Pro ad simul integre
  885. rationibus. Eu vel alii honestatis definitiones, mea no nonumy
  886. reprehendunt.
  887. Dicta appareat legendos est cu. Eu vel congue dicunt omittam, no vix
  888. adhuc minimum constituam, quot noluisse id mel. Eu quot sale mutat
  889. duo, ex nisl munere invenire duo. Ne nec ullum utamur. Pro alterum
  890. debitis nostrum no, ut vel aliquid vivendo.
  891. Aliquip fierent praesent quo ne, id sit audiam recusabo delicatissimi.
  892. Usu postulant incorrupte cu. At pro dicit tibique intellegam, cibo
  893. dolore impedit id eam, et aeque feugait assentior has. Quando sensibus
  894. nec ex. Possit sensibus pri ad, unum mutat periculis cu vix.
  895. Mundi tibique vix te, duo simul partiendo qualisque id, est at vidit
  896. sonet tempor. No per solet aeterno deseruisse. Petentium salutandi
  897. definiebas pri cu. Munere vivendum est in. Ei justo congue eligendi
  898. vis, modus offendit omittantur te mel.
  899. Integre voluptaria in qui, sit habemus tractatos constituam no. Utinam
  900. melius conceptam est ne, quo in minimum apeirian delicata, ut ius
  901. porro recusabo. Dicant expetenda vix no, ludus scripserit sed ex, eu
  902. his modo nostro. Ut etiam sonet his, quodsi inciderint philosophia te
  903. per. Nullam lobortis eu cum, vix an sonet efficiendi repudiandae. Vis
  904. ad idque fabellas intellegebat.
  905. Eum commodo senserit conclusionemque ex. Sed forensibus sadipscing ut,
  906. mei in facer delicata periculis, sea ne hinc putent cetero. Nec ne
  907. alia corpora invenire, alia prima soleat te cum. Eleifend posidonium
  908. nam at.
  909. Dolorum indoctum cu quo, ex dolor legendos recteque eam, cu pri zril
  910. discere. Nec civibus officiis dissentiunt ex, est te liber ludus
  911. elaboraret. Cum ea fabellas invenire. Ex vim nostrud eripuit
  912. comprehensam, nam te inermis delectus, saepe inermis senserit.
  913. `