1# -*- coding: utf-8 2# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license 3 4# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 5# 6# Permission to use, copy, modify, and distribute this software and its 7# documentation for any purpose with or without fee is hereby granted, 8# provided that the above copyright notice and this permission notice 9# appear in all copies. 10# 11# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 12# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 14# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 17# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 19import unittest 20import binascii 21 22import dns.exception 23import dns.flags 24import dns.message 25import dns.name 26import dns.rdataclass 27import dns.rdatatype 28import dns.rrset 29import dns.tsig 30import dns.update 31import dns.rdtypes.ANY.OPT 32import dns.rdtypes.ANY.TSIG 33 34from tests.util import here 35 36query_text = """id 1234 37opcode QUERY 38rcode NOERROR 39flags RD 40edns 0 41eflags DO 42payload 4096 43;QUESTION 44wwww.dnspython.org. IN A 45;ANSWER 46;AUTHORITY 47;ADDITIONAL""" 48 49goodhex = b'04d201000001000000000001047777777709646e73707974686f6e' \ 50 b'036f726700000100010000291000000080000000' 51 52goodwire = binascii.unhexlify(goodhex) 53 54answer_text = """id 1234 55opcode QUERY 56rcode NOERROR 57flags QR AA RD 58;QUESTION 59dnspython.org. IN SOA 60;ANSWER 61dnspython.org. 3600 IN SOA woof.dnspython.org. hostmaster.dnspython.org. 2003052700 3600 1800 604800 3600 62;AUTHORITY 63dnspython.org. 3600 IN NS ns1.staff.nominum.org. 64dnspython.org. 3600 IN NS ns2.staff.nominum.org. 65dnspython.org. 3600 IN NS woof.play-bow.org. 66;ADDITIONAL 67woof.play-bow.org. 3600 IN A 204.152.186.150 68""" 69 70goodhex2 = '04d2 8500 0001 0001 0003 0001' \ 71 '09646e73707974686f6e036f726700 0006 0001' \ 72 'c00c 0006 0001 00000e10 0028 ' \ 73 '04776f6f66c00c 0a686f73746d6173746572c00c' \ 74 '7764289c 00000e10 00000708 00093a80 00000e10' \ 75 'c00c 0002 0001 00000e10 0014' \ 76 '036e7331057374616666076e6f6d696e756dc016' \ 77 'c00c 0002 0001 00000e10 0006 036e7332c063' \ 78 'c00c 0002 0001 00000e10 0010 04776f6f6608706c61792d626f77c016' \ 79 'c091 0001 0001 00000e10 0004 cc98ba96' 80 81 82goodwire2 = binascii.unhexlify(goodhex2.replace(' ', '').encode()) 83 84query_text_2 = """id 1234 85opcode QUERY 86rcode 4095 87flags RD 88edns 0 89eflags DO 90payload 4096 91;QUESTION 92wwww.dnspython.org. IN A 93;ANSWER 94;AUTHORITY 95;ADDITIONAL""" 96 97goodhex3 = b'04d2010f0001000000000001047777777709646e73707974686f6e' \ 98 b'036f726700000100010000291000ff0080000000' 99 100goodwire3 = binascii.unhexlify(goodhex3) 101 102idna_text = """id 1234 103opcode QUERY 104rcode NOERROR 105flags QR AA RD 106;QUESTION 107Königsgäßchen. IN NS 108;ANSWER 109Königsgäßchen. 3600 IN NS Königsgäßchen. 110""" 111 112class MessageTestCase(unittest.TestCase): 113 114 def test_class(self): 115 m = dns.message.from_text(query_text) 116 self.assertTrue(isinstance(m, dns.message.QueryMessage)) 117 118 def test_comparison_eq1(self): 119 q1 = dns.message.from_text(query_text) 120 q2 = dns.message.from_text(query_text) 121 self.assertEqual(q1, q2) 122 123 def test_comparison_ne1(self): 124 q1 = dns.message.from_text(query_text) 125 q2 = dns.message.from_text(query_text) 126 q2.id = 10 127 self.assertNotEqual(q1, q2) 128 129 def test_comparison_ne2(self): 130 q1 = dns.message.from_text(query_text) 131 q2 = dns.message.from_text(query_text) 132 q2.question = [] 133 self.assertNotEqual(q1, q2) 134 135 def test_comparison_ne3(self): 136 q1 = dns.message.from_text(query_text) 137 self.assertNotEqual(q1, 1) 138 139 def test_EDNS_to_wire1(self): 140 q = dns.message.from_text(query_text) 141 w = q.to_wire() 142 self.assertEqual(w, goodwire) 143 144 def test_EDNS_from_wire1(self): 145 m = dns.message.from_wire(goodwire) 146 self.assertEqual(str(m), query_text) 147 148 def test_EDNS_to_wire2(self): 149 q = dns.message.from_text(query_text_2) 150 w = q.to_wire() 151 self.assertEqual(w, goodwire3) 152 153 def test_EDNS_from_wire2(self): 154 m = dns.message.from_wire(goodwire3) 155 self.assertEqual(str(m), query_text_2) 156 157 def test_EDNS_options_wire(self): 158 m = dns.message.make_query('foo', 'A') 159 opt = dns.edns.GenericOption(3, b'data') 160 m.use_edns(options=[opt]) 161 m2 = dns.message.from_wire(m.to_wire()) 162 self.assertEqual(m2.edns, 0) 163 self.assertEqual(len(m2.options), 1) 164 self.assertEqual(m2.options[0], opt) 165 166 def test_TooBig(self): 167 def bad(): 168 q = dns.message.from_text(query_text) 169 for i in range(0, 25): 170 rrset = dns.rrset.from_text('foo%d.' % i, 3600, 171 dns.rdataclass.IN, 172 dns.rdatatype.A, 173 '10.0.0.%d' % i) 174 q.additional.append(rrset) 175 q.to_wire(max_size=512) 176 self.assertRaises(dns.exception.TooBig, bad) 177 178 def test_answer1(self): 179 a = dns.message.from_text(answer_text) 180 wire = a.to_wire(want_shuffle=False) 181 self.assertEqual(wire, goodwire2) 182 183 def test_TrailingJunk(self): 184 def bad(): 185 badwire = goodwire + b'\x00' 186 dns.message.from_wire(badwire) 187 self.assertRaises(dns.message.TrailingJunk, bad) 188 189 def test_ShortHeader(self): 190 def bad(): 191 badwire = b'\x00' * 11 192 dns.message.from_wire(badwire) 193 self.assertRaises(dns.message.ShortHeader, bad) 194 195 def test_RespondingToResponse(self): 196 def bad(): 197 q = dns.message.make_query('foo', 'A') 198 r1 = dns.message.make_response(q) 199 dns.message.make_response(r1) 200 self.assertRaises(dns.exception.FormError, bad) 201 202 def test_RespondingToEDNSRequestAndSettingRA(self): 203 q = dns.message.make_query('foo', 'A', use_edns=0) 204 r = dns.message.make_response(q, True) 205 self.assertTrue(r.flags & dns.flags.RA != 0) 206 self.assertEqual(r.edns, 0) 207 208 def test_ExtendedRcodeSetting(self): 209 m = dns.message.make_query('foo', 'A') 210 m.set_rcode(4095) 211 self.assertEqual(m.rcode(), 4095) 212 self.assertEqual(m.edns, 0) 213 m.set_rcode(2) 214 self.assertEqual(m.rcode(), 2) 215 216 def test_EDNSVersionCoherence(self): 217 m = dns.message.make_query('foo', 'A') 218 m.use_edns(1) 219 self.assertEqual((m.ednsflags >> 16) & 0xFF, 1) 220 221 def test_SettingNoEDNSOptionsImpliesNoEDNS(self): 222 m = dns.message.make_query('foo', 'A') 223 self.assertEqual(m.edns, -1) 224 225 def test_SettingEDNSFlagsImpliesEDNS(self): 226 m = dns.message.make_query('foo', 'A', ednsflags=dns.flags.DO) 227 self.assertEqual(m.edns, 0) 228 229 def test_SettingEDNSPayloadImpliesEDNS(self): 230 m = dns.message.make_query('foo', 'A', payload=4096) 231 self.assertEqual(m.edns, 0) 232 233 def test_SettingEDNSRequestPayloadImpliesEDNS(self): 234 m = dns.message.make_query('foo', 'A', request_payload=4096) 235 self.assertEqual(m.edns, 0) 236 237 def test_SettingOptionsImpliesEDNS(self): 238 m = dns.message.make_query('foo', 'A', options=[]) 239 self.assertEqual(m.edns, 0) 240 241 def test_FindRRset(self): 242 a = dns.message.from_text(answer_text) 243 n = dns.name.from_text('dnspython.org.') 244 rrs1 = a.find_rrset(a.answer, n, dns.rdataclass.IN, dns.rdatatype.SOA) 245 rrs2 = a.find_rrset(dns.message.ANSWER, n, dns.rdataclass.IN, 246 dns.rdatatype.SOA) 247 self.assertEqual(rrs1, rrs2) 248 249 def test_FindRRsetUnindexed(self): 250 a = dns.message.from_text(answer_text) 251 a.index = None 252 n = dns.name.from_text('dnspython.org.') 253 rrs1 = a.find_rrset(a.answer, n, dns.rdataclass.IN, dns.rdatatype.SOA) 254 rrs2 = a.find_rrset(dns.message.ANSWER, n, dns.rdataclass.IN, 255 dns.rdatatype.SOA) 256 self.assertEqual(rrs1, rrs2) 257 258 def test_GetRRset(self): 259 a = dns.message.from_text(answer_text) 260 a.index = None 261 n = dns.name.from_text('dnspython.org.') 262 rrs1 = a.get_rrset(a.answer, n, dns.rdataclass.IN, dns.rdatatype.SOA) 263 rrs2 = a.get_rrset(dns.message.ANSWER, n, dns.rdataclass.IN, 264 dns.rdatatype.SOA) 265 self.assertEqual(rrs1, rrs2) 266 267 def test_GetNonexistentRRset(self): 268 a = dns.message.from_text(answer_text) 269 a.index = None 270 n = dns.name.from_text('dnspython.org.') 271 rrs1 = a.get_rrset(a.answer, n, dns.rdataclass.IN, dns.rdatatype.TXT) 272 rrs2 = a.get_rrset(dns.message.ANSWER, n, dns.rdataclass.IN, 273 dns.rdatatype.TXT) 274 self.assertTrue(rrs1 is None) 275 self.assertEqual(rrs1, rrs2) 276 277 def test_CleanTruncated(self): 278 def bad(): 279 a = dns.message.from_text(answer_text) 280 a.flags |= dns.flags.TC 281 wire = a.to_wire(want_shuffle=False) 282 dns.message.from_wire(wire, raise_on_truncation=True) 283 self.assertRaises(dns.message.Truncated, bad) 284 285 def test_MessyTruncated(self): 286 def bad(): 287 a = dns.message.from_text(answer_text) 288 a.flags |= dns.flags.TC 289 wire = a.to_wire(want_shuffle=False) 290 dns.message.from_wire(wire[:-3], raise_on_truncation=True) 291 self.assertRaises(dns.message.Truncated, bad) 292 293 def test_IDNA_2003(self): 294 a = dns.message.from_text(idna_text, idna_codec=dns.name.IDNA_2003) 295 rrs = dns.rrset.from_text_list('xn--knigsgsschen-lcb0w.', 30, 296 'in', 'ns', 297 ['xn--knigsgsschen-lcb0w.'], 298 idna_codec=dns.name.IDNA_2003) 299 self.assertEqual(a.answer[0], rrs) 300 301 @unittest.skipUnless(dns.name.have_idna_2008, 302 'Python idna cannot be imported; no IDNA2008') 303 def test_IDNA_2008(self): 304 a = dns.message.from_text(idna_text, idna_codec=dns.name.IDNA_2008) 305 rrs = dns.rrset.from_text_list('xn--knigsgchen-b4a3dun.', 30, 306 'in', 'ns', 307 ['xn--knigsgchen-b4a3dun.'], 308 idna_codec=dns.name.IDNA_2008) 309 self.assertEqual(a.answer[0], rrs) 310 311 def test_bad_section_number(self): 312 m = dns.message.make_query('foo', 'A') 313 self.assertRaises(ValueError, 314 lambda: m.section_number(123)) 315 316 def test_section_from_number(self): 317 m = dns.message.make_query('foo', 'A') 318 self.assertEqual(m.section_from_number(dns.message.QUESTION), 319 m.question) 320 self.assertEqual(m.section_from_number(dns.message.ANSWER), 321 m.answer) 322 self.assertEqual(m.section_from_number(dns.message.AUTHORITY), 323 m.authority) 324 self.assertEqual(m.section_from_number(dns.message.ADDITIONAL), 325 m.additional) 326 self.assertRaises(ValueError, 327 lambda: m.section_from_number(999)) 328 329 def test_wanting_EDNS_true_is_EDNS0(self): 330 m = dns.message.make_query('foo', 'A') 331 self.assertEqual(m.edns, -1) 332 m.use_edns(True) 333 self.assertEqual(m.edns, 0) 334 335 def test_wanting_DNSSEC_turns_on_EDNS(self): 336 m = dns.message.make_query('foo', 'A') 337 self.assertEqual(m.edns, -1) 338 m.want_dnssec() 339 self.assertEqual(m.edns, 0) 340 self.assertTrue(m.ednsflags & dns.flags.DO) 341 342 def test_EDNS_default_payload_is_1232(self): 343 m = dns.message.make_query('foo', 'A') 344 m.use_edns() 345 self.assertEqual(m.payload, dns.message.DEFAULT_EDNS_PAYLOAD) 346 347 def test_from_file(self): 348 m = dns.message.from_file(here('query')) 349 expected = dns.message.from_text(query_text) 350 self.assertEqual(m, expected) 351 352 def test_explicit_header_comment(self): 353 m = dns.message.from_text(';HEADER\n' + query_text) 354 expected = dns.message.from_text(query_text) 355 self.assertEqual(m, expected) 356 357 def test_repr(self): 358 q = dns.message.from_text(query_text) 359 self.assertEqual(repr(q), '<DNS message, ID 1234>') 360 361 def test_non_question_setters(self): 362 rrset = dns.rrset.from_text('foo', 300, 'in', 'a', '10.0.0.1') 363 q = dns.message.QueryMessage(id=1) 364 q.answer = [rrset] 365 self.assertEqual(q.sections[1], [rrset]) 366 self.assertEqual(q.sections[2], []) 367 self.assertEqual(q.sections[3], []) 368 q.authority = [rrset] 369 self.assertEqual(q.sections[2], [rrset]) 370 self.assertEqual(q.sections[3], []) 371 q.additional = [rrset] 372 self.assertEqual(q.sections[3], [rrset]) 373 374 def test_is_a_response_empty_question(self): 375 q = dns.message.make_query('www.dnspython.org.', 'a') 376 r = dns.message.make_response(q) 377 r.question = [] 378 r.set_rcode(dns.rcode.FORMERR) 379 self.assertTrue(q.is_response(r)) 380 381 def test_not_a_response(self): 382 q = dns.message.QueryMessage(id=1) 383 self.assertFalse(q.is_response(q)) 384 r = dns.message.QueryMessage(id=2) 385 r.flags = dns.flags.QR 386 self.assertFalse(q.is_response(r)) 387 r = dns.update.UpdateMessage(id=1) 388 self.assertFalse(q.is_response(r)) 389 q1 = dns.message.make_query('www.dnspython.org.', 'a') 390 q2 = dns.message.make_query('www.google.com.', 'a') 391 # Give them the same id, as we want to test if responses for 392 # differing questions are rejected. 393 q1.id = 1 394 q2.id = 1 395 r = dns.message.make_response(q2) 396 self.assertFalse(q1.is_response(r)) 397 # Now set rcode to FORMERR and check again. It should still 398 # not be a response as we check the question section for FORMERR 399 # if it is present. 400 r.set_rcode(dns.rcode.FORMERR) 401 self.assertFalse(q1.is_response(r)) 402 # Test the other case of differing questions, where there is 403 # something in the response's question section that is not in 404 # the question's. We have to do multiple questions to test 405 # this :) 406 r = dns.message.make_query('www.dnspython.org.', 'a') 407 r.flags |= dns.flags.QR 408 r.id = 1 409 r.find_rrset(r.question, dns.name.from_text('example'), 410 dns.rdataclass.IN, dns.rdatatype.A, create=True, 411 force_unique=True) 412 self.assertFalse(q1.is_response(r)) 413 414 def test_more_not_equal_cases(self): 415 q1 = dns.message.make_query('www.dnspython.org.', 'a') 416 q2 = dns.message.make_query('www.dnspython.org.', 'a') 417 # ensure ids are same 418 q1.id = 1 419 q2.id = 1 420 # and flags are different 421 q2.flags |= dns.flags.QR 422 self.assertFalse(q1 == q2) 423 q2.flags = q1.flags 424 q2.find_rrset(q2.question, dns.name.from_text('example'), 425 dns.rdataclass.IN, dns.rdatatype.A, create=True, 426 force_unique=True) 427 self.assertFalse(q1 == q2) 428 429 def test_edns_properties(self): 430 q = dns.message.make_query('www.dnspython.org.', 'a') 431 self.assertEqual(q.edns, -1) 432 self.assertEqual(q.payload, 0) 433 self.assertEqual(q.options, ()) 434 q = dns.message.make_query('www.dnspython.org.', 'a', use_edns=0, 435 payload=4096) 436 self.assertEqual(q.edns, 0) 437 self.assertEqual(q.payload, 4096) 438 self.assertEqual(q.options, ()) 439 440 def test_generic_message_class(self): 441 q1 = dns.message.Message(id=1) 442 q1.set_opcode(dns.opcode.NOTIFY) 443 q1.flags |= dns.flags.AA 444 q1.find_rrset(q1.question, dns.name.from_text('example'), 445 dns.rdataclass.IN, dns.rdatatype.SOA, create=True, 446 force_unique=True) 447 w = q1.to_wire() 448 q2 = dns.message.from_wire(w) 449 self.assertTrue(isinstance(q2, dns.message.Message)) 450 self.assertFalse(isinstance(q2, dns.message.QueryMessage)) 451 self.assertFalse(isinstance(q2, dns.update.UpdateMessage)) 452 self.assertEqual(q1, q2) 453 454 def test_truncated_exception_message(self): 455 q = dns.message.Message(id=1) 456 q.flags |= dns.flags.TC 457 te = dns.message.Truncated(message=q) 458 self.assertEqual(te.message(), q) 459 460 def test_bad_opt(self): 461 # Not in addtional 462 q = dns.message.Message(id=1) 463 opt = dns.rdtypes.ANY.OPT.OPT(1200, dns.rdatatype.OPT, ()) 464 rrs = dns.rrset.from_rdata(dns.name.root, 0, opt) 465 q.answer.append(rrs) 466 wire = q.to_wire() 467 with self.assertRaises(dns.message.BadEDNS): 468 dns.message.from_wire(wire) 469 # Owner name not root name 470 q = dns.message.Message(id=1) 471 rrs = dns.rrset.from_rdata('foo.', 0, opt) 472 q.additional.append(rrs) 473 wire = q.to_wire() 474 with self.assertRaises(dns.message.BadEDNS): 475 dns.message.from_wire(wire) 476 # Multiple opts 477 q = dns.message.Message(id=1) 478 rrs = dns.rrset.from_rdata(dns.name.root, 0, opt) 479 q.additional.append(rrs) 480 q.additional.append(rrs) 481 wire = q.to_wire() 482 with self.assertRaises(dns.message.BadEDNS): 483 dns.message.from_wire(wire) 484 485 def test_bad_tsig(self): 486 keyname = dns.name.from_text('key.') 487 # Not in addtional 488 q = dns.message.Message(id=1) 489 tsig = dns.rdtypes.ANY.TSIG.TSIG(dns.rdataclass.ANY, dns.rdatatype.TSIG, 490 dns.tsig.HMAC_SHA256, 0, 300, b'1234', 491 0, 0, b'') 492 rrs = dns.rrset.from_rdata(keyname, 0, tsig) 493 q.answer.append(rrs) 494 wire = q.to_wire() 495 with self.assertRaises(dns.message.BadTSIG): 496 dns.message.from_wire(wire) 497 # Multiple tsigs 498 q = dns.message.Message(id=1) 499 q.additional.append(rrs) 500 q.additional.append(rrs) 501 wire = q.to_wire() 502 with self.assertRaises(dns.message.BadTSIG): 503 dns.message.from_wire(wire) 504 # Class not ANY 505 tsig = dns.rdtypes.ANY.TSIG.TSIG(dns.rdataclass.IN, dns.rdatatype.TSIG, 506 dns.tsig.HMAC_SHA256, 0, 300, b'1234', 507 0, 0, b'') 508 rrs = dns.rrset.from_rdata(keyname, 0, tsig) 509 wire = q.to_wire() 510 with self.assertRaises(dns.message.BadTSIG): 511 dns.message.from_wire(wire) 512 513 def test_read_no_content_message(self): 514 m = dns.message.from_text(';comment') 515 self.assertIsInstance(m, dns.message.QueryMessage) 516 517 def test_eflags_turns_on_edns(self): 518 m = dns.message.from_text('eflags DO') 519 self.assertIsInstance(m, dns.message.QueryMessage) 520 self.assertEqual(m.edns, 0) 521 522 def test_payload_turns_on_edns(self): 523 m = dns.message.from_text('payload 1200') 524 self.assertIsInstance(m, dns.message.QueryMessage) 525 self.assertEqual(m.payload, 1200) 526 527 def test_bogus_header(self): 528 with self.assertRaises(dns.message.UnknownHeaderField): 529 dns.message.from_text('bogus foo') 530 531 def test_question_only(self): 532 m = dns.message.from_text(answer_text) 533 w = m.to_wire() 534 r = dns.message.from_wire(w, question_only=True) 535 self.assertEqual(r.id, m.id) 536 self.assertEqual(r.question[0], m.question[0]) 537 self.assertEqual(len(r.answer), 0) 538 self.assertEqual(len(r.authority), 0) 539 self.assertEqual(len(r.additional), 0) 540 541 def test_bad_resolve_chaining(self): 542 r = dns.message.make_query('www.dnspython.org.', 'a') 543 with self.assertRaises(dns.message.NotQueryResponse): 544 r.resolve_chaining() 545 r.flags |= dns.flags.QR 546 r.id = 1 547 r.find_rrset(r.question, dns.name.from_text('example'), 548 dns.rdataclass.IN, dns.rdatatype.A, create=True, 549 force_unique=True) 550 with self.assertRaises(dns.exception.FormError): 551 r.resolve_chaining() 552 553 def test_resolve_chaining_no_infinite_loop(self): 554 r = dns.message.from_text('''id 1 555flags QR 556;QUESTION 557www.example. IN CNAME 558;AUTHORITY 559example. 300 IN SOA . . 1 2 3 4 5 560''') 561 # passing is actuall not going into an infinite loop in this call 562 result = r.resolve_chaining() 563 self.assertEqual(result.canonical_name, 564 dns.name.from_text('www.example.')) 565 self.assertEqual(result.minimum_ttl, 5) 566 self.assertIsNone(result.answer) 567 568 def test_bad_text_questions(self): 569 with self.assertRaises(dns.exception.SyntaxError): 570 dns.message.from_text('''id 1 571;QUESTION 572example. 573''') 574 with self.assertRaises(dns.exception.SyntaxError): 575 dns.message.from_text('''id 1 576;QUESTION 577example. IN 578''') 579 with self.assertRaises(dns.rdatatype.UnknownRdatatype): 580 dns.message.from_text('''id 1 581;QUESTION 582example. INA 583''') 584 with self.assertRaises(dns.rdatatype.UnknownRdatatype): 585 dns.message.from_text('''id 1 586;QUESTION 587example. IN BOGUS 588''') 589 590 def test_bad_text_rrs(self): 591 with self.assertRaises(dns.exception.SyntaxError): 592 dns.message.from_text('''id 1 593flags QR 594;QUESTION 595example. IN A 596;ANSWER 597example. 598''') 599 with self.assertRaises(dns.exception.SyntaxError): 600 dns.message.from_text('''id 1 601flags QR 602;QUESTION 603example. IN A 604;ANSWER 605example. IN 606''') 607 with self.assertRaises(dns.exception.SyntaxError): 608 dns.message.from_text('''id 1 609flags QR 610;QUESTION 611example. IN A 612;ANSWER 613example. 300 614''') 615 with self.assertRaises(dns.rdatatype.UnknownRdatatype): 616 dns.message.from_text('''id 1 617flags QR 618;QUESTION 619example. IN A 620;ANSWER 621example. 30a IN A 622''') 623 with self.assertRaises(dns.rdatatype.UnknownRdatatype): 624 dns.message.from_text('''id 1 625flags QR 626;QUESTION 627example. IN A 628;ANSWER 629example. 300 INA A 630''') 631 with self.assertRaises(dns.exception.UnexpectedEnd): 632 dns.message.from_text('''id 1 633flags QR 634;QUESTION 635example. IN A 636;ANSWER 637example. 300 IN A 638''') 639 with self.assertRaises(dns.exception.SyntaxError): 640 dns.message.from_text('''id 1 641flags QR 642opcode UPDATE 643;ZONE 644example. IN SOA 645;UPDATE 646example. 300 IN A 647''') 648 with self.assertRaises(dns.exception.SyntaxError): 649 dns.message.from_text('''id 1 650flags QR 651opcode UPDATE 652;ZONE 653example. IN SOA 654;UPDATE 655example. 300 NONE A 656''') 657 with self.assertRaises(dns.exception.SyntaxError): 658 dns.message.from_text('''id 1 659flags QR 660opcode UPDATE 661;ZONE 662example. IN SOA 663;PREREQ 664example. 300 NONE A 10.0.0.1 665''') 666 with self.assertRaises(dns.exception.SyntaxError): 667 dns.message.from_text('''id 1 668flags QR 669;ANSWER 670 300 IN A 10.0.0.1 671''') 672 with self.assertRaises(dns.exception.SyntaxError): 673 dns.message.from_text('''id 1 674flags QR 675;QUESTION 676 IN SOA 677''') 678 679 def test_from_wire_makes_Flag(self): 680 m = dns.message.from_wire(goodwire) 681 self.assertIsInstance(m.flags, dns.flags.Flag) 682 self.assertEqual(m.flags, dns.flags.Flag.RD) 683 684 685if __name__ == '__main__': 686 unittest.main() 687