message_test.go 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  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 TestSkipEach(t *testing.T) {
  262. msg := smallTestMsg()
  263. buf, err := msg.Pack()
  264. if err != nil {
  265. t.Fatal("Packing test message:", err)
  266. }
  267. var p Parser
  268. if _, err := p.Start(buf); err != nil {
  269. t.Fatal(err)
  270. }
  271. tests := []struct {
  272. name string
  273. f func() error
  274. }{
  275. {"SkipQuestion", p.SkipQuestion},
  276. {"SkipAnswer", p.SkipAnswer},
  277. {"SkipAuthority", p.SkipAuthority},
  278. {"SkipAdditional", p.SkipAdditional},
  279. }
  280. for _, test := range tests {
  281. if err := test.f(); err != nil {
  282. t.Errorf("First call: got %s() = %v, want = %v", test.name, err, nil)
  283. }
  284. if err := test.f(); err != ErrSectionDone {
  285. t.Errorf("Second call: got %s() = %v, want = %v", test.name, err, ErrSectionDone)
  286. }
  287. }
  288. }
  289. func TestSkipAfterRead(t *testing.T) {
  290. msg := smallTestMsg()
  291. buf, err := msg.Pack()
  292. if err != nil {
  293. t.Fatal("Packing test message:", err)
  294. }
  295. var p Parser
  296. if _, err := p.Start(buf); err != nil {
  297. t.Fatal(err)
  298. }
  299. tests := []struct {
  300. name string
  301. skip func() error
  302. read func() error
  303. }{
  304. {"Question", p.SkipQuestion, func() error { _, err := p.Question(); return err }},
  305. {"Answer", p.SkipAnswer, func() error { _, err := p.Answer(); return err }},
  306. {"Authority", p.SkipAuthority, func() error { _, err := p.Authority(); return err }},
  307. {"Additional", p.SkipAdditional, func() error { _, err := p.Additional(); return err }},
  308. }
  309. for _, test := range tests {
  310. if err := test.read(); err != nil {
  311. t.Errorf("Got %s() = _, %v, want = _, %v", test.name, err, nil)
  312. }
  313. if err := test.skip(); err != ErrSectionDone {
  314. t.Errorf("Got Skip%s() = %v, want = %v", test.name, err, ErrSectionDone)
  315. }
  316. }
  317. }
  318. func TestSkipNotStarted(t *testing.T) {
  319. var p Parser
  320. tests := []struct {
  321. name string
  322. f func() error
  323. }{
  324. {"SkipAllQuestions", p.SkipAllQuestions},
  325. {"SkipAllAnswers", p.SkipAllAnswers},
  326. {"SkipAllAuthorities", p.SkipAllAuthorities},
  327. {"SkipAllAdditionals", p.SkipAllAdditionals},
  328. }
  329. for _, test := range tests {
  330. if err := test.f(); err != ErrNotStarted {
  331. t.Errorf("Got %s() = %v, want = %v", test.name, err, ErrNotStarted)
  332. }
  333. }
  334. }
  335. func TestTooManyRecords(t *testing.T) {
  336. const recs = int(^uint16(0)) + 1
  337. tests := []struct {
  338. name string
  339. msg Message
  340. want error
  341. }{
  342. {
  343. "Questions",
  344. Message{
  345. Questions: make([]Question, recs),
  346. },
  347. errTooManyQuestions,
  348. },
  349. {
  350. "Answers",
  351. Message{
  352. Answers: make([]Resource, recs),
  353. },
  354. errTooManyAnswers,
  355. },
  356. {
  357. "Authorities",
  358. Message{
  359. Authorities: make([]Resource, recs),
  360. },
  361. errTooManyAuthorities,
  362. },
  363. {
  364. "Additionals",
  365. Message{
  366. Additionals: make([]Resource, recs),
  367. },
  368. errTooManyAdditionals,
  369. },
  370. }
  371. for _, test := range tests {
  372. if _, got := test.msg.Pack(); got != test.want {
  373. t.Errorf("Packing %d %s: got = %v, want = %v", recs, test.name, got, test.want)
  374. }
  375. }
  376. }
  377. func TestVeryLongTxt(t *testing.T) {
  378. want := Resource{
  379. ResourceHeader{
  380. Name: mustNewName("foo.bar.example.com."),
  381. Type: TypeTXT,
  382. Class: ClassINET,
  383. },
  384. &TXTResource{loremIpsum},
  385. }
  386. buf, err := want.pack(make([]byte, 0, 8000), map[string]int{})
  387. if err != nil {
  388. t.Fatal("Packing failed:", err)
  389. }
  390. var got Resource
  391. off, err := got.Header.unpack(buf, 0)
  392. if err != nil {
  393. t.Fatal("Unpacking ResourceHeader failed:", err)
  394. }
  395. body, n, err := unpackResourceBody(buf, off, got.Header)
  396. if err != nil {
  397. t.Fatal("Unpacking failed:", err)
  398. }
  399. got.Body = body
  400. if n != len(buf) {
  401. t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", n, len(buf))
  402. }
  403. if !reflect.DeepEqual(got, want) {
  404. t.Errorf("Got = %#v, want = %#v", got, want)
  405. }
  406. }
  407. func TestStartError(t *testing.T) {
  408. tests := []struct {
  409. name string
  410. fn func(*Builder) error
  411. }{
  412. {"Questions", func(b *Builder) error { return b.StartQuestions() }},
  413. {"Answers", func(b *Builder) error { return b.StartAnswers() }},
  414. {"Authorities", func(b *Builder) error { return b.StartAuthorities() }},
  415. {"Additionals", func(b *Builder) error { return b.StartAdditionals() }},
  416. }
  417. envs := []struct {
  418. name string
  419. fn func() *Builder
  420. want error
  421. }{
  422. {"sectionNotStarted", func() *Builder { return &Builder{section: sectionNotStarted} }, ErrNotStarted},
  423. {"sectionDone", func() *Builder { return &Builder{section: sectionDone} }, ErrSectionDone},
  424. }
  425. for _, env := range envs {
  426. for _, test := range tests {
  427. if got := test.fn(env.fn()); got != env.want {
  428. t.Errorf("got Builder{%s}.Start%s = %v, want = %v", env.name, test.name, got, env.want)
  429. }
  430. }
  431. }
  432. }
  433. func TestBuilderResourceError(t *testing.T) {
  434. tests := []struct {
  435. name string
  436. fn func(*Builder) error
  437. }{
  438. {"CNAMEResource", func(b *Builder) error { return b.CNAMEResource(ResourceHeader{}, CNAMEResource{}) }},
  439. {"MXResource", func(b *Builder) error { return b.MXResource(ResourceHeader{}, MXResource{}) }},
  440. {"NSResource", func(b *Builder) error { return b.NSResource(ResourceHeader{}, NSResource{}) }},
  441. {"PTRResource", func(b *Builder) error { return b.PTRResource(ResourceHeader{}, PTRResource{}) }},
  442. {"SOAResource", func(b *Builder) error { return b.SOAResource(ResourceHeader{}, SOAResource{}) }},
  443. {"TXTResource", func(b *Builder) error { return b.TXTResource(ResourceHeader{}, TXTResource{}) }},
  444. {"SRVResource", func(b *Builder) error { return b.SRVResource(ResourceHeader{}, SRVResource{}) }},
  445. {"AResource", func(b *Builder) error { return b.AResource(ResourceHeader{}, AResource{}) }},
  446. {"AAAAResource", func(b *Builder) error { return b.AAAAResource(ResourceHeader{}, AAAAResource{}) }},
  447. }
  448. envs := []struct {
  449. name string
  450. fn func() *Builder
  451. want error
  452. }{
  453. {"sectionNotStarted", func() *Builder { return &Builder{section: sectionNotStarted} }, ErrNotStarted},
  454. {"sectionHeader", func() *Builder { return &Builder{section: sectionHeader} }, ErrNotStarted},
  455. {"sectionQuestions", func() *Builder { return &Builder{section: sectionQuestions} }, ErrNotStarted},
  456. {"sectionDone", func() *Builder { return &Builder{section: sectionDone} }, ErrSectionDone},
  457. }
  458. for _, env := range envs {
  459. for _, test := range tests {
  460. if got := test.fn(env.fn()); got != env.want {
  461. t.Errorf("got Builder{%s}.%s = %v, want = %v", env.name, test.name, got, env.want)
  462. }
  463. }
  464. }
  465. }
  466. func TestFinishError(t *testing.T) {
  467. var b Builder
  468. want := ErrNotStarted
  469. if _, got := b.Finish(); got != want {
  470. t.Errorf("got Builder{}.Finish() = %v, want = %v", got, want)
  471. }
  472. }
  473. func TestBuilder(t *testing.T) {
  474. msg := largeTestMsg()
  475. want, err := msg.Pack()
  476. if err != nil {
  477. t.Fatal("Packing without builder:", err)
  478. }
  479. var b Builder
  480. b.Start(nil, msg.Header)
  481. if err := b.StartQuestions(); err != nil {
  482. t.Fatal("b.StartQuestions():", err)
  483. }
  484. for _, q := range msg.Questions {
  485. if err := b.Question(q); err != nil {
  486. t.Fatalf("b.Question(%#v): %v", q, err)
  487. }
  488. }
  489. if err := b.StartAnswers(); err != nil {
  490. t.Fatal("b.StartAnswers():", err)
  491. }
  492. for _, a := range msg.Answers {
  493. switch a.Header.Type {
  494. case TypeA:
  495. if err := b.AResource(a.Header, *a.Body.(*AResource)); err != nil {
  496. t.Fatalf("b.AResource(%#v): %v", a, err)
  497. }
  498. case TypeNS:
  499. if err := b.NSResource(a.Header, *a.Body.(*NSResource)); err != nil {
  500. t.Fatalf("b.NSResource(%#v): %v", a, err)
  501. }
  502. case TypeCNAME:
  503. if err := b.CNAMEResource(a.Header, *a.Body.(*CNAMEResource)); err != nil {
  504. t.Fatalf("b.CNAMEResource(%#v): %v", a, err)
  505. }
  506. case TypeSOA:
  507. if err := b.SOAResource(a.Header, *a.Body.(*SOAResource)); err != nil {
  508. t.Fatalf("b.SOAResource(%#v): %v", a, err)
  509. }
  510. case TypePTR:
  511. if err := b.PTRResource(a.Header, *a.Body.(*PTRResource)); err != nil {
  512. t.Fatalf("b.PTRResource(%#v): %v", a, err)
  513. }
  514. case TypeMX:
  515. if err := b.MXResource(a.Header, *a.Body.(*MXResource)); err != nil {
  516. t.Fatalf("b.MXResource(%#v): %v", a, err)
  517. }
  518. case TypeTXT:
  519. if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
  520. t.Fatalf("b.TXTResource(%#v): %v", a, err)
  521. }
  522. case TypeAAAA:
  523. if err := b.AAAAResource(a.Header, *a.Body.(*AAAAResource)); err != nil {
  524. t.Fatalf("b.AAAAResource(%#v): %v", a, err)
  525. }
  526. case TypeSRV:
  527. if err := b.SRVResource(a.Header, *a.Body.(*SRVResource)); err != nil {
  528. t.Fatalf("b.SRVResource(%#v): %v", a, err)
  529. }
  530. }
  531. }
  532. if err := b.StartAuthorities(); err != nil {
  533. t.Fatal("b.StartAuthorities():", err)
  534. }
  535. for _, a := range msg.Authorities {
  536. if err := b.NSResource(a.Header, *a.Body.(*NSResource)); err != nil {
  537. t.Fatalf("b.NSResource(%#v): %v", a, err)
  538. }
  539. }
  540. if err := b.StartAdditionals(); err != nil {
  541. t.Fatal("b.StartAdditionals():", err)
  542. }
  543. for _, a := range msg.Additionals {
  544. if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
  545. t.Fatalf("b.TXTResource(%#v): %v", a, err)
  546. }
  547. }
  548. got, err := b.Finish()
  549. if err != nil {
  550. t.Fatal("b.Finish():", err)
  551. }
  552. if !bytes.Equal(got, want) {
  553. t.Fatalf("Got from Builder: %#v\nwant = %#v", got, want)
  554. }
  555. }
  556. func TestResourcePack(t *testing.T) {
  557. for _, tt := range []struct {
  558. m Message
  559. err error
  560. }{
  561. {
  562. Message{
  563. Questions: []Question{
  564. {
  565. Name: mustNewName("."),
  566. Type: TypeAAAA,
  567. Class: ClassINET,
  568. },
  569. },
  570. Answers: []Resource{{ResourceHeader{}, nil}},
  571. },
  572. &nestedError{"packing Answer", errNilResouceBody},
  573. },
  574. {
  575. Message{
  576. Questions: []Question{
  577. {
  578. Name: mustNewName("."),
  579. Type: TypeAAAA,
  580. Class: ClassINET,
  581. },
  582. },
  583. Authorities: []Resource{{ResourceHeader{}, (*NSResource)(nil)}},
  584. },
  585. &nestedError{"packing Authority",
  586. &nestedError{"ResourceHeader",
  587. &nestedError{"Name", errNonCanonicalName},
  588. },
  589. },
  590. },
  591. {
  592. Message{
  593. Questions: []Question{
  594. {
  595. Name: mustNewName("."),
  596. Type: TypeA,
  597. Class: ClassINET,
  598. },
  599. },
  600. Additionals: []Resource{{ResourceHeader{}, nil}},
  601. },
  602. &nestedError{"packing Additional", errNilResouceBody},
  603. },
  604. } {
  605. _, err := tt.m.Pack()
  606. if !reflect.DeepEqual(err, tt.err) {
  607. t.Errorf("got %v for %v; want %v", err, tt.m, tt.err)
  608. }
  609. }
  610. }
  611. func BenchmarkParsing(b *testing.B) {
  612. b.ReportAllocs()
  613. name := mustNewName("foo.bar.example.com.")
  614. msg := Message{
  615. Header: Header{Response: true, Authoritative: true},
  616. Questions: []Question{
  617. {
  618. Name: name,
  619. Type: TypeA,
  620. Class: ClassINET,
  621. },
  622. },
  623. Answers: []Resource{
  624. {
  625. ResourceHeader{
  626. Name: name,
  627. Class: ClassINET,
  628. },
  629. &AResource{[4]byte{}},
  630. },
  631. {
  632. ResourceHeader{
  633. Name: name,
  634. Class: ClassINET,
  635. },
  636. &AAAAResource{[16]byte{}},
  637. },
  638. {
  639. ResourceHeader{
  640. Name: name,
  641. Class: ClassINET,
  642. },
  643. &CNAMEResource{name},
  644. },
  645. {
  646. ResourceHeader{
  647. Name: name,
  648. Class: ClassINET,
  649. },
  650. &NSResource{name},
  651. },
  652. },
  653. }
  654. buf, err := msg.Pack()
  655. if err != nil {
  656. b.Fatal("msg.Pack():", err)
  657. }
  658. for i := 0; i < b.N; i++ {
  659. var p Parser
  660. if _, err := p.Start(buf); err != nil {
  661. b.Fatal("p.Start(buf):", err)
  662. }
  663. for {
  664. _, err := p.Question()
  665. if err == ErrSectionDone {
  666. break
  667. }
  668. if err != nil {
  669. b.Fatal("p.Question():", err)
  670. }
  671. }
  672. for {
  673. h, err := p.AnswerHeader()
  674. if err == ErrSectionDone {
  675. break
  676. }
  677. if err != nil {
  678. panic(err)
  679. }
  680. switch h.Type {
  681. case TypeA:
  682. if _, err := p.AResource(); err != nil {
  683. b.Fatal("p.AResource():", err)
  684. }
  685. case TypeAAAA:
  686. if _, err := p.AAAAResource(); err != nil {
  687. b.Fatal("p.AAAAResource():", err)
  688. }
  689. case TypeCNAME:
  690. if _, err := p.CNAMEResource(); err != nil {
  691. b.Fatal("p.CNAMEResource():", err)
  692. }
  693. case TypeNS:
  694. if _, err := p.NSResource(); err != nil {
  695. b.Fatal("p.NSResource():", err)
  696. }
  697. default:
  698. b.Fatalf("unknown type: %T", h)
  699. }
  700. }
  701. }
  702. }
  703. func BenchmarkBuilding(b *testing.B) {
  704. b.ReportAllocs()
  705. name := mustNewName("foo.bar.example.com.")
  706. buf := make([]byte, 0, packStartingCap)
  707. for i := 0; i < b.N; i++ {
  708. var bld Builder
  709. bld.StartWithoutCompression(buf, Header{Response: true, Authoritative: true})
  710. if err := bld.StartQuestions(); err != nil {
  711. b.Fatal("bld.StartQuestions():", err)
  712. }
  713. q := Question{
  714. Name: name,
  715. Type: TypeA,
  716. Class: ClassINET,
  717. }
  718. if err := bld.Question(q); err != nil {
  719. b.Fatalf("bld.Question(%+v): %v", q, err)
  720. }
  721. hdr := ResourceHeader{
  722. Name: name,
  723. Class: ClassINET,
  724. }
  725. if err := bld.StartAnswers(); err != nil {
  726. b.Fatal("bld.StartQuestions():", err)
  727. }
  728. ar := AResource{[4]byte{}}
  729. if err := bld.AResource(hdr, ar); err != nil {
  730. b.Fatalf("bld.AResource(%+v, %+v): %v", hdr, ar, err)
  731. }
  732. aaar := AAAAResource{[16]byte{}}
  733. if err := bld.AAAAResource(hdr, aaar); err != nil {
  734. b.Fatalf("bld.AAAAResource(%+v, %+v): %v", hdr, aaar, err)
  735. }
  736. cnr := CNAMEResource{name}
  737. if err := bld.CNAMEResource(hdr, cnr); err != nil {
  738. b.Fatalf("bld.CNAMEResource(%+v, %+v): %v", hdr, cnr, err)
  739. }
  740. nsr := NSResource{name}
  741. if err := bld.NSResource(hdr, nsr); err != nil {
  742. b.Fatalf("bld.NSResource(%+v, %+v): %v", hdr, nsr, err)
  743. }
  744. if _, err := bld.Finish(); err != nil {
  745. b.Fatal("bld.Finish():", err)
  746. }
  747. }
  748. }
  749. func smallTestMsg() Message {
  750. name := mustNewName("example.com.")
  751. return Message{
  752. Header: Header{Response: true, Authoritative: true},
  753. Questions: []Question{
  754. {
  755. Name: name,
  756. Type: TypeA,
  757. Class: ClassINET,
  758. },
  759. },
  760. Answers: []Resource{
  761. {
  762. ResourceHeader{
  763. Name: name,
  764. Type: TypeA,
  765. Class: ClassINET,
  766. },
  767. &AResource{[4]byte{127, 0, 0, 1}},
  768. },
  769. },
  770. Authorities: []Resource{
  771. {
  772. ResourceHeader{
  773. Name: name,
  774. Type: TypeA,
  775. Class: ClassINET,
  776. },
  777. &AResource{[4]byte{127, 0, 0, 1}},
  778. },
  779. },
  780. Additionals: []Resource{
  781. {
  782. ResourceHeader{
  783. Name: name,
  784. Type: TypeA,
  785. Class: ClassINET,
  786. },
  787. &AResource{[4]byte{127, 0, 0, 1}},
  788. },
  789. },
  790. }
  791. }
  792. func BenchmarkPack(b *testing.B) {
  793. msg := largeTestMsg()
  794. b.ReportAllocs()
  795. for i := 0; i < b.N; i++ {
  796. if _, err := msg.Pack(); err != nil {
  797. b.Fatal(err)
  798. }
  799. }
  800. }
  801. func BenchmarkAppendPack(b *testing.B) {
  802. msg := largeTestMsg()
  803. buf := make([]byte, 0, packStartingCap)
  804. b.ReportAllocs()
  805. for i := 0; i < b.N; i++ {
  806. if _, err := msg.AppendPack(buf[:0]); err != nil {
  807. b.Fatal(err)
  808. }
  809. }
  810. }
  811. func largeTestMsg() Message {
  812. name := mustNewName("foo.bar.example.com.")
  813. return Message{
  814. Header: Header{Response: true, Authoritative: true},
  815. Questions: []Question{
  816. {
  817. Name: name,
  818. Type: TypeA,
  819. Class: ClassINET,
  820. },
  821. },
  822. Answers: []Resource{
  823. {
  824. ResourceHeader{
  825. Name: name,
  826. Type: TypeA,
  827. Class: ClassINET,
  828. },
  829. &AResource{[4]byte{127, 0, 0, 1}},
  830. },
  831. {
  832. ResourceHeader{
  833. Name: name,
  834. Type: TypeA,
  835. Class: ClassINET,
  836. },
  837. &AResource{[4]byte{127, 0, 0, 2}},
  838. },
  839. {
  840. ResourceHeader{
  841. Name: name,
  842. Type: TypeAAAA,
  843. Class: ClassINET,
  844. },
  845. &AAAAResource{[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}},
  846. },
  847. {
  848. ResourceHeader{
  849. Name: name,
  850. Type: TypeCNAME,
  851. Class: ClassINET,
  852. },
  853. &CNAMEResource{mustNewName("alias.example.com.")},
  854. },
  855. {
  856. ResourceHeader{
  857. Name: name,
  858. Type: TypeSOA,
  859. Class: ClassINET,
  860. },
  861. &SOAResource{
  862. NS: mustNewName("ns1.example.com."),
  863. MBox: mustNewName("mb.example.com."),
  864. Serial: 1,
  865. Refresh: 2,
  866. Retry: 3,
  867. Expire: 4,
  868. MinTTL: 5,
  869. },
  870. },
  871. {
  872. ResourceHeader{
  873. Name: name,
  874. Type: TypePTR,
  875. Class: ClassINET,
  876. },
  877. &PTRResource{mustNewName("ptr.example.com.")},
  878. },
  879. {
  880. ResourceHeader{
  881. Name: name,
  882. Type: TypeMX,
  883. Class: ClassINET,
  884. },
  885. &MXResource{
  886. 7,
  887. mustNewName("mx.example.com."),
  888. },
  889. },
  890. {
  891. ResourceHeader{
  892. Name: name,
  893. Type: TypeSRV,
  894. Class: ClassINET,
  895. },
  896. &SRVResource{
  897. 8,
  898. 9,
  899. 11,
  900. mustNewName("srv.example.com."),
  901. },
  902. },
  903. },
  904. Authorities: []Resource{
  905. {
  906. ResourceHeader{
  907. Name: name,
  908. Type: TypeNS,
  909. Class: ClassINET,
  910. },
  911. &NSResource{mustNewName("ns1.example.com.")},
  912. },
  913. {
  914. ResourceHeader{
  915. Name: name,
  916. Type: TypeNS,
  917. Class: ClassINET,
  918. },
  919. &NSResource{mustNewName("ns2.example.com.")},
  920. },
  921. },
  922. Additionals: []Resource{
  923. {
  924. ResourceHeader{
  925. Name: name,
  926. Type: TypeTXT,
  927. Class: ClassINET,
  928. },
  929. &TXTResource{"So Long, and Thanks for All the Fish"},
  930. },
  931. {
  932. ResourceHeader{
  933. Name: name,
  934. Type: TypeTXT,
  935. Class: ClassINET,
  936. },
  937. &TXTResource{"Hamster Huey and the Gooey Kablooie"},
  938. },
  939. },
  940. }
  941. }
  942. const loremIpsum = `
  943. Lorem ipsum dolor sit amet, nec enim antiopam id, an ullum choro
  944. nonumes qui, pro eu debet honestatis mediocritatem. No alia enim eos,
  945. magna signiferumque ex vis. Mei no aperiri dissentias, cu vel quas
  946. regione. Malorum quaeque vim ut, eum cu semper aliquid invidunt, ei
  947. nam ipsum assentior.
  948. Nostrum appellantur usu no, vis ex probatus adipiscing. Cu usu illum
  949. facilis eleifend. Iusto conceptam complectitur vim id. Tale omnesque
  950. no usu, ei oblique sadipscing vim. At nullam voluptua usu, mei laudem
  951. reformidans et. Qui ei eros porro reformidans, ius suas veritus
  952. torquatos ex. Mea te facer alterum consequat.
  953. Soleat torquatos democritum sed et, no mea congue appareat, facer
  954. aliquam nec in. Has te ipsum tritani. At justo dicta option nec, movet
  955. phaedrum ad nam. Ea detracto verterem liberavisse has, delectus
  956. suscipiantur in mei. Ex nam meliore complectitur. Ut nam omnis
  957. honestatis quaerendum, ea mea nihil affert detracto, ad vix rebum
  958. mollis.
  959. Ut epicurei praesent neglegentur pri, prima fuisset intellegebat ad
  960. vim. An habemus comprehensam usu, at enim dignissim pro. Eam reque
  961. vivendum adipisci ea. Vel ne odio choro minimum. Sea admodum
  962. dissentiet ex. Mundi tamquam evertitur ius cu. Homero postea iisque ut
  963. pro, vel ne saepe senserit consetetur.
  964. Nulla utamur facilisis ius ea, in viderer diceret pertinax eum. Mei no
  965. enim quodsi facilisi, ex sed aeterno appareat mediocritatem, eum
  966. sententiae deterruisset ut. At suas timeam euismod cum, offendit
  967. appareat interpretaris ne vix. Vel ea civibus albucius, ex vim quidam
  968. accusata intellegebat, noluisse instructior sea id. Nec te nonumes
  969. habemus appellantur, quis dignissim vituperata eu nam.
  970. At vix apeirian patrioque vituperatoribus, an usu agam assum. Debet
  971. iisque an mea. Per eu dicant ponderum accommodare. Pri alienum
  972. placerat senserit an, ne eum ferri abhorreant vituperatoribus. Ut mea
  973. eligendi disputationi. Ius no tation everti impedit, ei magna quidam
  974. mediocritatem pri.
  975. Legendos perpetua iracundia ne usu, no ius ullum epicurei intellegam,
  976. ad modus epicuri lucilius eam. In unum quaerendum usu. Ne diam paulo
  977. has, ea veri virtute sed. Alia honestatis conclusionemque mea eu, ut
  978. iudico albucius his.
  979. Usu essent probatus eu, sed omnis dolor delicatissimi ex. No qui augue
  980. dissentias dissentiet. Laudem recteque no usu, vel an velit noluisse,
  981. an sed utinam eirmod appetere. Ne mea fuisset inimicus ocurreret. At
  982. vis dicant abhorreant, utinam forensibus nec ne, mei te docendi
  983. consequat. Brute inermis persecuti cum id. Ut ipsum munere propriae
  984. usu, dicit graeco disputando id has.
  985. Eros dolore quaerendum nam ei. Timeam ornatus inciderint pro id. Nec
  986. torquatos sadipscing ei, ancillae molestie per in. Malis principes duo
  987. ea, usu liber postulant ei.
  988. Graece timeam voluptatibus eu eam. Alia probatus quo no, ea scripta
  989. feugiat duo. Congue option meliore ex qui, noster invenire appellantur
  990. ea vel. Eu exerci legendos vel. Consetetur repudiandae vim ut. Vix an
  991. probo minimum, et nam illud falli tempor.
  992. Cum dico signiferumque eu. Sed ut regione maiorum, id veritus insolens
  993. tacimates vix. Eu mel sint tamquam lucilius, duo no oporteat
  994. tacimates. Atqui augue concludaturque vix ei, id mel utroque menandri.
  995. Ad oratio blandit aliquando pro. Vis et dolorum rationibus
  996. philosophia, ad cum nulla molestie. Hinc fuisset adversarium eum et,
  997. ne qui nisl verear saperet, vel te quaestio forensibus. Per odio
  998. option delenit an. Alii placerat has no, in pri nihil platonem
  999. cotidieque. Est ut elit copiosae scaevola, debet tollit maluisset sea
  1000. an.
  1001. Te sea hinc debet pericula, liber ridens fabulas cu sed, quem mutat
  1002. accusam mea et. Elitr labitur albucius et pri, an labore feugait mel.
  1003. Velit zril melius usu ea. Ad stet putent interpretaris qui. Mel no
  1004. error volumus scripserit. In pro paulo iudico, quo ei dolorem
  1005. verterem, affert fabellas dissentiet ea vix.
  1006. Vis quot deserunt te. Error aliquid detraxit eu usu, vis alia eruditi
  1007. salutatus cu. Est nostrud bonorum an, ei usu alii salutatus. Vel at
  1008. nisl primis, eum ex aperiri noluisse reformidans. Ad veri velit
  1009. utroque vis, ex equidem detraxit temporibus has.
  1010. Inermis appareat usu ne. Eros placerat periculis mea ad, in dictas
  1011. pericula pro. Errem postulant at usu, ea nec amet ornatus mentitum. Ad
  1012. mazim graeco eum, vel ex percipit volutpat iudicabit, sit ne delicata
  1013. interesset. Mel sapientem prodesset abhorreant et, oblique suscipit
  1014. eam id.
  1015. An maluisset disputando mea, vidit mnesarchum pri et. Malis insolens
  1016. inciderint no sea. Ea persius maluisset vix, ne vim appellantur
  1017. instructior, consul quidam definiebas pri id. Cum integre feugiat
  1018. pericula in, ex sed persius similique, mel ne natum dicit percipitur.
  1019. Primis discere ne pri, errem putent definitionem at vis. Ei mel dolore
  1020. neglegentur, mei tincidunt percipitur ei. Pro ad simul integre
  1021. rationibus. Eu vel alii honestatis definitiones, mea no nonumy
  1022. reprehendunt.
  1023. Dicta appareat legendos est cu. Eu vel congue dicunt omittam, no vix
  1024. adhuc minimum constituam, quot noluisse id mel. Eu quot sale mutat
  1025. duo, ex nisl munere invenire duo. Ne nec ullum utamur. Pro alterum
  1026. debitis nostrum no, ut vel aliquid vivendo.
  1027. Aliquip fierent praesent quo ne, id sit audiam recusabo delicatissimi.
  1028. Usu postulant incorrupte cu. At pro dicit tibique intellegam, cibo
  1029. dolore impedit id eam, et aeque feugait assentior has. Quando sensibus
  1030. nec ex. Possit sensibus pri ad, unum mutat periculis cu vix.
  1031. Mundi tibique vix te, duo simul partiendo qualisque id, est at vidit
  1032. sonet tempor. No per solet aeterno deseruisse. Petentium salutandi
  1033. definiebas pri cu. Munere vivendum est in. Ei justo congue eligendi
  1034. vis, modus offendit omittantur te mel.
  1035. Integre voluptaria in qui, sit habemus tractatos constituam no. Utinam
  1036. melius conceptam est ne, quo in minimum apeirian delicata, ut ius
  1037. porro recusabo. Dicant expetenda vix no, ludus scripserit sed ex, eu
  1038. his modo nostro. Ut etiam sonet his, quodsi inciderint philosophia te
  1039. per. Nullam lobortis eu cum, vix an sonet efficiendi repudiandae. Vis
  1040. ad idque fabellas intellegebat.
  1041. Eum commodo senserit conclusionemque ex. Sed forensibus sadipscing ut,
  1042. mei in facer delicata periculis, sea ne hinc putent cetero. Nec ne
  1043. alia corpora invenire, alia prima soleat te cum. Eleifend posidonium
  1044. nam at.
  1045. Dolorum indoctum cu quo, ex dolor legendos recteque eam, cu pri zril
  1046. discere. Nec civibus officiis dissentiunt ex, est te liber ludus
  1047. elaboraret. Cum ea fabellas invenire. Ex vim nostrud eripuit
  1048. comprehensam, nam te inermis delectus, saepe inermis senserit.
  1049. `