message_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  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. "fmt"
  7. "net"
  8. "reflect"
  9. "strings"
  10. "testing"
  11. )
  12. func (m *Message) String() string {
  13. s := fmt.Sprintf("Message: %#v\n", &m.Header)
  14. if len(m.Questions) > 0 {
  15. s += "-- Questions\n"
  16. for _, q := range m.Questions {
  17. s += fmt.Sprintf("%#v\n", q)
  18. }
  19. }
  20. if len(m.Answers) > 0 {
  21. s += "-- Answers\n"
  22. for _, a := range m.Answers {
  23. s += fmt.Sprintf("%#v\n", a)
  24. }
  25. }
  26. if len(m.Authorities) > 0 {
  27. s += "-- Authorities\n"
  28. for _, ns := range m.Authorities {
  29. s += fmt.Sprintf("%#v\n", ns)
  30. }
  31. }
  32. if len(m.Additionals) > 0 {
  33. s += "-- Additionals\n"
  34. for _, e := range m.Additionals {
  35. s += fmt.Sprintf("%#v\n", e)
  36. }
  37. }
  38. return s
  39. }
  40. func TestQuestionPackUnpack(t *testing.T) {
  41. want := Question{
  42. Name: ".",
  43. Type: TypeA,
  44. Class: ClassINET,
  45. }
  46. buf, err := want.pack(make([]byte, 1, 50), map[string]int{})
  47. if err != nil {
  48. t.Fatal("Packing failed:", err)
  49. }
  50. var p Parser
  51. p.msg = buf
  52. p.header.questions = 1
  53. p.section = sectionQuestions
  54. p.off = 1
  55. got, err := p.Question()
  56. if err != nil {
  57. t.Fatalf("Unpacking failed: %v\n%s", err, string(buf[1:]))
  58. }
  59. if p.off != len(buf) {
  60. t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", p.off, len(buf))
  61. }
  62. if !reflect.DeepEqual(got, want) {
  63. t.Errorf("Got = %+v, want = %+v", got, want)
  64. }
  65. }
  66. func TestNamePackUnpack(t *testing.T) {
  67. tests := []struct {
  68. in string
  69. want string
  70. err error
  71. }{
  72. {"", ".", nil},
  73. {".", ".", nil},
  74. {"google..com", "", errZeroSegLen},
  75. {"google.com", "google.com.", nil},
  76. {"google..com.", "", errZeroSegLen},
  77. {"google.com.", "google.com.", nil},
  78. {".google.com.", "", errZeroSegLen},
  79. {"www..google.com.", "", errZeroSegLen},
  80. {"www.google.com.", "www.google.com.", nil},
  81. }
  82. for _, test := range tests {
  83. buf, err := packName(make([]byte, 0, 30), test.in, map[string]int{})
  84. if err != test.err {
  85. t.Errorf("Packing of %s: got err = %v, want err = %v", test.in, err, test.err)
  86. continue
  87. }
  88. if test.err != nil {
  89. continue
  90. }
  91. got, n, err := unpackName(buf, 0)
  92. if err != nil {
  93. t.Errorf("Unpacking for %s failed: %v", test.in, err)
  94. continue
  95. }
  96. if n != len(buf) {
  97. t.Errorf(
  98. "Unpacked different amount than packed for %s: got n = %d, want = %d",
  99. test.in,
  100. n,
  101. len(buf),
  102. )
  103. }
  104. if got != test.want {
  105. t.Errorf("Unpacking packing of %s: got = %s, want = %s", test.in, got, test.want)
  106. }
  107. }
  108. }
  109. func TestDNSPackUnpack(t *testing.T) {
  110. wants := []Message{
  111. {
  112. Questions: []Question{
  113. {
  114. Name: ".",
  115. Type: TypeAAAA,
  116. Class: ClassINET,
  117. },
  118. },
  119. Answers: []Resource{},
  120. Authorities: []Resource{},
  121. Additionals: []Resource{},
  122. },
  123. largeTestMsg(),
  124. }
  125. for i, want := range wants {
  126. b, err := want.Pack()
  127. if err != nil {
  128. t.Fatalf("%d: packing failed: %v", i, err)
  129. }
  130. var got Message
  131. err = got.Unpack(b)
  132. if err != nil {
  133. t.Fatalf("%d: unpacking failed: %v", i, err)
  134. }
  135. if !reflect.DeepEqual(got, want) {
  136. t.Errorf("%d: got = %+v, want = %+v", i, &got, &want)
  137. }
  138. }
  139. }
  140. func TestSkipAll(t *testing.T) {
  141. msg := largeTestMsg()
  142. buf, err := msg.Pack()
  143. if err != nil {
  144. t.Fatal("Packing large test message:", err)
  145. }
  146. var p Parser
  147. if _, err := p.Start(buf); err != nil {
  148. t.Fatal(err)
  149. }
  150. tests := []struct {
  151. name string
  152. f func() error
  153. }{
  154. {"SkipAllQuestions", p.SkipAllQuestions},
  155. {"SkipAllAnswers", p.SkipAllAnswers},
  156. {"SkipAllAuthorities", p.SkipAllAuthorities},
  157. {"SkipAllAdditionals", p.SkipAllAdditionals},
  158. }
  159. for _, test := range tests {
  160. for i := 1; i <= 3; i++ {
  161. if err := test.f(); err != nil {
  162. t.Errorf("Call #%d to %s(): %v", i, test.name, err)
  163. }
  164. }
  165. }
  166. }
  167. func TestSkipNotStarted(t *testing.T) {
  168. var p Parser
  169. tests := []struct {
  170. name string
  171. f func() error
  172. }{
  173. {"SkipAllQuestions", p.SkipAllQuestions},
  174. {"SkipAllAnswers", p.SkipAllAnswers},
  175. {"SkipAllAuthorities", p.SkipAllAuthorities},
  176. {"SkipAllAdditionals", p.SkipAllAdditionals},
  177. }
  178. for _, test := range tests {
  179. if err := test.f(); err != ErrNotStarted {
  180. t.Errorf("Got %s() = %v, want = %v", test.name, err, ErrNotStarted)
  181. }
  182. }
  183. }
  184. func TestTooManyRecords(t *testing.T) {
  185. const recs = int(^uint16(0)) + 1
  186. tests := []struct {
  187. name string
  188. msg Message
  189. want error
  190. }{
  191. {
  192. "Questions",
  193. Message{
  194. Questions: make([]Question, recs),
  195. },
  196. errTooManyQuestions,
  197. },
  198. {
  199. "Answers",
  200. Message{
  201. Answers: make([]Resource, recs),
  202. },
  203. errTooManyAnswers,
  204. },
  205. {
  206. "Authorities",
  207. Message{
  208. Authorities: make([]Resource, recs),
  209. },
  210. errTooManyAuthorities,
  211. },
  212. {
  213. "Additionals",
  214. Message{
  215. Additionals: make([]Resource, recs),
  216. },
  217. errTooManyAdditionals,
  218. },
  219. }
  220. for _, test := range tests {
  221. if _, got := test.msg.Pack(); got != test.want {
  222. t.Errorf("Packing %d %s: got = %v, want = %v", recs, test.name, got, test.want)
  223. }
  224. }
  225. }
  226. func TestVeryLongTxt(t *testing.T) {
  227. want := &TXTResource{
  228. ResourceHeader: ResourceHeader{
  229. Name: "foo.bar.example.com.",
  230. Type: TypeTXT,
  231. Class: ClassINET,
  232. },
  233. Txt: loremIpsum,
  234. }
  235. buf, err := packResource(make([]byte, 0, 8000), want, map[string]int{})
  236. if err != nil {
  237. t.Fatal("Packing failed:", err)
  238. }
  239. var hdr ResourceHeader
  240. off, err := hdr.unpack(buf, 0)
  241. if err != nil {
  242. t.Fatal("Unpacking ResourceHeader failed:", err)
  243. }
  244. got, n, err := unpackResource(buf, off, hdr)
  245. if err != nil {
  246. t.Fatal("Unpacking failed:", err)
  247. }
  248. if n != len(buf) {
  249. t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", n, len(buf))
  250. }
  251. if !reflect.DeepEqual(got, want) {
  252. t.Errorf("Got = %+v, want = %+v", got, want)
  253. }
  254. }
  255. func ExampleHeaderSearch() {
  256. msg := Message{
  257. Header: Header{Response: true, Authoritative: true},
  258. Questions: []Question{
  259. {
  260. Name: "foo.bar.example.com.",
  261. Type: TypeA,
  262. Class: ClassINET,
  263. },
  264. {
  265. Name: "bar.example.com.",
  266. Type: TypeA,
  267. Class: ClassINET,
  268. },
  269. },
  270. Answers: []Resource{
  271. &AResource{
  272. ResourceHeader: ResourceHeader{
  273. Name: "foo.bar.example.com.",
  274. Type: TypeA,
  275. Class: ClassINET,
  276. },
  277. A: [4]byte{127, 0, 0, 1},
  278. },
  279. &AResource{
  280. ResourceHeader: ResourceHeader{
  281. Name: "bar.example.com.",
  282. Type: TypeA,
  283. Class: ClassINET,
  284. },
  285. A: [4]byte{127, 0, 0, 2},
  286. },
  287. },
  288. }
  289. buf, err := msg.Pack()
  290. if err != nil {
  291. panic(err)
  292. }
  293. wantName := "bar.example.com."
  294. var p Parser
  295. if _, err := p.Start(buf); err != nil {
  296. panic(err)
  297. }
  298. for {
  299. q, err := p.Question()
  300. if err == ErrSectionDone {
  301. break
  302. }
  303. if err != nil {
  304. panic(err)
  305. }
  306. if q.Name != wantName {
  307. continue
  308. }
  309. fmt.Println("Found question for name", wantName)
  310. if err := p.SkipAllQuestions(); err != nil {
  311. panic(err)
  312. }
  313. break
  314. }
  315. var gotIPs []net.IP
  316. for {
  317. h, err := p.AnswerHeader()
  318. if err == ErrSectionDone {
  319. break
  320. }
  321. if err != nil {
  322. panic(err)
  323. }
  324. if (h.Type != TypeA && h.Type != TypeAAAA) || h.Class != ClassINET {
  325. continue
  326. }
  327. if !strings.EqualFold(h.Name, wantName) {
  328. if err := p.SkipAnswer(); err != nil {
  329. panic(err)
  330. }
  331. continue
  332. }
  333. a, err := p.Answer()
  334. if err != nil {
  335. panic(err)
  336. }
  337. switch r := a.(type) {
  338. default:
  339. panic(fmt.Sprintf("unknown type: %T", r))
  340. case *AResource:
  341. gotIPs = append(gotIPs, r.A[:])
  342. case *AAAAResource:
  343. gotIPs = append(gotIPs, r.AAAA[:])
  344. }
  345. }
  346. fmt.Printf("Found A/AAAA records for name %s: %v\n", wantName, gotIPs)
  347. // Output:
  348. // Found question for name bar.example.com.
  349. // Found A/AAAA records for name bar.example.com.: [127.0.0.2]
  350. }
  351. func largeTestMsg() Message {
  352. return Message{
  353. Header: Header{Response: true, Authoritative: true},
  354. Questions: []Question{
  355. {
  356. Name: "foo.bar.example.com.",
  357. Type: TypeA,
  358. Class: ClassINET,
  359. },
  360. },
  361. Answers: []Resource{
  362. &AResource{
  363. ResourceHeader: ResourceHeader{
  364. Name: "foo.bar.example.com.",
  365. Type: TypeA,
  366. Class: ClassINET,
  367. },
  368. A: [4]byte{127, 0, 0, 1},
  369. },
  370. &AResource{
  371. ResourceHeader: ResourceHeader{
  372. Name: "foo.bar.example.com.",
  373. Type: TypeA,
  374. Class: ClassINET,
  375. },
  376. A: [4]byte{127, 0, 0, 2},
  377. },
  378. },
  379. Authorities: []Resource{
  380. &NSResource{
  381. ResourceHeader: ResourceHeader{
  382. Name: "foo.bar.example.com.",
  383. Type: TypeNS,
  384. Class: ClassINET,
  385. },
  386. NS: "ns1.example.com.",
  387. },
  388. &NSResource{
  389. ResourceHeader: ResourceHeader{
  390. Name: "foo.bar.example.com.",
  391. Type: TypeNS,
  392. Class: ClassINET,
  393. },
  394. NS: "ns2.example.com.",
  395. },
  396. },
  397. Additionals: []Resource{
  398. &TXTResource{
  399. ResourceHeader: ResourceHeader{
  400. Name: "foo.bar.example.com.",
  401. Type: TypeTXT,
  402. Class: ClassINET,
  403. },
  404. Txt: "So Long, and Thanks for All the Fish",
  405. },
  406. &TXTResource{
  407. ResourceHeader: ResourceHeader{
  408. Name: "foo.bar.example.com.",
  409. Type: TypeTXT,
  410. Class: ClassINET,
  411. },
  412. Txt: "Hamster Huey and the Gooey Kablooie",
  413. },
  414. },
  415. }
  416. }
  417. const loremIpsum = `
  418. Lorem ipsum dolor sit amet, nec enim antiopam id, an ullum choro
  419. nonumes qui, pro eu debet honestatis mediocritatem. No alia enim eos,
  420. magna signiferumque ex vis. Mei no aperiri dissentias, cu vel quas
  421. regione. Malorum quaeque vim ut, eum cu semper aliquid invidunt, ei
  422. nam ipsum assentior.
  423. Nostrum appellantur usu no, vis ex probatus adipiscing. Cu usu illum
  424. facilis eleifend. Iusto conceptam complectitur vim id. Tale omnesque
  425. no usu, ei oblique sadipscing vim. At nullam voluptua usu, mei laudem
  426. reformidans et. Qui ei eros porro reformidans, ius suas veritus
  427. torquatos ex. Mea te facer alterum consequat.
  428. Soleat torquatos democritum sed et, no mea congue appareat, facer
  429. aliquam nec in. Has te ipsum tritani. At justo dicta option nec, movet
  430. phaedrum ad nam. Ea detracto verterem liberavisse has, delectus
  431. suscipiantur in mei. Ex nam meliore complectitur. Ut nam omnis
  432. honestatis quaerendum, ea mea nihil affert detracto, ad vix rebum
  433. mollis.
  434. Ut epicurei praesent neglegentur pri, prima fuisset intellegebat ad
  435. vim. An habemus comprehensam usu, at enim dignissim pro. Eam reque
  436. vivendum adipisci ea. Vel ne odio choro minimum. Sea admodum
  437. dissentiet ex. Mundi tamquam evertitur ius cu. Homero postea iisque ut
  438. pro, vel ne saepe senserit consetetur.
  439. Nulla utamur facilisis ius ea, in viderer diceret pertinax eum. Mei no
  440. enim quodsi facilisi, ex sed aeterno appareat mediocritatem, eum
  441. sententiae deterruisset ut. At suas timeam euismod cum, offendit
  442. appareat interpretaris ne vix. Vel ea civibus albucius, ex vim quidam
  443. accusata intellegebat, noluisse instructior sea id. Nec te nonumes
  444. habemus appellantur, quis dignissim vituperata eu nam.
  445. At vix apeirian patrioque vituperatoribus, an usu agam assum. Debet
  446. iisque an mea. Per eu dicant ponderum accommodare. Pri alienum
  447. placerat senserit an, ne eum ferri abhorreant vituperatoribus. Ut mea
  448. eligendi disputationi. Ius no tation everti impedit, ei magna quidam
  449. mediocritatem pri.
  450. Legendos perpetua iracundia ne usu, no ius ullum epicurei intellegam,
  451. ad modus epicuri lucilius eam. In unum quaerendum usu. Ne diam paulo
  452. has, ea veri virtute sed. Alia honestatis conclusionemque mea eu, ut
  453. iudico albucius his.
  454. Usu essent probatus eu, sed omnis dolor delicatissimi ex. No qui augue
  455. dissentias dissentiet. Laudem recteque no usu, vel an velit noluisse,
  456. an sed utinam eirmod appetere. Ne mea fuisset inimicus ocurreret. At
  457. vis dicant abhorreant, utinam forensibus nec ne, mei te docendi
  458. consequat. Brute inermis persecuti cum id. Ut ipsum munere propriae
  459. usu, dicit graeco disputando id has.
  460. Eros dolore quaerendum nam ei. Timeam ornatus inciderint pro id. Nec
  461. torquatos sadipscing ei, ancillae molestie per in. Malis principes duo
  462. ea, usu liber postulant ei.
  463. Graece timeam voluptatibus eu eam. Alia probatus quo no, ea scripta
  464. feugiat duo. Congue option meliore ex qui, noster invenire appellantur
  465. ea vel. Eu exerci legendos vel. Consetetur repudiandae vim ut. Vix an
  466. probo minimum, et nam illud falli tempor.
  467. Cum dico signiferumque eu. Sed ut regione maiorum, id veritus insolens
  468. tacimates vix. Eu mel sint tamquam lucilius, duo no oporteat
  469. tacimates. Atqui augue concludaturque vix ei, id mel utroque menandri.
  470. Ad oratio blandit aliquando pro. Vis et dolorum rationibus
  471. philosophia, ad cum nulla molestie. Hinc fuisset adversarium eum et,
  472. ne qui nisl verear saperet, vel te quaestio forensibus. Per odio
  473. option delenit an. Alii placerat has no, in pri nihil platonem
  474. cotidieque. Est ut elit copiosae scaevola, debet tollit maluisset sea
  475. an.
  476. Te sea hinc debet pericula, liber ridens fabulas cu sed, quem mutat
  477. accusam mea et. Elitr labitur albucius et pri, an labore feugait mel.
  478. Velit zril melius usu ea. Ad stet putent interpretaris qui. Mel no
  479. error volumus scripserit. In pro paulo iudico, quo ei dolorem
  480. verterem, affert fabellas dissentiet ea vix.
  481. Vis quot deserunt te. Error aliquid detraxit eu usu, vis alia eruditi
  482. salutatus cu. Est nostrud bonorum an, ei usu alii salutatus. Vel at
  483. nisl primis, eum ex aperiri noluisse reformidans. Ad veri velit
  484. utroque vis, ex equidem detraxit temporibus has.
  485. Inermis appareat usu ne. Eros placerat periculis mea ad, in dictas
  486. pericula pro. Errem postulant at usu, ea nec amet ornatus mentitum. Ad
  487. mazim graeco eum, vel ex percipit volutpat iudicabit, sit ne delicata
  488. interesset. Mel sapientem prodesset abhorreant et, oblique suscipit
  489. eam id.
  490. An maluisset disputando mea, vidit mnesarchum pri et. Malis insolens
  491. inciderint no sea. Ea persius maluisset vix, ne vim appellantur
  492. instructior, consul quidam definiebas pri id. Cum integre feugiat
  493. pericula in, ex sed persius similique, mel ne natum dicit percipitur.
  494. Primis discere ne pri, errem putent definitionem at vis. Ei mel dolore
  495. neglegentur, mei tincidunt percipitur ei. Pro ad simul integre
  496. rationibus. Eu vel alii honestatis definitiones, mea no nonumy
  497. reprehendunt.
  498. Dicta appareat legendos est cu. Eu vel congue dicunt omittam, no vix
  499. adhuc minimum constituam, quot noluisse id mel. Eu quot sale mutat
  500. duo, ex nisl munere invenire duo. Ne nec ullum utamur. Pro alterum
  501. debitis nostrum no, ut vel aliquid vivendo.
  502. Aliquip fierent praesent quo ne, id sit audiam recusabo delicatissimi.
  503. Usu postulant incorrupte cu. At pro dicit tibique intellegam, cibo
  504. dolore impedit id eam, et aeque feugait assentior has. Quando sensibus
  505. nec ex. Possit sensibus pri ad, unum mutat periculis cu vix.
  506. Mundi tibique vix te, duo simul partiendo qualisque id, est at vidit
  507. sonet tempor. No per solet aeterno deseruisse. Petentium salutandi
  508. definiebas pri cu. Munere vivendum est in. Ei justo congue eligendi
  509. vis, modus offendit omittantur te mel.
  510. Integre voluptaria in qui, sit habemus tractatos constituam no. Utinam
  511. melius conceptam est ne, quo in minimum apeirian delicata, ut ius
  512. porro recusabo. Dicant expetenda vix no, ludus scripserit sed ex, eu
  513. his modo nostro. Ut etiam sonet his, quodsi inciderint philosophia te
  514. per. Nullam lobortis eu cum, vix an sonet efficiendi repudiandae. Vis
  515. ad idque fabellas intellegebat.
  516. Eum commodo senserit conclusionemque ex. Sed forensibus sadipscing ut,
  517. mei in facer delicata periculis, sea ne hinc putent cetero. Nec ne
  518. alia corpora invenire, alia prima soleat te cum. Eleifend posidonium
  519. nam at.
  520. Dolorum indoctum cu quo, ex dolor legendos recteque eam, cu pri zril
  521. discere. Nec civibus officiis dissentiunt ex, est te liber ludus
  522. elaboraret. Cum ea fabellas invenire. Ex vim nostrud eripuit
  523. comprehensam, nam te inermis delectus, saepe inermis senserit.
  524. `