message_test.go 27 KB

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