message_test.go 23 KB

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