Codebase list dnspython / upstream/1.16.0+git20191031.0d018c3
Import upstream version 1.16.0+git20191031.0d018c3, md5 cb8672cb0f2d59a5715b3e10cf7c789d Debian Janitor 4 years ago
85 changed file(s) with 1431 addition(s) and 1813 deletion(s). Raw diff Collapse all Expand all
99 .tox
1010 dnspython.egg-info/
1111 .eggs/
12 .mypy_cache/
00 language: python
11 python:
2 - "2.7"
3 - "3.4"
42 - "3.5"
53 - "3.6"
4 - "3.7"
5 - "3.8"
66 #- "nightly"
77 matrix:
88 include:
1717 install:
1818 - pip install typing pylint pycryptodome ecdsa idna
1919 script:
20 - make typecheck
21 - make lint
2220 - make test
1717 # $Id: Makefile,v 1.16 2004/03/19 00:17:27 halley Exp $
1818
1919 PYTHON=python
20 PYTHON3=python3
20 PIP=pip
21 # set this to "--user" if you prefer
22 PIPMODE=
2123
2224 all:
2325 ${PYTHON} ./setup.py build
5153 rm -rf html.tar.gz html.zip html
5254
5355 kits:
54 ${PYTHON3} ./setup.py sdist --formats=gztar,zip bdist_wheel
56 ${PYTHON} ./setup.py sdist --formats=gztar,zip bdist_wheel
5557
5658 tags:
5759 find . -name '*.py' -print | etags -
5961 check: test
6062
6163 test:
62 cd tests; make PYTHON=${PYTHON} test
64 cd tests; make test
6365
64 test2:
65 cd tests; make PYTHON=python test
66
67 test3:
68 cd tests; make PYTHON=${PYTHON3} test
66 test3: test
6967
7068 lint:
7169 pylint dns tests examples/*.py
7270
73 lint3:
74 pylint3 dns tests examples/*.py
71 lint3: lint
7572
7673 typecheck:
77 if [ $(shell python -c "import sys; print(sys.version_info[0])") -ne 2 ]; then pip install mypy; mypy examples tests; else echo Skipping typecheck on Python 2; fi
74 ${PIP} show mypy >/dev/null 2>&1 || ${PIP} install ${PIPMODE} mypy
75 mypy examples tests
00 # dnspython
11
22 [![Build Status](https://travis-ci.org/rthalley/dnspython.svg?branch=master)](https://travis-ci.org/rthalley/dnspython)
3 [![PyPI version](https://badge.fury.io/py/dnspython.svg)](https://badge.fury.io/py/dnspython)
4 [![PyPI Statistics](https://img.shields.io/pypi/dm/dnspython.svg)](https://pypistats.org/packages/dnspython)
5
36
47 ## INTRODUCTION
58
3033
3134 ## ABOUT THIS RELEASE
3235
33 This is dnspython 1.16.0
36 This is the development verison of dnspython 2.0.0
3437
3538 ### Notices
3639
37 Python 2.x support ends with the release of 1.16.0, unless there are
38 critical bugs in 1.16.0. Future versions of dnspython will only
39 support Python 3.
40
41 Version numbering of future dnspython releases will also start at 2.0, as
42 incompatible changes will be permitted. We're not planning huge changes at
43 this time, but we'd like to do a better job at IDNA, and there are other
44 API improvements to be made.
40 Python 2.x support ended with the release of 1.16.0. dnspython 2.0.0 and
41 later only support Python 3.4 and later.
4542
4643 The ChangeLog has been discontinued. Please see the git history for detailed
4744 change information.
48
49 ### New since 1.15.0:
50
51 * Much of the internals of dns.query.udp() and dns.query.tcp() have
52 been factored out into dns.query.send_udp(),
53 dns.query.receive_udp(), dns.query.send_tcp(), and
54 dns.query.receive_tcp(). Applications which want more control over
55 the socket may find the new routines helpful; for example it would
56 be easy to send multiple queries over a single TCP connection.
57
58 * The OPENPGPKEY RR, and the CHAOS class A RR are now supported.
59
60 * EDNS0 client-subnet is supported.
61
62 * dns.resover.query() now has a lifetime timeout optional parameter.
63
64 * pycryptodome and pycryptodomex are now supported and recommended for use
65 instead of pycrypto.
66
67 * dns.message.from_wire() now has an ignore_trailing option.
68
69 * type signatures have been provided.
70
71 * module dns.hash is now deprecated, use standard Python libraries instead.
72
73 * setup.py supports Cythonization to improve performance.
74
75 ### Bugs fixed since 1.15.0:
76
77 * DNSSEC signature validation didn't check names correctly. [Issue #295]
78
79 * The NXDOMAIN exception should not use its docstring. [Issue #253]
80
81 * Fixed regression where trailing zeros in APL RRs were not
82 suppressed, and then fixed the problem where trailing zeros
83 were not added back properly on python 3 when needed.
84
85 * Masterfile TTL defaulting is now harmonized with BIND practice.
86
87 * dns.query.xfr() now raises on a non-zero rcode.
88
89 * Rdata module importing is now locked to avoid races.
90
91 * Several Python 3 incompatibilities have been fixed.
92
93 * NSEC3 bitmap parsing now works with mulitple NSEC3 windows.
94
95 * dns.renderer.Render supports TSIG on DNS envelope sequences.
96
97 * DNSSEC validation now checks names properly [Issue #295]
98
99 ### New since 1.14.0:
100
101 * IDNA 2008 support is now available if the "idna" module has been
102 installed and IDNA 2008 is requested. The default IDNA behavior is
103 still IDNA 2003. The new IDNA codec mechanism is currently only
104 useful for direct calls to dns.name.from_text() or
105 dns.name.from_unicode(), but in future releases it will be deployed
106 throughout dnspython, e.g. so that you can read a masterfile with an
107 IDNA 2008 codec in force.
108
109 * By default, dns.name.to_unicode() is not strict about which
110 version of IDNA the input complies with. Strictness can be
111 requested by using one of the strict IDNA codecs.
112
113 * The AVC RR is now supported.
114
115 ### Bugs fixed since 1.14.0:
116
117 * Some problems with newlines in various output modes have been
118 addressed.
119
120 * dns.name.to_text() now returns text and not bytes on Python 3.x
121
122 * Miscellaneous fixes for the Python 2/3 codeline merge.
123
124 * Many "lint" fixes after the addition of pylint support.
125
126 * The random number generator reseeds after a fork().
127
128
129 ## REQUIREMENTS
130
131 Python 2.7 or 3.4+.
132
133
134 ## HOME PAGE
135
136 For the latest in releases, documentation, and information, visit the dnspython
137 home page at http://www.dnspython.org/
138
139
140 ## BUG REPORTS
141
142 Bug reports may be opened at
143 https://github.com/rthalley/dnspython/issues or sent to
144 bugs@dnspython.org
145
146
147 ## MAILING LISTS
148
149 A number of mailing lists are available. Visit the dnspython home page to
150 subscribe or unsubscribe.
151
152
153 ## PRIOR RELEASE INFORMATION
154
155 ### New since 1.13.0:
156
157 * CSYNC RRs are now supported.
158
159 * `dns/message.py` (`make_query`): Setting any value which implies EDNS will
160 turn on EDNS if `use_edns` has not been specified.
161
162 ### Bugs fixed since 1.13.0:
163
164 * TSIG signature algorithm setting was broken by the Python 2 and Python 3 code
165 line merge.
166
167 * A bug in the LOC RR destroyed N/S and E/W distinctions within a degree of the
168 equator or prime merdian respectively.
169
170 * Misc. fixes to deal with fallout from the Python 2 & 3 merge.
171 Fixes #156, #157, #158, #159, #160.
172
173 * Running with python optimization on caused issues when stripped docstrings
174 were referenced. Fixes #154
175
176 * `dns.zone.from_text()` erroneously required the zone to be provided.
177 Fixes #153
178
179 ### New since 1.12.0:
180
181 * Dnspython now uses a single source for Python 2 and Python 3, eliminating the
182 painful merging between the Python 2 and Python 3 branches. Thank you so much
183 to Arthur Gautier for taking on this challenge and making it work! It was a
184 big job!
185
186 * Support for Python older than 2.6 dropped.
187
188 * Support for Python older than 3.3 dropped.
189
190 * Zone origin can be specified as a string.
191
192 * A rich string representation for all DNSExceptions.
193
194 * setuptools has replaced distutils
195
196 * Added support for CAA, CDS, CDNSKEY, EUI48, EUI64, and URI RR types.
197
198 * Names now support the pickle protocol.
199
200 * Ports can be specified per-nameserver in the stub resolver.
201
202 ### Bugs fixed since 1.12.0:
203
204 * A number of Unicode name bugs have been fixed.
205
206 * `resolv.conf` processing now rejects lines with too few tokens.
207
208 * NameDicts now keep the max-depth value correct, and update properly.
209
210 ### New since 1.11.1:
211
212 * Added `dns.zone.to_text()`.
213
214 * Added support for "options rotate" in `/etc/resolv.conf`.
215
216 * `dns.rdtypes.ANY.DNSKEY` now has helpers functions to convert between the
217 numeric form of the flags and a set of human-friendly strings
218
219 * The reverse name of an IPv6 mapped IPv4 address is now in the IPv4 reverse
220 namespace.
221
222 * The test system can now run the tests without requiring dnspython to be
223 installed.
224
225 * Preliminary Elliptic Curve DNSSEC Validation (requires ecdsa module)
226
227 ### Bugs fixed since 1.11.1:
228
229 * dnspython raised an exception when reading a masterfile starting with leading
230 whitespace
231
232 * dnspython was affected by a python slicing API bug present on 64-bit windows.
233
234 * Unicode escaping was applied at the wrong time.
235
236 * RRSIG `to_text()` did not respect the relativize setting.
237
238 * APL RRs with zero rdlength were rejected.
239
240 * The tokenizer could put back an unescaped token.
241
242 * Making a response to a message signed with TSIG was broken.
243
244 * The IXFR state machine didn't handle long IXFR diffs.
245
246 ### New since 1.11.0:
247
248 * Nothing
249
250 ### Bugs fixed since 1.11.0:
251
252 * `dns.resolver.Resolver` erroneously referred to `retry_servfail`
253 instead of `self.retry_servfail`.
254
255 * `dns.tsigkeyring.to_text()` would fail trying to convert the keyname to text.
256
257 * Multi-message TSIGs were broken for algorithms other than HMAC-MD5 because we
258 weren't passing the right digest module to the HMAC code.
259
260 * `dns.dnssec._find_candidate_keys()` tried to extract the key from the wrong
261 variable name.
262
263 * $GENERATE tests were not backward compatible with python 2.4.
264
265 ### New since 1.10.0:
266
267 * $GENERATE support
268
269 * TLSA RR support
270
271 * Added set_flags() method to dns.resolver.Resolver
272
273 ### Bugs fixed since 1.10.0:
274
275 * Names with offsets >= 2^14 are no longer added to the compression table.
276
277 * The "::" syntax is not used to shorten a single 16-bit section of the text
278 form an IPv6 address.
279
280 * Caches are now locked.
281
282 * YXDOMAIN is raised if seen by the resolver.
283
284 * Empty rdatasets are not printed.
285
286 * DNSKEY key tags are no longer assumed to be unique.
287
288 ### New since 1.9.4:
289
290 * Added dns.resolver.LRUCache. In this cache implementation, the cache size is
291 limited to a user-specified number of nodes, and when adding a new node to a
292 full cache the least-recently used node is removed. If you're crawling the web
293 or otherwise doing lots of resolutions and you are using a cache, switching
294 to the LRUCache is recommended.
295
296 * `dns.resolver.query()` will try TCP if a UDP response is truncated.
297
298 * The python socket module's DNS methods can be now be overridden with
299 implementations that use dnspython's resolver.
300
301 * Old DNSSEC types KEY, NXT, and SIG have been removed.
302
303 * Whitespace is allowed in SSHFP fingerprints.
304
305 * Origin checking in `dns.zone.from_xfr()` can be disabled.
306
307 * Trailing junk checking can be disabled.
308
309 * A source port can be specified when creating a resolver query.
310
311 * All EDNS values may now be specified to `dns.message.make_query()`.
312
313 ### Bugs fixed since 1.9.4:
314
315 * IPv4 and IPv6 address processing is now stricter.
316
317 * Bounds checking of slices in rdata wire processing is now more strict, and
318 bounds errors (e.g. we got less data than was expected) now raise
319 `dns.exception.FormError` rather than `IndexError`.
320
321 * Specifying a source port without specifying source used to have no effect, but
322 now uses the wildcard address and the specified port.
323
324 ### New since 1.9.3:
325
326 * Nothing.
327
328 ### Bugs fixed since 1.9.3:
329
330 * The rdata `_wire_cmp()` routine now handles relative names.
331
332 * The SIG RR implementation was missing `import struct`.
333
334 ### New since 1.9.2:
335
336 * A boolean parameter, `raise_on_no_answer`, has been added to the `query()`
337 methods. In no-error, no-data situations, this parameter determines whether
338 `NoAnswer` should be raised or not. If True, `NoAnswer` is raised. If False,
339 then an `Answer()` object with a None rrset will be returned.
340
341 * Resolver `Answer()` objects now have a canonical_name field.
342
343 * Rdata now has a `__hash__` method.
344
345 ### Bugs fixed since 1.9.2:
346
347 * Dnspython was erroneously doing case-insensitive comparisons of the names in
348 NSEC and RRSIG RRs.
349
350 * We now use `is` and not `==` when testing what section an RR is in.
351
352 * The resolver now disallows metaqueries.
353
354 ### New since 1.9.1:
355
356 * Nothing.
357
358 ### Bugs fixed since 1.9.1:
359
360 * The `dns.dnssec` module didn't work at all due to missing imports that escaped
361 detection in testing because the test suite also did the imports. The third
362 time is the charm!
363
364 ### New since 1.9.0:
365
366 * Nothing.
367
368 ### Bugs fixed since 1.9.0:
369
370 * The `dns.dnssec` module didn't work with DSA due to namespace contamination
371 from a "from"-style import.
372
373 ### New since 1.8.0:
374
375 * dnspython now uses `poll()` instead of `select()` when available.
376
377 * Basic DNSSEC validation can be done using `dns.dnsec.validate()` and
378 `dns.dnssec.validate_rrsig()` if you have PyCrypto 2.3 or later installed.
379 Complete secure resolution is not yet available.
380
381 * Added `key_id()` to the DNSSEC module, which computes the DNSSEC key id of a
382 DNSKEY rdata.
383
384 * Added `make_ds()` to the DNSSEC module, which returns the DS RR for a given
385 DNSKEY rdata.
386
387 * dnspython now raises an exception if HMAC-SHA284 or HMAC-SHA512 are used with
388 a Python older than 2.5.2. (Older Pythons do not compute the correct value.)
389
390 * Symbolic constants are now available for TSIG algorithm names.
391
392 ### Bugs fixed since 1.8.0
393
394 * `dns.resolver.zone_for_name()` didn't handle a query response with a CNAME or
395 DNAME correctly in some cases.
396
397 * When specifying rdata types and classes as text, Unicode strings may now be
398 used.
399
400 * Hashlib compatibility issues have been fixed.
401
402 * `dns.message` now imports `dns.edns`.
403
404 * The TSIG algorithm value was passed incorrectly to `use_tsig()` in some cases.
405
406 ### New since 1.7.1:
407
408 * Support for hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384 and hmac-sha512
409 has been contributed by Kevin Chen.
410
411 * The tokenizer's tokens are now Token objects instead of (type, value) tuples.
412
413 ### Bugs fixed since 1.7.1:
414
415 * Escapes in masterfiles now work correctly. Previously they were only working
416 correctly when the text involved was part of a domain name.
417
418 * When constructing a DDNS update, if the `present()` method was used with a
419 single rdata, a zero TTL was not added.
420
421 * The entropy pool needed locking to be thread safe.
422
423 * The entropy pool's reading of `/dev/random` could cause dnspython to block.
424
425 * The entropy pool did buffered reads, potentially consuming more randomness
426 than we needed.
427
428 * The entropy pool did not seed with high quality randomness on Windows.
429
430 * SRV records were compared incorrectly.
431
432 * In the e164 query function, the resolver parameter was not used.
433
434 ### New since 1.7.0:
435
436 * Nothing
437
438 ### Bugs fixed since 1.7.0:
439
440 * The 1.7.0 kitting process inadvertently omitted the code for the DLV RR.
441
442 * Negative DDNS prerequisites are now handled correctly.
443
444 ### New since 1.6.0:
445
446 * Rdatas now have a `to_digestable()` method, which returns the DNSSEC canonical
447 form of the rdata, suitable for use in signature computations.
448
449 * The NSEC3, NSEC3PARAM, DLV, and HIP RR types are now supported.
450
451 * An entropy module has been added and is used to randomize query ids.
452
453 * EDNS0 options are now supported.
454
455 * UDP IXFR is now supported.
456
457 * The wire format parser now has a `one_rr_per_rrset` mode, which suppresses the
458 usual coalescing of all RRs of a given type into a single RRset.
459
460 * Various helpful DNSSEC-related constants are now defined.
461
462 * The resolver's `query()` method now has an optional `source` parameter,
463 allowing the source IP address to be specified.
464
465 ### Bugs fixed since 1.6.0:
466
467 * On Windows, the resolver set the domain incorrectly.
468
469 * DS RR parsing only allowed one Base64 chunk.
470
471 * TSIG validation didn't always use absolute names.
472
473 * `NSEC.to_text()` only printed the last window.
474
475 * We did not canonicalize IPv6 addresses before comparing them; we
476 would thus treat equivalent but different textual forms, e.g.
477 "1:00::1" and "1::1" as being non-equivalent.
478
479 * If the peer set a TSIG error, we didn't raise an exception.
480
481 * Some EDNS bugs in the message code have been fixed (see the ChangeLog
482 for details).
483
484 ### New since 1.5.0:
485
486 * Added dns.inet.is_multicast().
487
488 ### Bugs fixed since 1.5.0:
489
490 * If `select()` raises an exception due to EINTR, we should just `select()`
491 again.
492
493 * If the queried address is a multicast address, then don't check that the
494 address of the response is the same as the address queried.
495
496 * NAPTR comparisons didn't compare the preference field due to a typo.
497
498 * Testing of whether a Windows NIC is enabled now works on Vista thanks to code
499 contributed by Paul Marks.
500
501 ### New since 1.4.0:
502
503 * Answer objects now support more of the python sequence protocol, forwarding
504 the requests to the answer rrset. E.g. `for a in answer` is equivalent to
505 `for a in answer.rrset`, `answer[i]` is equivalent to `answer.rrset[i]`, and
506 `answer[i:j]` is equivalent to `answer.rrset[i:j]`.
507
508 * Making requests using EDNS, including indicating DNSSEC awareness,
509 is now easier. For example, you can now say:
510 `q = dns.message.make_query('www.dnspython.org', 'MX', want_dnssec=True)`
511
512 * `dns.query.xfr()` can now be used for IXFR.
513
514 * Support has been added for the DHCID, IPSECKEY, and SPF RR types.
515
516 * UDP messages from unexpected sources can now be ignored by setting
517 `ignore_unexpected` to True when calling `dns.query.udp`.
518
519 ### Bugs fixed since 1.4.0:
520
521 * If `/etc/resolv.conf` didn't exist, we raised an exception instead of simply
522 using the default resolver configuration.
523
524 * In `dns.resolver.Resolver._config_win32_fromkey()`, we were passing the wrong
525 variable to `self._config_win32_search()`.
526
527 ### New since 1.3.5:
528
529 * You can now convert E.164 numbers to/from their ENUM name forms:
530 ```python
531 >>> import dns.e164
532 >>> n = dns.e164.from_e164("+1 555 1212")
533 >>> n
534 <DNS name 2.1.2.1.5.5.5.1.e164.arpa.>
535 >>> dns.e164.to_e164(n)
536 '+15551212'
537 ```
538
539 * You can now convert IPv4 and IPv6 address to/from their corresponding DNS
540 reverse map names:
541 ```python
542 >>> import dns.reversename
543 >>> n = dns.reversename.from_address("127.0.0.1")
544 >>> n
545 <DNS name 1.0.0.127.in-addr.arpa.>
546 >>> dns.reversename.to_address(n)
547 '127.0.0.1'
548 ```
549
550 * You can now convert between Unicode strings and their IDN ACE form:
551 ```python
552 >>> n = dns.name.from_text(u'les-\u00e9l\u00e8ves.example.')
553 >>> n
554 <DNS name xn--les-lves-50ai.example.>
555 >>> n.to_unicode()
556 u'les-\xe9l\xe8ves.example.'
557 ```
558
559 * The origin parameter to `dns.zone.from_text()` and `dns.zone.to_text()` is now
560 optional. If not specified, the origin will be taken from the first $ORIGIN
561 statement in the master file.
562
563 * Sanity checking of a zone can be disabled; this is useful when working with
564 files which are zone fragments.
565
566 ### Bugs fixed since 1.3.5:
567
568 * The correct delimiter was not used when retrieving the list of nameservers
569 from the registry in certain versions of windows.
570
571 * The floating-point version of latitude and longitude in LOC RRs
572 (`float_latitude` and `float_longitude`) had incorrect signs for south
573 latitudes and west longitudes.
574
575 * BIND 8 TTL syntax is now accepted in all TTL-like places (i.e. SOA fields
576 refresh, retry, expire, and minimum; SIG/RRSIG field original_ttl).
577
578 * TTLs are now bounds checked when their text form is parsed, and their values
579 must be in the closed interval `[0, 2^31 - 1]`.
580
581 ### New since 1.3.4:
582
583 * In the resolver, if time goes backward a little bit, ignore it.
584
585 * `zone_for_name()` has been added to the resolver module. It returns the zone
586 which is authoritative for the specified name, which is handy for dynamic
587 update. E.g.
588
589 import dns.resolver
590 print dns.resolver.zone_for_name('www.dnspython.org')
591
592 will output `"dnspython.org."` and
593 `print dns.resolver.zone_for_name('a.b.c.d.e.f.example.')`
594 will output `"."`.
595
596 * The default resolver can be fetched with the `get_default_resolver()` method.
597
598 * You can now get the parent (immediate superdomain) of a name by using the
599 `parent()` method.
600
601 * `Zone.iterate_rdatasets()` and `Zone.iterate_rdatas()` now have a default
602 rdtype of `dns.rdatatype.ANY` like the documentation says.
603
604 * A Dynamic DNS example, ddns.py, has been added.
605
606 ### New since 1.3.3:
607
608 * The source address and port may now be specified when calling
609 `dns.query.{udp,tcp,xfr}`.
610
611 * The resolver now does exponential backoff each time it runs through all of the
612 nameservers.
613
614 * Rcodes which indicate a nameserver is likely to be a "permanent failure" for a
615 query cause the nameserver to be removed from the mix for that query.
616
617 ### New since 1.3.2:
618
619 * `dns.message.Message.find_rrset()` now uses an index, vastly improving the
620 `from_wire()` performance of large messages such as zone transfers.
621
622 * Added `dns.message.make_response()`, which creates a skeletal response for the
623 specified query.
624
625 * Added `opcode()` and `set_opcode()` convenience methods to the
626 `dns.message.Message` class. Added the `request_payload` attribute to the
627 Message class.
628
629 * The `file` parameter of `dns.name.Name.to_wire()` is now optional; if omitted,
630 the wire form will be returned as the value of the function.
631
632 * `dns.zone.from_xfr()` in relativization mode incorrectly set `zone.origin` to
633 the empty name.
634
635 * The masterfile parser incorrectly rejected TXT records where a value was not
636 quoted.
637
638 ### New since 1.3.1:
639
640 * The NSEC format doesn't allow specifying types by number, so we shouldn't
641 either. (Using the unknown type format is still OK though.)
642
643 * The resolver wasn't catching `dns.exception.Timeout`, so a timeout erroneously
644 caused the whole resolution to fail instead of just going on to the next
645 server.
646
647 * The renderer module didn't import random, causing an exception to be raised if
648 a query id wasn't provided when a Renderer was created.
649
650 * The conversion of LOC milliseconds values from text to binary was incorrect if
651 the length of the milliseconds string was not 3.
652
653 ### New since 1.3.0:
654
655 * Added support for the SSHFP type.
656
657 ### New since 1.2.0:
658
659 * Added support for new DNSSEC types RRSIG, NSEC, and DNSKEY.
660
661 * This release fixes all known bugs.
662
663 * See the ChangeLog file for more detailed information on changes since the
664 prior release.
0 # Incompatible differences between dnspython 1.x and 2.x
1
2 ## Rounding
3
4 dnspython 2.0 rounds in the standard python 3 fashion; dnspython 1.x rounded
5 in the python 2 style on both python 2 and 3.
6
7 # Removed hash module
8
9 dns.hash module was removed. Use Python built in hashlib instead.
2323 'entropy',
2424 'exception',
2525 'flags',
26 'hash',
2726 'inet',
2827 'ipv4',
2928 'ipv6',
5352 'wiredata',
5453 'zone',
5554 ]
55
56 from dns.version import version as __version__
+0
-59
dns/_compat.py less more
0 import sys
1 import decimal
2 from decimal import Context
3
4 PY3 = sys.version_info[0] == 3
5 PY2 = sys.version_info[0] == 2
6
7
8 if PY3:
9 long = int
10 xrange = range
11 else:
12 long = long # pylint: disable=long-builtin
13 xrange = xrange # pylint: disable=xrange-builtin
14
15 # unicode / binary types
16 if PY3:
17 text_type = str
18 binary_type = bytes
19 string_types = (str,)
20 unichr = chr
21 def maybe_decode(x):
22 return x.decode()
23 def maybe_encode(x):
24 return x.encode()
25 def maybe_chr(x):
26 return x
27 def maybe_ord(x):
28 return x
29 else:
30 text_type = unicode # pylint: disable=unicode-builtin, undefined-variable
31 binary_type = str
32 string_types = (
33 basestring, # pylint: disable=basestring-builtin, undefined-variable
34 )
35 unichr = unichr # pylint: disable=unichr-builtin
36 def maybe_decode(x):
37 return x
38 def maybe_encode(x):
39 return x
40 def maybe_chr(x):
41 return chr(x)
42 def maybe_ord(x):
43 return ord(x)
44
45
46 def round_py2_compat(what):
47 """
48 Python 2 and Python 3 use different rounding strategies in round(). This
49 function ensures that results are python2/3 compatible and backward
50 compatible with previous py2 releases
51 :param what: float
52 :return: rounded long
53 """
54 d = Context(
55 prec=len(str(long(what))), # round to integer with max precision
56 rounding=decimal.ROUND_HALF_UP
57 ).create_decimal(str(what)) # str(): python 2.6 compat
58 return long(d)
1616
1717 """Common DNSSEC-related functions and constants."""
1818
19 import hashlib # used in make_ds() to avoid pycrypto dependency
1920 from io import BytesIO
2021 import struct
2122 import time
2728 import dns.rdata
2829 import dns.rdatatype
2930 import dns.rdataclass
30 from ._compat import string_types
3131
3232
3333 class UnsupportedAlgorithm(dns.exception.DNSException):
131131 """
132132
133133 rdata = _to_rdata(key, origin)
134 rdata = bytearray(rdata)
135134 if key.algorithm == RSAMD5:
136135 return (rdata[-3] << 8) + rdata[-2]
137136 else:
161160
162161 Returns a ``dns.rdtypes.ANY.DS``.
163162 """
164
165163 if algorithm.upper() == 'SHA1':
166164 dsalg = 1
167 hash = SHA1.new()
165 dshash = hashlib.sha1()
168166 elif algorithm.upper() == 'SHA256':
169167 dsalg = 2
170 hash = SHA256.new()
168 dshash = hashlib.sha256()
171169 else:
172170 raise UnsupportedAlgorithm('unsupported algorithm "%s"' % algorithm)
173171
174 if isinstance(name, string_types):
172 if isinstance(name, str):
175173 name = dns.name.from_text(name, origin)
176 hash.update(name.canonicalize().to_wire())
177 hash.update(_to_rdata(key, origin))
178 digest = hash.digest()
174 dshash.update(name.canonicalize().to_wire())
175 dshash.update(_to_rdata(key, origin))
176 digest = dshash.digest()
179177
180178 dsrdata = struct.pack("!HBB", key_id(key), key.algorithm, dsalg) + digest
181179 return dns.rdata.from_wire(dns.rdataclass.IN, dns.rdatatype.DS, dsrdata, 0,
291289 in seconds since the UNIX epoch. The default is the current time.
292290 """
293291
294 if isinstance(origin, string_types):
292 if isinstance(origin, str):
295293 origin = dns.name.from_text(origin, dns.name.root)
296294
297295 candidate_keys = _find_candidate_keys(keys, rrsig)
442440 in seconds since the UNIX epoch. The default is the current time.
443441 """
444442
445 if isinstance(origin, string_types):
443 if isinstance(origin, str):
446444 origin = dns.name.from_text(origin, dns.name.root)
447445
448446 if isinstance(rrset, tuple):
1919 import dns.exception
2020 import dns.name
2121 import dns.resolver
22 from ._compat import string_types, maybe_decode
2322
2423 #: The public E.164 domain.
2524 public_enum_domain = dns.name.from_text('e164.arpa.')
7473 text = b''.join(dlabels)
7574 if want_plus_prefix:
7675 text = b'+' + text
77 return maybe_decode(text)
76 return text.decode()
7877
7978
8079 def query(number, domains, resolver=None):
9493 resolver = dns.resolver.get_default_resolver()
9594 e_nx = dns.resolver.NXDOMAIN()
9695 for domain in domains:
97 if isinstance(domain, string_types):
96 if isinstance(domain, str):
9897 domain = dns.name.from_text(domain)
9998 qname = dns.e164.from_e164(number, domain)
10099 try:
153153 return 1
154154 return -1
155155
156 def __str__(self):
157 return self.to_text()
156158
157159 class ECSOption(Option):
158160 """EDNS Client Subnet (ECS, RFC7871)"""
194196 self.addrdata = addrdata[:nbytes]
195197 nbits = srclen % 8
196198 if nbits != 0:
197 last = struct.pack('B', ord(self.addrdata[-1:]) & (0xff << nbits))
199 last = struct.pack('B',
200 ord(self.addrdata[-1:]) & (0xff << (8 - nbits)))
198201 self.addrdata = self.addrdata[:-1] + last
199202
200203 def to_text(self):
201204 return "ECS {}/{} scope/{}".format(self.address, self.srclen,
202205 self.scopelen)
206 @staticmethod
207 def from_text(text):
208 """Convert a string into a `dns.edns.ECSOption`
209
210 :param text: string
211 :return: `dns.edns.ECSOption`
212
213 Examples:
214
215 >>> import dns.edns
216 >>>
217 >>> # basic example
218 >>> dns.edns.ECSOption.from_text('1.2.3.4/24')
219 >>>
220 >>> # also understands scope
221 >>> dns.edns.ECSOption.from_text('1.2.3.4/24/32')
222 >>>
223 >>> # IPv6
224 >>> dns.edns.ECSOption.from_text('2001:4b98::1/64/64')
225 >>>
226 >>> # it understands results from `dns.edns.ECSOption.to_text()`
227 >>> dns.edns.ECSOption.from_text('ECS 1.2.3.4/24/32')
228 """
229 optional_prefix = 'ECS'
230 tokens = text.split()
231 ecs_text = None
232 if len(tokens) == 1:
233 ecs_text = tokens[0]
234 elif len(tokens) == 2:
235 if tokens[0] != optional_prefix:
236 raise ValueError('could not parse ECS from "{}"'.format(text))
237 ecs_text = tokens[1]
238 else:
239 raise ValueError('could not parse ECS from "{}"'.format(text))
240 n_slashes = ecs_text.count('/')
241 if n_slashes == 1:
242 address, srclen = ecs_text.split('/')
243 scope = 0
244 elif n_slashes == 2:
245 address, srclen, scope = ecs_text.split('/')
246 else:
247 raise ValueError('could not parse ECS from "{}"'.format(text))
248 try:
249 scope = int(scope)
250 except ValueError:
251 raise ValueError('invalid scope "{}": scope must be an integer'.format(scope))
252 try:
253 srclen = int(srclen)
254 except ValueError:
255 raise ValueError('invalid srclen "{}": srclen must be an integer'.format(srclen))
256 return ECSOption(address, srclen, scope)
203257
204258 def to_wire(self, file):
205259 file.write(struct.pack('!H', self.family))
232286 return 1
233287 return -1
234288
289 def __str__(self):
290 return self.to_text()
291
235292 _type_to_class = {
236293 ECS: ECSOption
237294 }
1717 import os
1818 import random
1919 import time
20 from ._compat import long, binary_type
2120 try:
2221 import threading as _threading
2322 except ImportError:
9695 try:
9796 self._maybe_seed()
9897 if self.digest is None or self.next_byte == self.hash_len:
99 self.hash.update(binary_type(self.pool))
98 self.hash.update(bytes(self.pool))
10099 self.digest = bytearray(self.hash.digest())
101100 self.stir(self.digest, True)
102101 self.next_byte = 0
114113
115114 def random_between(self, first, last):
116115 size = last - first + 1
117 if size > long(4294967296):
116 if size > 4294967296:
118117 raise ValueError('too big')
119118 if size > 65536:
120119 rand = self.random_32
121 max = long(4294967295)
120 max = 4294967295
122121 elif size > 256:
123122 rand = self.random_16
124123 max = 65535
+0
-37
dns/hash.py less more
0 # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
1
2 # Copyright (C) 2011 Nominum, Inc.
3 #
4 # Permission to use, copy, modify, and distribute this software and its
5 # documentation for any purpose with or without fee is hereby granted,
6 # provided that the above copyright notice and this permission notice
7 # appear in all copies.
8 #
9 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
12 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
17 """Hashing backwards compatibility wrapper"""
18
19 import hashlib
20 import warnings
21
22 warnings.warn(
23 "dns.hash module will be removed in future versions. Please use hashlib instead.",
24 DeprecationWarning)
25
26 hashes = {}
27 hashes['MD5'] = hashlib.md5
28 hashes['SHA1'] = hashlib.sha1
29 hashes['SHA224'] = hashlib.sha224
30 hashes['SHA256'] = hashlib.sha256
31 hashes['SHA384'] = hashlib.sha384
32 hashes['SHA512'] = hashlib.sha512
33
34
35 def get(algorithm):
36 return hashes[algorithm.upper()]
2020
2121 import dns.ipv4
2222 import dns.ipv6
23
24 from ._compat import maybe_ord
2523
2624 # We assume that AF_INET is always defined.
2725
113111 """
114112
115113 try:
116 first = maybe_ord(dns.ipv4.inet_aton(text)[0])
114 first = dns.ipv4.inet_aton(text)[0]
117115 return first >= 224 and first <= 239
118116 except Exception:
119117 try:
120 first = maybe_ord(dns.ipv6.inet_aton(text)[0])
118 first = dns.ipv6.inet_aton(text)[0]
121119 return first == 255
122120 except Exception:
123121 raise ValueError
1919 import struct
2020
2121 import dns.exception
22 from ._compat import binary_type
2322
2423 def inet_ntoa(address):
2524 """Convert an IPv4 address in binary form to text form.
2625
27 *address*, a ``binary``, the IPv4 address in binary form.
26 *address*, a ``bytes``, the IPv4 address in binary form.
2827
29 Returns a ``text``.
28 Returns a ``str``.
3029 """
3130
3231 if len(address) != 4:
3332 raise dns.exception.SyntaxError
34 if not isinstance(address, bytearray):
35 address = bytearray(address)
3633 return ('%u.%u.%u.%u' % (address[0], address[1],
3734 address[2], address[3]))
3835
3936 def inet_aton(text):
4037 """Convert an IPv4 address in text form to binary form.
4138
42 *text*, a ``text``, the IPv4 address in textual form.
39 *text*, a ``str``, the IPv4 address in textual form.
4340
44 Returns a ``binary``.
41 Returns a ``bytes``.
4542 """
4643
47 if not isinstance(text, binary_type):
44 if not isinstance(text, bytes):
4845 text = text.encode()
4946 parts = text.split(b'.')
5047 if len(parts) != 4:
5653 # No leading zeros
5754 raise dns.exception.SyntaxError
5855 try:
59 bytes = [int(part) for part in parts]
60 return struct.pack('BBBB', *bytes)
56 b = [int(part) for part in parts]
57 return struct.pack('BBBB', *b)
6158 except:
6259 raise dns.exception.SyntaxError
2121
2222 import dns.exception
2323 import dns.ipv4
24 from ._compat import xrange, binary_type, maybe_decode
2524
2625 _leading_zero = re.compile(r'0+([0-9a-f]+)')
2726
2827 def inet_ntoa(address):
2928 """Convert an IPv6 address in binary form to text form.
3029
31 *address*, a ``binary``, the IPv6 address in binary form.
30 *address*, a ``bytes``, the IPv6 address in binary form.
3231
3332 Raises ``ValueError`` if the address isn't 16 bytes long.
34 Returns a ``text``.
33 Returns a ``str``.
3534 """
3635
3736 if len(address) != 16:
4140 i = 0
4241 l = len(hex)
4342 while i < l:
44 chunk = maybe_decode(hex[i : i + 4])
43 chunk = hex[i : i + 4].decode()
4544 # strip leading zeros. we do this with an re instead of
4645 # with lstrip() because lstrip() didn't support chars until
4746 # python 2.2.2
5756 best_len = 0
5857 start = -1
5958 last_was_zero = False
60 for i in xrange(8):
59 for i in range(8):
6160 if chunks[i] != '0':
6261 if last_was_zero:
6362 end = i
101100
102101 *text*, a ``text``, the IPv6 address in textual form.
103102
104 Returns a ``binary``.
103 Returns a ``bytes``.
105104 """
106105
107106 #
108107 # Our aim here is not something fast; we just want something that works.
109108 #
110 if not isinstance(text, binary_type):
109 if not isinstance(text, bytes):
111110 text = text.encode()
112111
113112 if text == b'::':
117116 #
118117 m = _v4_ending.match(text)
119118 if not m is None:
120 b = bytearray(dns.ipv4.inet_aton(m.group(2)))
119 b = dns.ipv4.inet_aton(m.group(2))
121120 text = (u"{}:{:02x}{:02x}:{:02x}{:02x}".format(m.group(1).decode(),
122121 b[0], b[1], b[2],
123122 b[3])).encode()
146145 if seen_empty:
147146 raise dns.exception.SyntaxError
148147 seen_empty = True
149 for i in xrange(0, 8 - l + 1):
148 for i in range(0, 8 - l + 1):
150149 canonical.append(b'0000')
151150 else:
152151 lc = len(c)
172171 def is_mapped(address):
173172 """Is the specified address a mapped IPv4 address?
174173
175 *address*, a ``binary`` is an IPv6 address in binary form.
174 *address*, a ``bytes`` is an IPv6 address in binary form.
176175
177176 Returns a ``bool``.
178177 """
3737 import dns.tsig
3838 import dns.wiredata
3939
40 from ._compat import long, xrange, string_types
41
4240
4341 class ShortHeader(dns.exception.FormError):
4442 """The DNS packet passed to from_wire() is too short."""
6563
6664 class UnknownTSIGKey(dns.exception.DNSException):
6765 """A TSIG with an unknown key was received."""
66
67
68 class Truncated(dns.exception.DNSException):
69 """The truncated flag is set."""
6870
6971
7072 #: The question section number
130132 """
131133
132134 s = StringIO()
133 s.write(u'id %d\n' % self.id)
134 s.write(u'opcode %s\n' %
135 s.write('id %d\n' % self.id)
136 s.write('opcode %s\n' %
135137 dns.opcode.to_text(dns.opcode.from_flags(self.flags)))
136138 rc = dns.rcode.from_flags(self.flags, self.ednsflags)
137 s.write(u'rcode %s\n' % dns.rcode.to_text(rc))
138 s.write(u'flags %s\n' % dns.flags.to_text(self.flags))
139 s.write('rcode %s\n' % dns.rcode.to_text(rc))
140 s.write('flags %s\n' % dns.flags.to_text(self.flags))
139141 if self.edns >= 0:
140 s.write(u'edns %s\n' % self.edns)
142 s.write('edns %s\n' % self.edns)
141143 if self.ednsflags != 0:
142 s.write(u'eflags %s\n' %
144 s.write('eflags %s\n' %
143145 dns.flags.edns_to_text(self.ednsflags))
144 s.write(u'payload %d\n' % self.payload)
146 s.write('payload %d\n' % self.payload)
145147 for opt in self.options:
146 s.write(u'option %s\n' % opt.to_text())
148 s.write('option %s\n' % opt.to_text())
147149 is_update = dns.opcode.is_update(self.flags)
148150 if is_update:
149 s.write(u';ZONE\n')
150 else:
151 s.write(u';QUESTION\n')
151 s.write(';ZONE\n')
152 else:
153 s.write(';QUESTION\n')
152154 for rrset in self.question:
153155 s.write(rrset.to_text(origin, relativize, **kw))
154 s.write(u'\n')
156 s.write('\n')
155157 if is_update:
156 s.write(u';PREREQ\n')
157 else:
158 s.write(u';ANSWER\n')
158 s.write(';PREREQ\n')
159 else:
160 s.write(';ANSWER\n')
159161 for rrset in self.answer:
160162 s.write(rrset.to_text(origin, relativize, **kw))
161 s.write(u'\n')
163 s.write('\n')
162164 if is_update:
163 s.write(u';UPDATE\n')
164 else:
165 s.write(u';AUTHORITY\n')
165 s.write(';UPDATE\n')
166 else:
167 s.write(';AUTHORITY\n')
166168 for rrset in self.authority:
167169 s.write(rrset.to_text(origin, relativize, **kw))
168 s.write(u'\n')
169 s.write(u';ADDITIONAL\n')
170 s.write('\n')
171 s.write(';ADDITIONAL\n')
170172 for rrset in self.additional:
171173 s.write(rrset.to_text(origin, relativize, **kw))
172 s.write(u'\n')
174 s.write('\n')
173175 #
174176 # We strip off the final \n so the caller can print the result without
175177 # doing weird things to get around eccentricities in Python print
471473 if keyname is None:
472474 self.keyname = list(self.keyring.keys())[0]
473475 else:
474 if isinstance(keyname, string_types):
476 if isinstance(keyname, str):
475477 keyname = dns.name.from_text(keyname)
476478 self.keyname = keyname
477479 self.keyalgorithm = algorithm
519521 options = []
520522 else:
521523 # make sure the EDNS version in ednsflags agrees with edns
522 ednsflags &= long(0xFF00FFFF)
524 ednsflags &= 0xFF00FFFF
523525 ednsflags |= (edns << 16)
524526 if options is None:
525527 options = []
560562 (value, evalue) = dns.rcode.to_flags(rcode)
561563 self.flags &= 0xFFF0
562564 self.flags |= value
563 self.ednsflags &= long(0x00FFFFFF)
565 self.ednsflags &= 0x00FFFFFF
564566 self.ednsflags |= evalue
565567 if self.ednsflags != 0 and self.edns < 0:
566568 self.edns = 0
616618 if self.updating and qcount > 1:
617619 raise dns.exception.FormError
618620
619 for i in xrange(0, qcount):
621 for i in range(0, qcount):
620622 (qname, used) = dns.name.from_wire(self.wire, self.current)
621623 if self.message.origin is not None:
622624 qname = qname.relativize(self.message.origin)
644646 else:
645647 force_unique = False
646648 seen_opt = False
647 for i in xrange(0, count):
649 for i in range(0, count):
648650 rr_start = self.current
649651 (name, used) = dns.name.from_wire(self.wire, self.current)
650652 absolute_name = name
740742 (self.message.id, self.message.flags, qcount, ancount,
741743 aucount, adcount) = struct.unpack('!HHHHHH', self.wire[:12])
742744 self.current = 12
745 self.message.original_id = self.message.id
743746 if dns.opcode.is_update(self.message.flags):
744747 self.updating = True
748 if self.message.flags & dns.flags.TC:
749 raise Truncated
745750 self._get_question(qcount)
746751 if self.question_only:
747752 return
804809
805810 Raises ``dns.message.BadTSIG`` if a TSIG record was not the last
806811 record of the additional data section.
812
813 Raises ``dns.message.Truncated`` if the TC flag is set.
807814
808815 Returns a ``dns.message.Message``.
809816 """
10401047 Returns a ``dns.message.Message object``
10411048 """
10421049
1043 str_type = string_types
1050 str_type = str
10441051 opts = 'rU'
10451052
10461053 if isinstance(f, str_type):
10981105 Returns a ``dns.message.Message``
10991106 """
11001107
1101 if isinstance(qname, string_types):
1108 if isinstance(qname, str):
11021109 qname = dns.name.from_text(qname)
1103 if isinstance(rdtype, string_types):
1110 if isinstance(rdtype, str):
11041111 rdtype = dns.rdatatype.from_text(rdtype)
1105 if isinstance(rdclass, string_types):
1112 if isinstance(rdclass, str):
11061113 rdclass = dns.rdataclass.from_text(rdclass)
11071114 m = Message()
11081115 m.flags |= dns.flags.RD
3131 import dns.exception
3232 import dns.wiredata
3333
34 from ._compat import long, binary_type, text_type, unichr, maybe_decode
35
3634 try:
3735 maxint = sys.maxint # pylint: disable=sys-max-int
3836 except AttributeError:
109107 def __init__(self):
110108 pass
111109
110 def is_idna(self, label):
111 return label.lower().startswith(b'xn--')
112
112113 def encode(self, label):
113114 raise NotImplementedError
114115
115116 def decode(self, label):
116 # We do not apply any IDNA policy on decode; we just
117 downcased = label.lower()
118 if downcased.startswith(b'xn--'):
117 # We do not apply any IDNA policy on decode.
118 if self.is_idna(label):
119119 try:
120 label = downcased[4:].decode('punycode')
120 label = label[4:].decode('punycode')
121121 except Exception as e:
122122 raise IDNAException(idna_exception=e)
123 else:
124 label = maybe_decode(label)
125 return _escapify(label, True)
123 return _escapify(label)
126124
127125
128126 class IDNA2003Codec(IDNACodec):
154152 if not self.strict_decode:
155153 return super(IDNA2003Codec, self).decode(label)
156154 if label == b'':
157 return u''
155 return ''
158156 try:
159 return _escapify(encodings.idna.ToUnicode(label), True)
157 return _escapify(encodings.idna.ToUnicode(label))
160158 except Exception as e:
161159 raise IDNAException(idna_exception=e)
162160
194192 self.allow_pure_ascii = allow_pure_ascii
195193 self.strict_decode = strict_decode
196194
197 def is_all_ascii(self, label):
198 for c in label:
199 if ord(c) > 0x7f:
200 return False
201 return True
202
203195 def encode(self, label):
204196 if label == '':
205197 return b''
206 if self.allow_pure_ascii and self.is_all_ascii(label):
198 if self.allow_pure_ascii and is_all_ascii(label):
207199 return label.encode('ascii')
208200 if not have_idna_2008:
209201 raise NoIDNA2008
218210 if not self.strict_decode:
219211 return super(IDNA2008Codec, self).decode(label)
220212 if label == b'':
221 return u''
213 return ''
222214 if not have_idna_2008:
223215 raise NoIDNA2008
224216 try:
225217 if self.uts_46:
226218 label = idna.uts46_remap(label, False, False)
227 return _escapify(idna.ulabel(label), True)
219 return _escapify(idna.ulabel(label))
228220 except idna.IDNAError as e:
229221 raise IDNAException(idna_exception=e)
230222
231 _escaped = bytearray(b'"().;\\@$')
223 _escaped = b'"().;\\@$'
224 _escaped_text = '"().;\\@$'
232225
233226 IDNA_2003_Practical = IDNA2003Codec(False)
234227 IDNA_2003_Strict = IDNA2003Codec(True)
239232 IDNA_2008_Transitional = IDNA2008Codec(True, True, False, False)
240233 IDNA_2008 = IDNA_2008_Practical
241234
242 def _escapify(label, unicode_mode=False):
235 def _escapify(label):
243236 """Escape the characters in label which need it.
244 @param unicode_mode: escapify only special and whitespace (<= 0x20)
245 characters
246237 @returns: the escaped string
247238 @rtype: string"""
248 if not unicode_mode:
239 if isinstance(label, bytes):
240 # Ordinary DNS label mode. Escape special characters and values
241 # < 0x20 or > 0x7f.
249242 text = ''
250 if isinstance(label, text_type):
243 if isinstance(label, str):
251244 label = label.encode()
252 for c in bytearray(label):
245 for c in label:
253246 if c in _escaped:
254247 text += '\\' + chr(c)
255248 elif c > 0x20 and c < 0x7F:
256249 text += chr(c)
257250 else:
258251 text += '\\%03d' % c
259 return text.encode()
260
261 text = u''
262 if isinstance(label, binary_type):
263 label = label.decode()
252 return text
253
254 # Unicode label mode. Escape only special characters and values < 0x20
255 text = ''
264256 for c in label:
265 if c > u'\x20' and c < u'\x7f':
257 if c in _escaped_text:
258 text += '\\' + c
259 elif c <= '\x20':
260 text += '\\%03d' % ord(c)
261 else:
266262 text += c
267 else:
268 if c >= u'\x7f':
269 text += c
270 else:
271 text += u'\\%03d' % ord(c)
272263 return text
273264
274265 def _validate_labels(labels):
307298
308299 """
309300
310 if isinstance(label, binary_type):
301 if isinstance(label, bytes):
311302 return label
312 if isinstance(label, text_type):
303 if isinstance(label, str):
313304 return label.encode()
314305 raise ValueError
315306
373364 Returns an ``int``.
374365 """
375366
376 h = long(0)
367 h = 0
377368 for label in self.labels:
378 for c in bytearray(label.lower()):
369 for c in label.lower():
379370 h += (h << 3) + c
380 return int(h % maxint)
371 return h % maxint
381372
382373 def fullcompare(self, other):
383374 """Compare two names, returning a 3-tuple
543534 """
544535
545536 if len(self.labels) == 0:
546 return maybe_decode(b'@')
537 return '@'
547538 if len(self.labels) == 1 and self.labels[0] == b'':
548 return maybe_decode(b'.')
539 return '.'
549540 if omit_final_dot and self.is_absolute():
550541 l = self.labels[:-1]
551542 else:
552543 l = self.labels
553 s = b'.'.join(map(_escapify, l))
554 return maybe_decode(s)
544 s = '.'.join(map(_escapify, l))
545 return s
555546
556547 def to_unicode(self, omit_final_dot=False, idna_codec=None):
557548 """Convert name to Unicode text format.
572563 """
573564
574565 if len(self.labels) == 0:
575 return u'@'
566 return '@'
576567 if len(self.labels) == 1 and self.labels[0] == b'':
577 return u'.'
568 return '.'
578569 if omit_final_dot and self.is_absolute():
579570 l = self.labels[:-1]
580571 else:
581572 l = self.labels
582573 if idna_codec is None:
583574 idna_codec = IDNA_2003_Practical
584 return u'.'.join([idna_codec.decode(x) for x in l])
575 return '.'.join([idna_codec.decode(x) for x in l])
585576
586577 def to_digestable(self, origin=None):
587578 """Convert name to a format suitable for digesting in hashes.
812803 Returns a ``dns.name.Name``.
813804 """
814805
815 if not isinstance(text, text_type):
806 if not isinstance(text, str):
816807 raise ValueError("input to from_unicode() must be a unicode string")
817808 if not (origin is None or isinstance(origin, Name)):
818809 raise ValueError("origin must be a Name or None")
819810 labels = []
820 label = u''
811 label = ''
821812 escaping = False
822813 edigits = 0
823814 total = 0
824815 if idna_codec is None:
825816 idna_codec = IDNA_2003
826 if text == u'@':
827 text = u''
817 if text == '@':
818 text = ''
828819 if text:
829 if text == u'.':
820 if text in ['.', '\u3002', '\uff0e', '\uff61']:
830821 return Name([b'']) # no Unicode "u" on this constant!
831822 for c in text:
832823 if escaping:
845836 edigits += 1
846837 if edigits == 3:
847838 escaping = False
848 label += unichr(total)
849 elif c in [u'.', u'\u3002', u'\uff0e', u'\uff61']:
839 label += chr(total)
840 elif c in ['.', '\u3002', '\uff0e', '\uff61']:
850841 if len(label) == 0:
851842 raise EmptyLabel
852843 labels.append(idna_codec.encode(label))
853 label = u''
854 elif c == u'\\':
844 label = ''
845 elif c == '\\':
855846 escaping = True
856847 edigits = 0
857848 total = 0
868859 labels.extend(list(origin.labels))
869860 return Name(labels)
870861
862 def is_all_ascii(text):
863 for c in text:
864 if ord(c) > 0x7f:
865 return False
866 return True
871867
872868 def from_text(text, origin=root, idna_codec=None):
873869 """Convert text into a Name object.
884880 Returns a ``dns.name.Name``.
885881 """
886882
887 if isinstance(text, text_type):
888 return from_unicode(text, origin, idna_codec)
889 if not isinstance(text, binary_type):
883 if isinstance(text, str):
884 if not is_all_ascii(text):
885 # Some codepoint in the input text is > 127, so IDNA applies.
886 return from_unicode(text, origin, idna_codec)
887 # The input is all ASCII, so treat this like an ordinary non-IDNA
888 # domain name. Note that "all ASCII" is about the input text,
889 # not the codepoints in the domain name. E.g. if text has value
890 #
891 # r'\150\151\152\153\154\155\156\157\158\159'
892 #
893 # then it's still "all ASCII" even though the domain name has
894 # codepoints > 127.
895 text = text.encode('ascii')
896 if not isinstance(text, bytes):
890897 raise ValueError("input to from_text() must be a string")
891898 if not (origin is None or isinstance(origin, Name)):
892899 raise ValueError("origin must be a Name or None")
900907 if text:
901908 if text == b'.':
902909 return Name([b''])
903 for c in bytearray(text):
910 for c in text:
904911 byte_ = struct.pack('!B', c)
905912 if escaping:
906913 if edigits == 0:
960967 which were consumed reading it.
961968 """
962969
963 if not isinstance(message, binary_type):
970 if not isinstance(message, bytes):
964971 raise ValueError("input to from_wire() must be a byte string")
965972 message = dns.wiredata.maybe_wrap(message)
966973 labels = []
2626
2727 """DNS name dictionary"""
2828
29 import collections
29 try:
30 from collections.abc import MutableMapping
31 except ImportError:
32 from collections import MutableMapping
3033 import dns.name
31 from ._compat import xrange
3234
3335
34 class NameDict(collections.MutableMapping):
36 class NameDict(MutableMapping):
3537 """A dictionary whose keys are dns.name.Name objects.
3638
3739 In addition to being like a regular Python dictionary, this
99101 depth = len(name)
100102 if depth > self.max_depth:
101103 depth = self.max_depth
102 for i in xrange(-depth, 0):
104 for i in range(-depth, 0):
103105 n = dns.name.Name(name[i:])
104106 if n in self:
105107 return (n, self[n])
4848 for rds in self.rdatasets:
4949 if len(rds) > 0:
5050 s.write(rds.to_text(name, **kw))
51 s.write(u'\n')
51 s.write('\n')
5252 return s.getvalue()[:-1]
5353
5454 def __repr__(self):
1919 from __future__ import generators
2020
2121 import errno
22 import os
2223 import select
2324 import socket
2425 import struct
3233 import dns.rcode
3334 import dns.rdataclass
3435 import dns.rdatatype
35 from ._compat import long, string_types, PY3
36
37 if PY3:
38 select_error = OSError
39 else:
40 select_error = select.error
36
37 try:
38 import ssl
39 except ImportError:
40 class ssl(object):
41 class WantReadException(Exception):
42 pass
43 class WantWriteException(Exception):
44 pass
45 class SSLSocket(object):
46 pass
47 def create_default_context(self, *args, **kwargs):
48 raise Exception('no ssl support')
4149
4250 # Function used to create a socket. Can be overridden if needed in special
4351 # situations.
8694 pollable.register(fd, event_mask)
8795
8896 if timeout:
89 event_list = pollable.poll(long(timeout * 1000))
97 event_list = pollable.poll(timeout * 1000)
9098 else:
9199 event_list = pollable.poll()
92100
127135 if timeout <= 0.0:
128136 raise dns.exception.Timeout
129137 try:
138 if isinstance(fd, ssl.SSLSocket) and readable and fd.pending() > 0:
139 return True
130140 if not _polling_backend(fd, readable, writable, error, timeout):
131141 raise dns.exception.Timeout
132 except select_error as e:
142 except OSError as e:
133143 if e.args[0] != errno.EINTR:
134144 raise e
135145 done = True
343353 s = b''
344354 while count > 0:
345355 _wait_for_readable(sock, expiration)
346 n = sock.recv(count)
356 try:
357 n = sock.recv(count)
358 except ssl.SSLWantReadError:
359 continue
360 except ssl.SSLWantWriteError:
361 _wait_for_writable(sock, expiration)
362 continue
347363 if n == b'':
348364 raise EOFError
349365 count = count - len(n)
360376 l = len(data)
361377 while current < l:
362378 _wait_for_writable(sock, expiration)
363 current += sock.send(data[current:])
379 try:
380 current += sock.send(data[current:])
381 except ssl.SSLWantReadError:
382 _wait_for_readable(sock, expiration)
383 continue
384 except ssl.SSLWantWriteError:
385 continue
364386
365387
366388 def send_tcp(sock, what, expiration=None):
424446 ignore_trailing=ignore_trailing)
425447 return (r, received_time)
426448
427 def _connect(s, address):
449 def _connect(s, address, expiration):
428450 try:
429451 s.connect(address)
430452 except socket.error:
436458 v_err = v[0]
437459 if v_err not in [errno.EINPROGRESS, errno.EWOULDBLOCK, errno.EALREADY]:
438460 raise v
461 _wait_for_writable(s, expiration)
462 err = s.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
463 if err != 0:
464 raise OSError(err, os.strerror(err)) from None
439465
440466
441467 def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
484510 begin_time = time.time()
485511 if source is not None:
486512 s.bind(source)
487 _connect(s, destination)
513 _connect(s, destination, expiration)
488514 send_tcp(s, wire, expiration)
489515 (r, received_time) = receive_tcp(s, expiration, one_rr_per_rrset,
490516 q.keyring, q.mac, ignore_trailing)
500526 return r
501527
502528
529 def tls(q, where, timeout=None, port=853, af=None, source=None, source_port=0,
530 one_rr_per_rrset=False, ignore_trailing=False,
531 ssl_context=None, server_hostname=None):
532 """Return the response obtained after sending a query via TLS.
533
534 *q*, a ``dns.message.Message``, the query to send
535
536 *where*, a ``text`` containing an IPv4 or IPv6 address, where
537 to send the message.
538
539 *timeout*, a ``float`` or ``None``, the number of seconds to wait before the
540 query times out. If ``None``, the default, wait forever.
541
542 *port*, an ``int``, the port send the message to. The default is 853.
543
544 *af*, an ``int``, the address family to use. The default is ``None``,
545 which causes the address family to use to be inferred from the form of
546 *where*. If the inference attempt fails, AF_INET is used. This
547 parameter is historical; you need never set it.
548
549 *source*, a ``text`` containing an IPv4 or IPv6 address, specifying
550 the source address. The default is the wildcard address.
551
552 *source_port*, an ``int``, the port from which to send the message.
553 The default is 0.
554
555 *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own
556 RRset.
557
558 *ignore_trailing*, a ``bool``. If ``True``, ignore trailing
559 junk at end of the received message.
560
561 *ssl_context*, an ``ssl.SSLContext``, the context to use when establishing
562 a TLS connection. If ``None``, the default, creates one with the default
563 configuration.
564
565 *server_hostname*, a ``text`` containing the server's hostname. The
566 default is ``None``, which means that no hostname is known, and if an
567 SSL context is created, hostname checking will be disabled.
568
569 Returns a ``dns.message.Message``.
570 """
571
572 wire = q.to_wire()
573 (af, destination, source) = _destination_and_source(af, where, port,
574 source, source_port)
575 s = socket_factory(af, socket.SOCK_STREAM, 0)
576 begin_time = None
577 received_time = None
578 try:
579 expiration = _compute_expiration(timeout)
580 s.setblocking(0)
581 begin_time = time.time()
582 if source is not None:
583 s.bind(source)
584 _connect(s, destination, expiration)
585 if ssl_context is None:
586 ssl_context = ssl.create_default_context()
587 if server_hostname is None:
588 ssl_context.check_hostname = False
589 s = ssl_context.wrap_socket(s, do_handshake_on_connect=False,
590 server_hostname=server_hostname)
591 while True:
592 try:
593 s.do_handshake()
594 break
595 except ssl.SSLWantReadError:
596 _wait_for_readable(s, expiration)
597 except ssl.SSLWantWriteError:
598 _wait_for_writable(s, expiration)
599 send_tcp(s, wire, expiration)
600 (r, received_time) = receive_tcp(s, expiration, one_rr_per_rrset,
601 q.keyring, q.mac, ignore_trailing)
602 finally:
603 if begin_time is None or received_time is None:
604 response_time = 0
605 else:
606 response_time = received_time - begin_time
607 s.close()
608 r.time = response_time
609 if not q.is_response(r):
610 raise BadResponse
611 return r
612
613
503614 def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN,
504615 timeout=None, port=53, keyring=None, keyname=None, relativize=True,
505616 af=None, lifetime=None, source=None, source_port=0, serial=0,
561672 Returns a generator of ``dns.message.Message`` objects.
562673 """
563674
564 if isinstance(zone, string_types):
675 if isinstance(zone, str):
565676 zone = dns.name.from_text(zone)
566 if isinstance(rdtype, string_types):
677 if isinstance(rdtype, str):
567678 rdtype = dns.rdatatype.from_text(rdtype)
568679 q = dns.message.make_query(zone, rdtype, rdclass)
569680 if rdtype == dns.rdatatype.IXFR:
585696 if source is not None:
586697 s.bind(source)
587698 expiration = _compute_expiration(lifetime)
588 _connect(s, destination)
699 _connect(s, destination, expiration)
589700 l = len(wire)
590701 if use_udp:
591702 _wait_for_writable(s, expiration)
607718 first = True
608719 while not done:
609720 mexpiration = _compute_expiration(timeout)
610 if mexpiration is None or mexpiration > expiration:
721 if mexpiration is None or \
722 (expiration is not None and mexpiration > expiration):
611723 mexpiration = expiration
612724 if use_udp:
613725 _wait_for_readable(s, expiration)
00 from typing import Optional, Union, Dict, Generator, Any
1 from . import message, tsig, rdatatype, rdataclass, name, message
2 def tcp(q : message.Message, where : str, timeout : float = None, port=53, af : Optional[int] = None, source : Optional[str] = None, source_port : int = 0,
3 one_rr_per_rrset=False) -> message.Message:
1 from . import tsig, rdatatype, rdataclass, name, message
2
3 try:
4 import ssl
5 except ImportError:
6 class ssl(object):
7 SSLContext = {}
8
9 def tcp(q : message.Message, where : str, timeout : float = None, port=53, af : Optional[int] = None, source : Optional[str] = None, source_port : Optional[int] = 0,
10 one_rr_per_rrset : Optional[bool] = False, ignore_trailing : Optional[bool] = False) -> message.Message:
411 pass
512
613 def xfr(where : None, zone : Union[name.Name,str], rdtype=rdatatype.AXFR, rdclass=rdataclass.IN,
714 timeout : Optional[float] =None, port=53, keyring : Optional[Dict[name.Name, bytes]] =None, keyname : Union[str,name.Name]=None, relativize=True,
815 af : Optional[int] =None, lifetime : Optional[float]=None, source : Optional[str] =None, source_port=0, serial=0,
9 use_udp=False, keyalgorithm=tsig.default_algorithm) -> Generator[Any,Any,message.Message]:
16 use_udp : Optional[bool] = False, keyalgorithm=tsig.default_algorithm) -> Generator[Any,Any,message.Message]:
1017 pass
1118
12 def udp(q : message.Message, where : str, timeout : Optional[float] = None, port=53, af : Optional[int] = None, source : Optional[str] = None, source_port=0,
13 ignore_unexpected=False, one_rr_per_rrset=False) -> message.Message:
14 ...
19 def udp(q : message.Message, where : str, timeout : Optional[float] = None, port=53, af : Optional[int] = None, source : Optional[str] = None, source_port : Optional[int] = 0,
20 ignore_unexpected : Optional[bool] = False, one_rr_per_rrset : Optional[bool] = False, ignore_trailing : Optional[bool] = False) -> message.Message:
21 pass
22
23 def tls(q : message.Message, where : str, timeout : Optional[float] = None, port=53, af : Optional[int] = None, source : Optional[str] = None, source_port : Optional[int] = 0,
24 one_rr_per_rrset : Optional[bool] = False, ignore_trailing : Optional[bool] = False, ssl_context: Optional[ssl.SSLContext] = None, server_hostname: Optional[str] = None) -> message.Message:
25 pass
1717 """DNS Result Codes."""
1818
1919 import dns.exception
20 from ._compat import long
2120
2221 #: No error
2322 NOERROR = 0
121120 if value < 0 or value > 4095:
122121 raise ValueError('rcode must be >= 0 and <= 4095')
123122 v = value & 0xf
124 ev = long(value & 0xff0) << 20
123 ev = (value & 0xff0) << 20
125124 return (v, ev)
126125
127126
2626 import dns.rdatatype
2727 import dns.tokenizer
2828 import dns.wiredata
29 from ._compat import xrange, string_types, text_type
3029
3130 try:
3231 import threading as _threading
5958 for i
6059 in range(0, len(line), chunksize)]).decode()
6160
62 __escaped = bytearray(b'"\\')
61 __escaped = b'"\\'
6362
6463 def _escapify(qstring):
6564 """Escape the characters in a quoted string which need it."""
6665
67 if isinstance(qstring, text_type):
66 if isinstance(qstring, str):
6867 qstring = qstring.encode()
6968 if not isinstance(qstring, bytearray):
7069 qstring = bytearray(qstring)
8584 return the bitmap that contains all the bytes less than that index.
8685 """
8786
88 for i in xrange(len(what) - 1, -1, -1):
87 for i in range(len(what) - 1, -1, -1):
8988 if what[i] != 0:
9089 return what[0: i + 1]
9190 return what[0:1]
369368 Returns an instance of the chosen Rdata subclass.
370369 """
371370
372 if isinstance(tok, string_types):
371 if isinstance(tok, str):
373372 tok = dns.tokenizer.Tokenizer(tok)
374373 cls = get_rdata_class(rdclass, rdtype)
375374 if cls != GenericRdata:
2525 import dns.rdataclass
2626 import dns.rdata
2727 import dns.set
28 from ._compat import string_types
2928
3029 # define SimpleSet here for backwards compatibility
3130 SimpleSet = dns.set.Set
205204 # some dynamic updates, so we don't need to print out the TTL
206205 # (which is meaningless anyway).
207206 #
208 s.write(u'{}{}{} {}\n'.format(ntext, pad,
209 dns.rdataclass.to_text(rdclass),
210 dns.rdatatype.to_text(self.rdtype)))
207 s.write('{}{}{} {}\n'.format(ntext, pad,
208 dns.rdataclass.to_text(rdclass),
209 dns.rdatatype.to_text(self.rdtype)))
211210 else:
212211 for rd in self:
213 s.write(u'%s%s%d %s %s %s\n' %
212 s.write('%s%s%d %s %s %s\n' %
214213 (ntext, pad, self.ttl, dns.rdataclass.to_text(rdclass),
215214 dns.rdatatype.to_text(self.rdtype),
216215 rd.to_text(origin=origin, relativize=relativize,
296295 Returns a ``dns.rdataset.Rdataset`` object.
297296 """
298297
299 if isinstance(rdclass, string_types):
298 if isinstance(rdclass, str):
300299 rdclass = dns.rdataclass.from_text(rdclass)
301 if isinstance(rdtype, string_types):
300 if isinstance(rdtype, str):
302301 rdtype = dns.rdatatype.from_text(rdtype)
303302 r = Rdataset(rdclass, rdtype)
304303 r.update_ttl(ttl)
7070 NSEC3PARAM = 51
7171 TLSA = 52
7272 HIP = 55
73 NINFO = 56
7374 CDS = 59
7475 CDNSKEY = 60
7576 OPENPGPKEY = 61
142143 'NSEC3PARAM': NSEC3PARAM,
143144 'TLSA': TLSA,
144145 'HIP': HIP,
146 'NINFO': NINFO,
145147 'CDS': CDS,
146148 'CDNSKEY': CDNSKEY,
147149 'OPENPGPKEY': OPENPGPKEY,
169171 # would cause the mapping not to be true inverse.
170172
171173 _by_value = {y: x for x, y in _by_text.items()}
174 # Render type 0 as "TYPE0" not "NONE", as NONE is a dnspython-ism and not
175 # an official mnemonic.
176 _by_value[0] = 'TYPE0'
172177
173178 _metatypes = {
174179 OPT: True
2020 import dns.rdata
2121 import dns.rdatatype
2222 import dns.name
23 from dns._compat import xrange
2423
2524 class CSYNC(dns.rdata.Rdata):
2625
4544 text = ''
4645 for (window, bitmap) in self.windows:
4746 bits = []
48 for i in xrange(0, len(bitmap)):
49 byte = bitmap[i]
50 for j in xrange(0, 8):
47 for (i, byte) in enumerate(bitmap):
48 for j in range(0, 8):
5149 if byte & (0x80 >> j):
5250 bits.append(dns.rdatatype.to_text(window * 256 +
5351 i * 8 + j))
1919 import dns.exception
2020 import dns.rdata
2121 import dns.tokenizer
22 from dns._compat import long, text_type
2322
2423
2524 def _validate_float_string(what):
3736
3837
3938 def _sanitize(value):
40 if isinstance(value, text_type):
39 if isinstance(value, str):
4140 return value.encode()
4241 return value
4342
5958 def __init__(self, rdclass, rdtype, latitude, longitude, altitude):
6059 super(GPOS, self).__init__(rdclass, rdtype)
6160 if isinstance(latitude, float) or \
62 isinstance(latitude, int) or \
63 isinstance(latitude, long):
61 isinstance(latitude, int):
6462 latitude = str(latitude)
6563 if isinstance(longitude, float) or \
66 isinstance(longitude, int) or \
67 isinstance(longitude, long):
64 isinstance(longitude, int):
6865 longitude = str(longitude)
6966 if isinstance(altitude, float) or \
70 isinstance(altitude, int) or \
71 isinstance(altitude, long):
67 isinstance(altitude, int):
7268 altitude = str(altitude)
7369 latitude = _sanitize(latitude)
7470 longitude = _sanitize(longitude)
1919 import dns.exception
2020 import dns.rdata
2121 import dns.tokenizer
22 from dns._compat import text_type
2322
2423
2524 class HINFO(dns.rdata.Rdata):
3635
3736 def __init__(self, rdclass, rdtype, cpu, os):
3837 super(HINFO, self).__init__(rdclass, rdtype)
39 if isinstance(cpu, text_type):
38 if isinstance(cpu, str):
4039 self.cpu = cpu.encode()
4140 else:
4241 self.cpu = cpu
43 if isinstance(os, text_type):
42 if isinstance(os, str):
4443 self.os = os.encode()
4544 else:
4645 self.os = os
4949 def to_text(self, origin=None, relativize=True, **kw):
5050 hit = binascii.hexlify(self.hit).decode()
5151 key = base64.b64encode(self.key).replace(b'\n', b'').decode()
52 text = u''
52 text = ''
5353 servers = []
5454 for server in self.servers:
5555 servers.append(server.choose_relativity(origin, relativize))
5656 if len(servers) > 0:
57 text += (u' ' + u' '.join((x.to_unicode() for x in servers)))
58 return u'%u %s %s%s' % (self.algorithm, hit, key, text)
57 text += (' ' + ' '.join((x.to_unicode() for x in servers)))
58 return '%u %s %s%s' % (self.algorithm, hit, key, text)
5959
6060 @classmethod
6161 def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
1919 import dns.exception
2020 import dns.rdata
2121 import dns.tokenizer
22 from dns._compat import text_type
2322
2423
2524 class ISDN(dns.rdata.Rdata):
3635
3736 def __init__(self, rdclass, rdtype, address, subaddress):
3837 super(ISDN, self).__init__(rdclass, rdtype)
39 if isinstance(address, text_type):
38 if isinstance(address, str):
4039 self.address = address.encode()
4140 else:
4241 self.address = address
43 if isinstance(address, text_type):
42 if isinstance(address, str):
4443 self.subaddress = subaddress.encode()
4544 else:
4645 self.subaddress = subaddress
2020
2121 import dns.exception
2222 import dns.rdata
23 from dns._compat import long, xrange, round_py2_compat
24
25
26 _pows = tuple(long(10**i) for i in range(0, 11))
23
24
25 _pows = tuple(10**i for i in range(0, 11))
2726
2827 # default values are in centimeters
2928 _default_size = 100.0
3534 if what == 0:
3635 return 0
3736 exp = None
38 for i in xrange(len(_pows)):
39 if what // _pows[i] == long(0):
37 for (i, pow) in enumerate(_pows):
38 if what // pow == 0:
4039 exp = i - 1
4140 break
4241 if exp is None or exp < 0:
5049 what *= -1
5150 else:
5251 sign = 1
53 what = round_py2_compat(what * 3600000)
52 what = round(what * 3600000) # pylint: disable=round-builtin
5453 degrees = int(what // 3600000)
5554 what -= degrees * 3600000
5655 minutes = int(what // 60000)
7069
7170
7271 def _encode_size(what, desc):
73 what = long(what)
72 what = int(what)
7473 exponent = _exponent_of(what, desc) & 0xF
7574 base = what // pow(10, exponent) & 0xF
7675 return base * 16 + exponent
8382 base = (what & 0xF0) >> 4
8483 if base > 9:
8584 raise dns.exception.SyntaxError("bad %s base" % desc)
86 return long(base) * pow(10, exponent)
85 return base * pow(10, exponent)
8786
8887
8988 class LOC(dns.rdata.Rdata):
121120 and vertical precision are specified in centimeters."""
122121
123122 super(LOC, self).__init__(rdclass, rdtype)
124 if isinstance(latitude, int) or isinstance(latitude, long):
123 if isinstance(latitude, int):
125124 latitude = float(latitude)
126125 if isinstance(latitude, float):
127126 latitude = _float_to_tuple(latitude)
128127 self.latitude = latitude
129 if isinstance(longitude, int) or isinstance(longitude, long):
128 if isinstance(longitude, int):
130129 longitude = float(longitude)
131130 if isinstance(longitude, float):
132131 longitude = _float_to_tuple(longitude)
270269 self.latitude[1] * 60000 +
271270 self.latitude[2] * 1000 +
272271 self.latitude[3]) * self.latitude[4]
273 latitude = long(0x80000000) + milliseconds
272 latitude = 0x80000000 + milliseconds
274273 milliseconds = (self.longitude[0] * 3600000 +
275274 self.longitude[1] * 60000 +
276275 self.longitude[2] * 1000 +
277276 self.longitude[3]) * self.longitude[4]
278 longitude = long(0x80000000) + milliseconds
279 altitude = long(self.altitude) + long(10000000)
277 longitude = 0x80000000 + milliseconds
278 altitude = int(self.altitude) + 10000000
280279 size = _encode_size(self.size, "size")
281280 hprec = _encode_size(self.horizontal_precision, "horizontal precision")
282281 vprec = _encode_size(self.vertical_precision, "vertical precision")
288287 def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
289288 (version, size, hprec, vprec, latitude, longitude, altitude) = \
290289 struct.unpack("!BBBBIII", wire[current: current + rdlen])
291 if latitude > long(0x80000000):
292 latitude = float(latitude - long(0x80000000)) / 3600000
290 if latitude > 0x80000000:
291 latitude = float(latitude - 0x80000000) / 3600000
293292 else:
294 latitude = -1 * float(long(0x80000000) - latitude) / 3600000
293 latitude = -1 * float(0x80000000 - latitude) / 3600000
295294 if latitude < -90.0 or latitude > 90.0:
296295 raise dns.exception.FormError("bad latitude")
297 if longitude > long(0x80000000):
298 longitude = float(longitude - long(0x80000000)) / 3600000
296 if longitude > 0x80000000:
297 longitude = float(longitude - 0x80000000) / 3600000
299298 else:
300 longitude = -1 * float(long(0x80000000) - longitude) / 3600000
299 longitude = -1 * float(0x80000000 - longitude) / 3600000
301300 if longitude < -180.0 or longitude > 180.0:
302301 raise dns.exception.FormError("bad longitude")
303302 altitude = float(altitude) - 10000000.0
0 # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
1
2 # Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
3 #
4 # Permission to use, copy, modify, and distribute this software and its
5 # documentation for any purpose with or without fee is hereby granted,
6 # provided that the above copyright notice and this permission notice
7 # appear in all copies.
8 #
9 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
12 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
17 import dns.rdtypes.txtbase
18
19
20 class NINFO(dns.rdtypes.txtbase.TXTBase):
21
22 """NINFO record
23 @see: draft-reid-dnsext-zs-01"""
2020 import dns.rdata
2121 import dns.rdatatype
2222 import dns.name
23 from dns._compat import xrange
2423
2524
2625 class NSEC(dns.rdata.Rdata):
4443 text = ''
4544 for (window, bitmap) in self.windows:
4645 bits = []
47 for i in xrange(0, len(bitmap)):
48 byte = bitmap[i]
49 for j in xrange(0, 8):
46 for (i, byte) in enumerate(bitmap):
47 for j in range(0, 8):
5048 if byte & (0x80 >> j):
5149 bits.append(dns.rdatatype.to_text(window * 256 +
5250 i * 8 + j))
1616
1717 import base64
1818 import binascii
19 import string
2019 import struct
2120
2221 import dns.exception
2322 import dns.rdata
2423 import dns.rdatatype
25 from dns._compat import xrange, text_type, PY3
2624
27 # pylint: disable=deprecated-string-function
28 if PY3:
29 b32_hex_to_normal = bytes.maketrans(b'0123456789ABCDEFGHIJKLMNOPQRSTUV',
30 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
31 b32_normal_to_hex = bytes.maketrans(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
32 b'0123456789ABCDEFGHIJKLMNOPQRSTUV')
33 else:
34 b32_hex_to_normal = string.maketrans('0123456789ABCDEFGHIJKLMNOPQRSTUV',
35 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
36 b32_normal_to_hex = string.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
37 '0123456789ABCDEFGHIJKLMNOPQRSTUV')
38 # pylint: enable=deprecated-string-function
3925
26 b32_hex_to_normal = bytes.maketrans(b'0123456789ABCDEFGHIJKLMNOPQRSTUV',
27 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
28 b32_normal_to_hex = bytes.maketrans(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
29 b'0123456789ABCDEFGHIJKLMNOPQRSTUV')
4030
4131 # hash algorithm constants
4232 SHA1 = 1
7060 self.algorithm = algorithm
7161 self.flags = flags
7262 self.iterations = iterations
73 if isinstance(salt, text_type):
63 if isinstance(salt, str):
7464 self.salt = salt.encode()
7565 else:
7666 self.salt = salt
8474 salt = '-'
8575 else:
8676 salt = binascii.hexlify(self.salt).decode()
87 text = u''
77 text = ''
8878 for (window, bitmap) in self.windows:
8979 bits = []
90 for i in xrange(0, len(bitmap)):
91 byte = bitmap[i]
92 for j in xrange(0, 8):
80 for (i, byte) in enumerate(bitmap):
81 for j in range(0, 8):
9382 if byte & (0x80 >> j):
9483 bits.append(dns.rdatatype.to_text(window * 256 +
9584 i * 8 + j))
96 text += (u' ' + u' '.join(bits))
97 return u'%u %u %u %s %s%s' % (self.algorithm, self.flags,
98 self.iterations, salt, next, text)
85 text += (' ' + ' '.join(bits))
86 return '%u %u %u %s %s%s' % (self.algorithm, self.flags,
87 self.iterations, salt, next, text)
9988
10089 @classmethod
10190 def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
10392 flags = tok.get_uint8()
10493 iterations = tok.get_uint16()
10594 salt = tok.get_string()
106 if salt == u'-':
95 if salt == '-':
10796 salt = b''
10897 else:
10998 salt = binascii.unhexlify(salt.encode('ascii'))
1919
2020 import dns.exception
2121 import dns.rdata
22 from dns._compat import text_type
2322
2423
2524 class NSEC3PARAM(dns.rdata.Rdata):
4241 self.algorithm = algorithm
4342 self.flags = flags
4443 self.iterations = iterations
45 if isinstance(salt, text_type):
44 if isinstance(salt, str):
4645 self.salt = salt.encode()
4746 else:
4847 self.salt = salt
3131
3232
3333 def sigtime_to_posixtime(what):
34 if len(what) <= 10 and what.isdigit():
35 return int(what)
3436 if len(what) != 14:
3537 raise BadSigTime
3638 year = int(what[0:4])
2020 import dns.exception
2121 import dns.rdata
2222 import dns.name
23 from dns._compat import text_type
2423
2524
2625 class URI(dns.rdata.Rdata):
4342 self.weight = weight
4443 if len(target) < 1:
4544 raise dns.exception.SyntaxError("URI target cannot be empty")
46 if isinstance(target, text_type):
45 if isinstance(target, str):
4746 self.target = target.encode()
4847 else:
4948 self.target = target
1919 import dns.exception
2020 import dns.rdata
2121 import dns.tokenizer
22 from dns._compat import text_type
2322
2423
2524 class X25(dns.rdata.Rdata):
3433
3534 def __init__(self, rdclass, rdtype, address):
3635 super(X25, self).__init__(rdclass, rdtype)
37 if isinstance(address, text_type):
36 if isinstance(address, str):
3837 self.address = address.encode()
3938 else:
4039 self.address = address
2222 import dns.inet
2323 import dns.rdata
2424 import dns.tokenizer
25 from dns._compat import xrange, maybe_chr
26
2725
2826 class APLItem(object):
2927
6462 # Truncate least significant zero bytes.
6563 #
6664 last = 0
67 for i in xrange(len(address) - 1, -1, -1):
68 if address[i] != maybe_chr(0):
65 for i in range(len(address) - 1, -1, -1):
66 if address[i] != 0:
6967 last = i + 1
7068 break
7169 address = address[0: last]
1919 import dns.exception
2020 import dns.name
2121 import dns.rdata
22 from dns._compat import xrange, text_type
2322
2423
2524 def _write_string(file, s):
3029
3130
3231 def _sanitize(value):
33 if isinstance(value, text_type):
32 if isinstance(value, str):
3433 return value.encode()
3534 return value
3635
102101 current += 4
103102 rdlen -= 4
104103 strings = []
105 for i in xrange(3):
104 for i in range(3):
106105 l = wire[current]
107106 current += 1
108107 rdlen -= 1
1919
2020 import dns.ipv4
2121 import dns.rdata
22 from dns._compat import xrange
2322
2423 _proto_tcp = socket.getprotobyname('tcp')
2524 _proto_udp = socket.getprotobyname('udp')
5049
5150 def to_text(self, origin=None, relativize=True, **kw):
5251 bits = []
53 for i in xrange(0, len(self.bitmap)):
52 for i in range(0, len(self.bitmap)):
5453 byte = self.bitmap[i]
55 for j in xrange(0, 8):
54 for j in range(0, 8):
5655 if byte & (0x80 >> j):
5756 bits.append(str(i * 8 + j))
5857 text = ' '.join(bits)
8483 i = serv // 8
8584 l = len(bitmap)
8685 if l < i + 1:
87 for j in xrange(l, i + 1):
86 for j in range(l, i + 1):
8887 bitmap.append(0)
8988 bitmap[i] = bitmap[i] | (0x80 >> (serv % 8))
9089 bitmap = dns.rdata._truncate_bitmap(bitmap)
1616 import binascii
1717
1818 import dns.rdata
19 from dns._compat import xrange
2019
2120
2221 class EUIBase(dns.rdata.Rdata):
4948 if len(text) != cls.text_len:
5049 raise dns.exception.SyntaxError(
5150 'Input text must have %s characters' % cls.text_len)
52 expected_dash_idxs = xrange(2, cls.byte_len * 3 - 1, 3)
53 for i in expected_dash_idxs:
51 for i in range(2, cls.byte_len * 3 - 1, 3):
5452 if text[i] != '-':
5553 raise dns.exception.SyntaxError('Dash expected at position %s'
5654 % i)
2121 import dns.exception
2222 import dns.rdata
2323 import dns.tokenizer
24 from dns._compat import binary_type, string_types
2524
2625
2726 class TXTBase(dns.rdata.Rdata):
3635
3736 def __init__(self, rdclass, rdtype, strings):
3837 super(TXTBase, self).__init__(rdclass, rdtype)
39 if isinstance(strings, binary_type) or \
40 isinstance(strings, string_types):
38 if isinstance(strings, bytes) or \
39 isinstance(strings, str):
4140 strings = [strings]
4241 self.strings = []
4342 for string in strings:
44 if isinstance(string, string_types):
43 if isinstance(string, str):
4544 string = string.encode()
4645 self.strings.append(string)
4746
6564 if len(token.value) > 255:
6665 raise dns.exception.SyntaxError("string too long")
6766 value = token.value
68 if isinstance(value, binary_type):
67 if isinstance(value, bytes):
6968 strings.append(value)
7069 else:
7170 strings.append(value.encode())
2323
2424 import dns.exception
2525 import dns.tsig
26 from ._compat import long
2726
2827
2928 QUESTION = 0
171170 """Add an EDNS OPT record to the message."""
172171
173172 # make sure the EDNS version in ednsflags agrees with edns
174 ednsflags &= long(0xFF00FFFF)
173 ednsflags &= 0xFF00FFFF
175174 ednsflags |= (edns << 16)
176175 self._set_section(ADDITIONAL)
177176 before = self.output.tell()
2020 import sys
2121 import time
2222 import random
23
2423 try:
2524 import threading as _threading
2625 except ImportError:
3837 import dns.rdatatype
3938 import dns.reversename
4039 import dns.tsig
41 from ._compat import xrange, string_types
4240
4341 if sys.platform == 'win32':
4442 try:
181179 class NoMetaqueries(dns.exception.DNSException):
182180 """DNS metaqueries are not allowed."""
183181
182 class NoResolverConfiguration(dns.exception.DNSException):
183 """Resolver configuration could not be read or specified no nameservers."""
184184
185185 class Answer(object):
186186 """DNS stub resolver answer.
199199 """
200200
201201 def __init__(self, qname, rdtype, rdclass, response,
202 raise_on_no_answer=True):
202 raise_on_no_answer=True, nameserver=None,
203 port=None):
203204 self.qname = qname
204205 self.rdtype = rdtype
205206 self.rdclass = rdclass
206207 self.response = response
208 self.nameserver = nameserver
209 self.port = port
207210 min_ttl = -1
208211 rrset = None
209 for count in xrange(0, 15):
212 for count in range(0, 15):
210213 try:
211214 rrset = response.find_rrset(response.answer, qname,
212215 rdclass, rdtype)
572575 a ``text``, it is used as the name of the file to open; otherwise it
573576 is treated as the file itself."""
574577
575 if isinstance(f, string_types):
578 if isinstance(f, str):
576579 try:
577580 f = open(f, 'r')
578581 except IOError:
579582 # /etc/resolv.conf doesn't exist, can't be read, etc.
580 # We'll just use the default resolver configuration.
581 self.nameservers = ['127.0.0.1']
582 return
583 raise NoResolverConfiguration
583584 want_close = True
584585 else:
585586 want_close = False
607608 if want_close:
608609 f.close()
609610 if len(self.nameservers) == 0:
610 self.nameservers.append('127.0.0.1')
611 raise NoResolverConfiguration
611612
612613 def _determine_split_char(self, entry):
613614 #
823824
824825 *source_port*, an ``int``, the port from which to send the message.
825826
826 *lifetime*, a ``float``, how long query should run before timing out.
827 *lifetime*, a ``float``, how many seconds a query should run before timing out.
827828
828829 Raises ``dns.exception.Timeout`` if no answers could be found
829830 in the specified lifetime.
843844 Returns a ``dns.resolver.Answer`` instance.
844845 """
845846
846 if isinstance(qname, string_types):
847 if isinstance(qname, str):
847848 qname = dns.name.from_text(qname, None)
848 if isinstance(rdtype, string_types):
849 if isinstance(rdtype, str):
849850 rdtype = dns.rdatatype.from_text(rdtype)
850851 if dns.rdatatype.is_metatype(rdtype):
851852 raise NoMetaqueries
852 if isinstance(rdclass, string_types):
853 if isinstance(rdclass, str):
853854 rdclass = dns.rdataclass.from_text(rdclass)
854855 if dns.rdataclass.is_metaclass(rdclass):
855856 raise NoMetaqueries
892893 if self.rotate:
893894 random.shuffle(nameservers)
894895 backoff = 0.10
896 # keep track of nameserver and port
897 # to include them in Answer
898 nameserver_answered = None
899 port_answered = None
895900 while response is None:
896901 if len(nameservers) == 0:
897902 raise NoNameservers(request=request, errors=errors)
906911 source=source,
907912 source_port=source_port)
908913 else:
909 response = dns.query.udp(request, nameserver,
910 timeout, port,
911 source=source,
912 source_port=source_port)
913 if response.flags & dns.flags.TC:
914 try:
915 response = dns.query.udp(request, nameserver,
916 timeout, port,
917 source=source,
918 source_port=\
919 source_port)
920 except dns.message.Truncated:
914921 # Response truncated; retry with TCP.
915922 tcp_attempt = True
916923 timeout = self._compute_timeout(start, lifetime)
959966 response))
960967 response = None
961968 continue
969 nameserver_answered = nameserver
970 port_answered = port
962971 rcode = response.rcode()
963972 if rcode == dns.rcode.YXDOMAIN:
964973 ex = YXDOMAIN()
10001009 if all_nxdomain:
10011010 raise NXDOMAIN(qnames=qnames_to_try, responses=nxdomain_responses)
10021011 answer = Answer(_qname, rdtype, rdclass, response,
1003 raise_on_no_answer)
1012 raise_on_no_answer, nameserver_answered, port_answered)
10041013 if self.cache:
10051014 self.cache.put((_qname, rdtype, rdclass), answer)
10061015 return answer
11201129 Returns a ``dns.name.Name``.
11211130 """
11221131
1123 if isinstance(name, string_types):
1132 if isinstance(name, str):
11241133 name = dns.name.from_text(name, dns.name.root)
11251134 if resolver is None:
11261135 resolver = get_default_resolver()
11611170 def _getaddrinfo(host=None, service=None, family=socket.AF_UNSPEC, socktype=0,
11621171 proto=0, flags=0):
11631172 if flags & (socket.AI_ADDRCONFIG | socket.AI_V4MAPPED) != 0:
1164 raise NotImplementedError
1173 # Not implemented. We raise a gaierror as opposed to a
1174 # NotImplementedError as it helps callers handle errors more
1175 # appropriately. [Issue #316]
1176 raise socket.gaierror(socket.EAI_SYSTEM)
11651177 if host is None and service is None:
11661178 raise socket.gaierror(socket.EAI_NONAME)
11671179 v6addrs = []
22
33 import socket
44 _gethostbyname = socket.gethostbyname
5 class NXDOMAIN(exception.DNSException):
6 ...
5
6 class NXDOMAIN(exception.DNSException): ...
7 class YXDOMAIN(exception.DNSException): ...
8 class NoAnswer(exception.DNSException): ...
9 class NoNameservers(exception.DNSException): ...
10 class NotAbsolute(exception.DNSException): ...
11 class NoRootSOA(exception.DNSException): ...
12 class NoMetaqueries(exception.DNSException): ...
13 class NoResolverConfiguration(exception.DNSException): ...
14 Timeout = exception.Timeout
15
716 def query(qname : str, rdtype : Union[int,str] = 0, rdclass : Union[int,str] = 0,
817 tcp=False, source=None, raise_on_no_answer=True,
918 source_port=0):
2222 import dns.ipv6
2323 import dns.ipv4
2424
25 from dns._compat import PY3
26
2725 ipv4_reverse_domain = dns.name.from_text('in-addr.arpa.')
2826 ipv6_reverse_domain = dns.name.from_text('ip6.arpa.')
2927
4341 try:
4442 v6 = dns.ipv6.inet_aton(text)
4543 if dns.ipv6.is_mapped(v6):
46 if PY3:
47 parts = ['%d' % byte for byte in v6[12:]]
48 else:
49 parts = ['%d' % ord(byte) for byte in v6[12:]]
44 parts = ['%d' % byte for byte in v6[12:]]
5045 origin = ipv4_reverse_domain
5146 else:
5247 parts = [x for x in str(binascii.hexlify(v6).decode())]
5348 origin = ipv6_reverse_domain
5449 except Exception:
5550 parts = ['%d' %
56 byte for byte in bytearray(dns.ipv4.inet_aton(text))]
51 byte for byte in dns.ipv4.inet_aton(text)]
5752 origin = ipv4_reverse_domain
5853 parts.reverse()
5954 return dns.name.from_text('.'.join(parts), origin=origin)
2121 import dns.rdataset
2222 import dns.rdataclass
2323 import dns.renderer
24 from ._compat import string_types
2524
2625
2726 class RRset(dns.rdataset.Rdataset):
133132 Returns a ``dns.rrset.RRset`` object.
134133 """
135134
136 if isinstance(name, string_types):
135 if isinstance(name, str):
137136 name = dns.name.from_text(name, None, idna_codec=idna_codec)
138 if isinstance(rdclass, string_types):
137 if isinstance(rdclass, str):
139138 rdclass = dns.rdataclass.from_text(rdclass)
140 if isinstance(rdtype, string_types):
139 if isinstance(rdtype, str):
141140 rdtype = dns.rdatatype.from_text(rdtype)
142141 r = RRset(name, rdclass, rdtype)
143142 r.update_ttl(ttl)
164163 Returns a ``dns.rrset.RRset`` object.
165164 """
166165
167 if isinstance(name, string_types):
166 if isinstance(name, str):
168167 name = dns.name.from_text(name, None, idna_codec=idna_codec)
169168
170169 if len(rdatas) == 0:
2222 import dns.exception
2323 import dns.name
2424 import dns.ttl
25 from ._compat import long, text_type, binary_type
2625
2726 _DELIMITERS = {
2827 ' ': True,
188187 will return.
189188 """
190189
191 if isinstance(f, text_type):
190 if isinstance(f, str):
192191 f = StringIO(f)
193192 if filename is None:
194193 filename = '<string>'
195 elif isinstance(f, binary_type):
194 elif isinstance(f, bytes):
196195 f = StringIO(f.decode())
197196 if filename is None:
198197 filename = '<string>'
496495 raise dns.exception.SyntaxError('expecting an identifier')
497496 if not token.value.isdigit():
498497 raise dns.exception.SyntaxError('expecting an integer')
499 value = long(token.value)
500 if value < 0 or value > long(4294967296):
498 value = int(token.value)
499 if value < 0 or value > 4294967296:
501500 raise dns.exception.SyntaxError(
502501 '%d is not an unsigned 32-bit integer' % value)
503502 return value
2323 import dns.exception
2424 import dns.rdataclass
2525 import dns.name
26 from ._compat import long, string_types, text_type
2726
2827 class BadTime(dns.exception.DNSException):
2928
9695 @raises NotImplementedError: I{algorithm} is not supported
9796 """
9897
99 if isinstance(other_data, text_type):
98 if isinstance(other_data, str):
10099 other_data = other_data.encode()
101100 (algorithm_name, digestmod) = get_algorithm(algorithm)
102101 if first:
112111 ctx.update(keyname.to_digestable())
113112 ctx.update(struct.pack('!H', dns.rdataclass.ANY))
114113 ctx.update(struct.pack('!I', 0))
115 long_time = time + long(0)
116 upper_time = (long_time >> 32) & long(0xffff)
117 lower_time = long_time & long(0xffffffff)
114 upper_time = (time >> 32) & 0xffff
115 lower_time = time & 0xffffffff
118116 time_mac = struct.pack('!HIH', upper_time, lower_time, fudge)
119117 pre_mac = algorithm_name + time_mac
120118 ol = len(other_data)
166164 current = current + used
167165 (upper_time, lower_time, fudge, mac_size) = \
168166 struct.unpack("!HIHH", wire[current:current + 10])
169 time = ((upper_time + long(0)) << 32) + (lower_time + long(0))
167 time = (upper_time << 32) + lower_time
170168 current += 10
171169 mac = wire[current:current + mac_size]
172170 current += mac_size
208206 @raises NotImplementedError: I{algorithm} is not supported
209207 """
210208
211 if isinstance(algorithm, string_types):
209 if isinstance(algorithm, str):
212210 algorithm = dns.name.from_text(algorithm)
213211
214212 try:
1616
1717 """A place to store TSIG keys."""
1818
19 from dns._compat import maybe_decode, maybe_encode
20
2119 import base64
2220
2321 import dns.name
3129 keyring = {}
3230 for keytext in textring:
3331 keyname = dns.name.from_text(keytext)
34 secret = base64.decodestring(maybe_encode(textring[keytext]))
32 secret = base64.decodebytes(textring[keytext].encode())
3533 keyring[keyname] = secret
3634 return keyring
3735
4341
4442 textring = {}
4543 for keyname in keyring:
46 keytext = maybe_decode(keyname.to_text())
47 secret = maybe_decode(base64.encodestring(keyring[keyname]))
44 keytext = keyname.to_text()
45 # rstrip to get rid of the \n encoding adds
46 secret = base64.encodebytes(keyring[keyname]).decode().rstrip()
4847 textring[keytext] = secret
4948 return textring
1717 """DNS TTL conversion."""
1818
1919 import dns.exception
20 from ._compat import long
2120
2221
2322 class BadTTL(dns.exception.SyntaxError):
3736 """
3837
3938 if text.isdigit():
40 total = long(text)
39 total = int(text)
4140 else:
4241 if not text[0].isdigit():
4342 raise BadTTL
44 total = long(0)
45 current = long(0)
43 total = 0
44 current = 0
4645 for c in text:
4746 if c.isdigit():
4847 current *= 10
49 current += long(c)
48 current += int(c)
5049 else:
5150 c = c.lower()
5251 if c == 'w':
53 total += current * long(604800)
52 total += current * 604800
5453 elif c == 'd':
55 total += current * long(86400)
54 total += current * 86400
5655 elif c == 'h':
57 total += current * long(3600)
56 total += current * 3600
5857 elif c == 'm':
59 total += current * long(60)
58 total += current * 60
6059 elif c == 's':
6160 total += current
6261 else:
6463 current = 0
6564 if not current == 0:
6665 raise BadTTL("trailing integer")
67 if total < long(0) or total > long(2147483647):
66 if total < 0 or total > 2147483647:
6867 raise BadTTL("TTL should be between 0 and 2^31 - 1 (inclusive)")
6968 return total
2424 import dns.rdataclass
2525 import dns.rdataset
2626 import dns.tsig
27 from ._compat import string_types
2827
2928
3029 class Update(dns.message.Message):
5554 """
5655 super(Update, self).__init__()
5756 self.flags |= dns.opcode.to_flags(dns.opcode.UPDATE)
58 if isinstance(zone, string_types):
57 if isinstance(zone, str):
5958 zone = dns.name.from_text(zone)
6059 self.origin = zone
61 if isinstance(rdclass, string_types):
60 if isinstance(rdclass, str):
6261 rdclass = dns.rdataclass.from_text(rdclass)
6362 self.zone_rdclass = rdclass
6463 self.find_rrset(self.question, self.origin, rdclass, dns.rdatatype.SOA,
9291 - ttl, rdtype, string...
9392 """
9493
95 if isinstance(name, string_types):
94 if isinstance(name, str):
9695 name = dns.name.from_text(name, None)
9796 if isinstance(args[0], dns.rdataset.Rdataset):
9897 for rds in args:
110109 self._add_rr(name, ttl, rd, section=section)
111110 else:
112111 rdtype = args.pop(0)
113 if isinstance(rdtype, string_types):
112 if isinstance(rdtype, str):
114113 rdtype = dns.rdatatype.from_text(rdtype)
115114 if replace:
116115 self.delete(name, rdtype)
149148 - rdtype, [string...]
150149 """
151150
152 if isinstance(name, string_types):
151 if isinstance(name, str):
153152 name = dns.name.from_text(name, None)
154153 if len(args) == 0:
155154 self.find_rrset(self.authority, name, dns.rdataclass.ANY,
166165 self._add_rr(name, 0, rd, dns.rdataclass.NONE)
167166 else:
168167 rdtype = args.pop(0)
169 if isinstance(rdtype, string_types):
168 if isinstance(rdtype, str):
170169 rdtype = dns.rdatatype.from_text(rdtype)
171170 if len(args) == 0:
172171 self.find_rrset(self.authority, name,
213212 - rdtype, string...
214213 """
215214
216 if isinstance(name, string_types):
215 if isinstance(name, str):
217216 name = dns.name.from_text(name, None)
218217 if len(args) == 0:
219218 self.find_rrset(self.answer, name,
230229 self._add(False, self.answer, name, *args)
231230 else:
232231 rdtype = args[0]
233 if isinstance(rdtype, string_types):
232 if isinstance(rdtype, str):
234233 rdtype = dns.rdatatype.from_text(rdtype)
235234 self.find_rrset(self.answer, name,
236235 dns.rdataclass.ANY, rdtype,
241240 """Require that an owner name (and optionally an rdata type) does
242241 not exist as a prerequisite to the execution of the update."""
243242
244 if isinstance(name, string_types):
243 if isinstance(name, str):
245244 name = dns.name.from_text(name, None)
246245 if rdtype is None:
247246 self.find_rrset(self.answer, name,
249248 dns.rdatatype.NONE, None,
250249 True, True)
251250 else:
252 if isinstance(rdtype, string_types):
251 if isinstance(rdtype, str):
253252 rdtype = dns.rdatatype.from_text(rdtype)
254253 self.find_rrset(self.answer, name,
255254 dns.rdataclass.NONE, rdtype,
1717 """dnspython release version information."""
1818
1919 #: MAJOR
20 MAJOR = 1
20 MAJOR = 2
2121 #: MINOR
22 MINOR = 16
22 MINOR = 0
2323 #: MICRO
2424 MICRO = 0
2525 #: RELEASELEVEL
1717 """DNS Wire Data Helper"""
1818
1919 import dns.exception
20 from ._compat import binary_type, string_types, PY2
2120
2221 # Figure out what constant python passes for an unspecified slice bound.
2322 # It's supposed to be sys.maxint, yet on 64-bit windows sys.maxint is 2^31 - 1
2625 # out what constant Python will use.
2726
2827
29 class _SliceUnspecifiedBound(binary_type):
28 class _SliceUnspecifiedBound(bytes):
3029
3130 def __getitem__(self, key):
3231 return key.stop
3332
34 if PY2:
35 def __getslice__(self, i, j): # pylint: disable=getslice-method
36 return self.__getitem__(slice(i, j))
37
3833 _unspecified_bound = _SliceUnspecifiedBound()[1:]
3934
4035
41 class WireData(binary_type):
36 class WireData(bytes):
4237 # WireData is a binary type with stricter slicing
4338
4439 def __getitem__(self, key):
5045 start = key.start
5146 stop = key.stop
5247
53 if PY2:
54 if stop == _unspecified_bound:
55 # handle the case where the right bound is unspecified
56 stop = len(self)
57
58 if start < 0 or stop < 0:
48 for index in (start, stop):
49 if index is None:
50 continue
51 elif abs(index) > len(self):
5952 raise dns.exception.FormError
60 # If it's not an empty slice, access left and right bounds
61 # to make sure they're valid
62 if start != stop:
63 super(WireData, self).__getitem__(start)
64 super(WireData, self).__getitem__(stop - 1)
65 else:
66 for index in (start, stop):
67 if index is None:
68 continue
69 elif abs(index) > len(self):
70 raise dns.exception.FormError
7153
7254 return WireData(super(WireData, self).__getitem__(
7355 slice(start, stop)))
74 return bytearray(self.unwrap())[key]
56 return self.unwrap()[key]
7557 except IndexError:
7658 raise dns.exception.FormError
77
78 if PY2:
79 def __getslice__(self, i, j): # pylint: disable=getslice-method
80 return self.__getitem__(slice(i, j))
8159
8260 def __iter__(self):
8361 i = 0
8967 raise StopIteration
9068
9169 def unwrap(self):
92 return binary_type(self)
70 return bytes(self)
9371
9472
9573 def maybe_wrap(wire):
9674 if isinstance(wire, WireData):
9775 return wire
98 elif isinstance(wire, binary_type):
76 elif isinstance(wire, bytes):
9977 return WireData(wire)
100 elif isinstance(wire, string_types):
78 elif isinstance(wire, str):
10179 return WireData(wire.encode())
10280 raise ValueError("unhandled type %s" % type(wire))
3434 import dns.tokenizer
3535 import dns.ttl
3636 import dns.grange
37 from ._compat import string_types, text_type, PY3
3837
3938
4039 class BadZone(dns.exception.DNSException):
9493 @type rdclass: int"""
9594
9695 if origin is not None:
97 if isinstance(origin, string_types):
96 if isinstance(origin, str):
9897 origin = dns.name.from_text(origin)
9998 elif not isinstance(origin, dns.name.Name):
10099 raise ValueError("origin parameter must be convertible to a "
128127 return not self.__eq__(other)
129128
130129 def _validate_name(self, name):
131 if isinstance(name, string_types):
130 if isinstance(name, str):
132131 name = dns.name.from_text(name, None)
133132 elif not isinstance(name, dns.name.Name):
134133 raise KeyError("name parameter must be convertible to a DNS name")
156155 return self.nodes.__iter__()
157156
158157 def iterkeys(self):
159 if PY3:
160 return self.nodes.keys() # pylint: disable=dict-keys-not-iterating
161 else:
162 return self.nodes.iterkeys() # pylint: disable=dict-iter-method
158 return self.nodes.keys() # pylint: disable=dict-keys-not-iterating
163159
164160 def keys(self):
165161 return self.nodes.keys() # pylint: disable=dict-keys-not-iterating
166162
167163 def itervalues(self):
168 if PY3:
169 return self.nodes.values() # pylint: disable=dict-values-not-iterating
170 else:
171 return self.nodes.itervalues() # pylint: disable=dict-iter-method
164 return self.nodes.values() # pylint: disable=dict-values-not-iterating
172165
173166 def values(self):
174167 return self.nodes.values() # pylint: disable=dict-values-not-iterating
264257 """
265258
266259 name = self._validate_name(name)
267 if isinstance(rdtype, string_types):
260 if isinstance(rdtype, str):
268261 rdtype = dns.rdatatype.from_text(rdtype)
269 if isinstance(covers, string_types):
262 if isinstance(covers, str):
270263 covers = dns.rdatatype.from_text(covers)
271264 node = self.find_node(name, create)
272265 return node.find_rdataset(self.rdclass, rdtype, covers, create)
327320 """
328321
329322 name = self._validate_name(name)
330 if isinstance(rdtype, string_types):
323 if isinstance(rdtype, str):
331324 rdtype = dns.rdatatype.from_text(rdtype)
332 if isinstance(covers, string_types):
325 if isinstance(covers, str):
333326 covers = dns.rdatatype.from_text(covers)
334327 node = self.get_node(name)
335328 if node is not None:
390383 """
391384
392385 name = self._validate_name(name)
393 if isinstance(rdtype, string_types):
386 if isinstance(rdtype, str):
394387 rdtype = dns.rdatatype.from_text(rdtype)
395 if isinstance(covers, string_types):
388 if isinstance(covers, str):
396389 covers = dns.rdatatype.from_text(covers)
397390 rdataset = self.nodes[name].find_rdataset(self.rdclass, rdtype, covers)
398391 rrset = dns.rrset.RRset(name, self.rdclass, rdtype, covers)
446439 @type covers: int or string
447440 """
448441
449 if isinstance(rdtype, string_types):
442 if isinstance(rdtype, str):
450443 rdtype = dns.rdatatype.from_text(rdtype)
451 if isinstance(covers, string_types):
444 if isinstance(covers, str):
452445 covers = dns.rdatatype.from_text(covers)
453446 for (name, node) in self.iteritems(): # pylint: disable=dict-iter-method
454447 for rds in node:
469462 @type covers: int or string
470463 """
471464
472 if isinstance(rdtype, string_types):
465 if isinstance(rdtype, str):
473466 rdtype = dns.rdatatype.from_text(rdtype)
474 if isinstance(covers, string_types):
467 if isinstance(covers, str):
475468 covers = dns.rdatatype.from_text(covers)
476469 for (name, node) in self.iteritems(): # pylint: disable=dict-iter-method
477470 for rds in node:
498491 @type nl: string or None
499492 """
500493
501 if isinstance(f, string_types):
494 if isinstance(f, str):
502495 f = open(f, 'wb')
503496 want_close = True
504497 else:
512505
513506 if nl is None:
514507 nl_b = os.linesep.encode(file_enc) # binary mode, '\n' is not enough
515 nl = u'\n'
516 elif isinstance(nl, string_types):
508 nl = '\n'
509 elif isinstance(nl, str):
517510 nl_b = nl.encode(file_enc)
518511 else:
519512 nl_b = nl
528521 for n in names:
529522 l = self[n].to_text(n, origin=self.origin,
530523 relativize=relativize)
531 if isinstance(l, text_type):
524 if isinstance(l, str):
532525 l_b = l.encode(file_enc)
533526 else:
534527 l_b = l
618611
619612 def __init__(self, tok, origin, rdclass, relativize, zone_factory=Zone,
620613 allow_include=False, check_origin=True):
621 if isinstance(origin, string_types):
614 if isinstance(origin, str):
622615 origin = dns.name.from_text(origin)
623616 self.tok = tok
624617 self.current_origin = origin
664657 token = self.tok.get()
665658 if not token.is_identifier():
666659 raise dns.exception.SyntaxError
660
667661 # TTL
662 ttl = None
668663 try:
669664 ttl = dns.ttl.from_text(token.value)
670665 self.last_ttl = ttl
673668 if not token.is_identifier():
674669 raise dns.exception.SyntaxError
675670 except dns.ttl.BadTTL:
676 if not (self.last_ttl_known or self.default_ttl_known):
677 raise dns.exception.SyntaxError("Missing default TTL value")
678671 if self.default_ttl_known:
679672 ttl = self.default_ttl
680 else:
673 elif self.last_ttl_known:
681674 ttl = self.last_ttl
675
682676 # Class
683677 try:
684678 rdclass = dns.rdataclass.from_text(token.value)
725719 self.default_ttl = rd.minimum
726720 self.default_ttl_known = True
727721
722 # TTL check
723 if ttl is None:
724 if not (self.last_ttl_known or self.default_ttl_known):
725 raise dns.exception.SyntaxError("Missing default TTL value")
726 else:
727 if self.default_ttl_known:
728 ttl = self.default_ttl
729 else:
730 ttl = self.last_ttl
731
728732 rd.choose_relativity(self.zone.origin, self.relativize)
729733 covers = rd.covers()
730734 rds = n.find_rdataset(rdclass, rdtype, covers, True)
733737 def _parse_modify(self, side):
734738 # Here we catch everything in '{' '}' in a group so we can replace it
735739 # with ''.
736 is_generate1 = re.compile("^.*\$({(\+|-?)(\d+),(\d+),(.)}).*$")
737 is_generate2 = re.compile("^.*\$({(\+|-?)(\d+)}).*$")
738 is_generate3 = re.compile("^.*\$({(\+|-?)(\d+),(\d+)}).*$")
740 is_generate1 = re.compile(r"^.*\$({(\+|-?)(\d+),(\d+),(.)}).*$")
741 is_generate2 = re.compile(r"^.*\$({(\+|-?)(\d+)}).*$")
742 is_generate3 = re.compile(r"^.*\$({(\+|-?)(\d+),(\d+)}).*$")
739743 # Sometimes there are modifiers in the hostname. These come after
740744 # the dollar sign. They are in the form: ${offset[,width[,base]]}.
741745 # Make names
753757 base = 'd'
754758 g3 = is_generate3.match(side)
755759 if g3:
756 mod, sign, offset, width = g1.groups()
760 mod, sign, offset, width = g3.groups()
757761 if sign == '':
758762 sign = '+'
759 width = g1.groups()[2]
760763 base = 'd'
761764
762765 if not (g1 or g2 or g3):
810813 raise dns.exception.SyntaxError("Missing default TTL value")
811814 if self.default_ttl_known:
812815 ttl = self.default_ttl
813 else:
816 elif self.last_ttl_known:
814817 ttl = self.last_ttl
815818 # Class
816819 try:
845848 for i in range(start, stop + 1, step):
846849 # +1 because bind is inclusive and python is exclusive
847850
848 if lsign == u'+':
851 if lsign == '+':
849852 lindex = i + int(loffset)
850 elif lsign == u'-':
853 elif lsign == '-':
851854 lindex = i - int(loffset)
852855
853 if rsign == u'-':
856 if rsign == '-':
854857 rindex = i - int(roffset)
855 elif rsign == u'+':
858 elif rsign == '+':
856859 rindex = i + int(roffset)
857860
858861 lzfindex = str(lindex).zfill(int(lwidth))
859862 rzfindex = str(rindex).zfill(int(rwidth))
860863
861 name = lhs.replace(u'$%s' % (lmod), lzfindex)
862 rdata = rhs.replace(u'$%s' % (rmod), rzfindex)
864 name = lhs.replace('$%s' % (lmod), lzfindex)
865 rdata = rhs.replace('$%s' % (rmod), rzfindex)
863866
864867 self.last_name = dns.name.from_text(name, self.current_origin)
865868 name = self.last_name
924927 elif token.is_comment():
925928 self.tok.get_eol()
926929 continue
927 elif token.value[0] == u'$':
930 elif token.value[0] == '$':
928931 c = token.value.upper()
929 if c == u'$TTL':
932 if c == '$TTL':
930933 token = self.tok.get()
931934 if not token.is_identifier():
932935 raise dns.exception.SyntaxError("bad $TTL")
933936 self.default_ttl = dns.ttl.from_text(token.value)
934937 self.default_ttl_known = True
935938 self.tok.get_eol()
936 elif c == u'$ORIGIN':
939 elif c == '$ORIGIN':
937940 self.current_origin = self.tok.get_name()
938941 self.tok.get_eol()
939942 if self.zone.origin is None:
940943 self.zone.origin = self.current_origin
941 elif c == u'$INCLUDE' and self.allow_include:
944 elif c == '$INCLUDE' and self.allow_include:
942945 token = self.tok.get()
943946 filename = token.value
944947 token = self.tok.get()
964967 self.tok = dns.tokenizer.Tokenizer(self.current_file,
965968 filename)
966969 self.current_origin = new_origin
967 elif c == u'$GENERATE':
970 elif c == '$GENERATE':
968971 self._generate_line()
969972 else:
970973 raise dns.exception.SyntaxError(
10591062 @rtype: dns.zone.Zone object
10601063 """
10611064
1062 str_type = string_types
1063 if PY3:
1064 opts = 'r'
1065 else:
1066 opts = 'rU'
1067
1068 if isinstance(f, str_type):
1065 if isinstance(f, str):
10691066 if filename is None:
10701067 filename = f
1071 f = open(f, opts)
1068 f = open(f, 'r')
10721069 want_close = True
10731070 else:
10741071 if filename is None:
2222 while True:
2323 (wire, address) = s.recvfrom(512)
2424 notify = dns.message.from_wire(wire)
25 soa = notify.find_rrset(notify.answer, notify.question[0].name,
26 dns.rdataclass.IN, dns.rdatatype.SOA)
2725
28 # Do something with the SOA RR here
29 print('The serial number for', soa.name, 'is', soa[0].serial)
26 try:
27 soa = notify.find_rrset(notify.answer, notify.question[0].name,
28 dns.rdataclass.IN, dns.rdatatype.SOA)
29
30 # Do something with the SOA RR here
31 print('The serial number for', soa.name, 'is', soa[0].serial)
32 except KeyError:
33 # No SOA RR in the answer section.
34 pass
3035
3136 response = dns.message.make_response(notify) # type: dns.message.Message
3237 response.flags |= dns.flags.AA
0 #!/usr/bin/env python
1 #
02 # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
1
2 #!/usr/bin/env python
33 #
44 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
55 #
1919 import sys
2020 from setuptools import setup
2121
22 version = '1.16.0'
22 version = '2.0.0'
2323
2424 try:
2525 sys.argv.remove("--cython-compile")
6161 "Programming Language :: Python",
6262 "Topic :: Internet :: Name Service (DNS)",
6363 "Topic :: Software Development :: Libraries :: Python Modules",
64 "Programming Language :: Python :: 2",
65 "Programming Language :: Python :: 2.7",
6664 "Programming Language :: Python :: 3",
6765 "Programming Language :: Python :: 3.4",
6866 "Programming Language :: Python :: 3.5",
6967 "Programming Language :: Python :: 3.6",
7068 "Programming Language :: Python :: 3.7",
7169 ],
72 'python_requires': '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
70 'python_requires': '>=3.4',
7371 'test_suite': 'tests',
7472 'provides': ['dns'],
73 'tests_require': ['typing ; python_version<"3.5"'],
7574 'extras_require': {
7675 'IDNA': ['idna>=2.1'],
7776 'DNSSEC': ['pycryptodome', 'ecdsa>=0.13'],
167167 unknown2 TYPE999 \# 8 0a0000010a000001
168168 unknown3 A \# 4 7f000002
169169 rrsig01 RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl d80jEeC8aTrO+KKmCaY=
170 rrsig02 RRSIG NSEC 1 3 3600 1577836800 1041379200 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/vILz45IkskceFGgi WCn/GxHhai6VAuHAoNUz4YoU1tVfSCSqQYn6//11U6Nl d80jEeC8aTrO+KKmCaY=
170171 nsec01 NSEC a.secure A MX RRSIG NSEC TYPE1234
171172 nsec02 NSEC . ( NSAP-PTR NSEC )
172173 nsec03 NSEC . ( NSEC TYPE65535 )
9595 rp01 3600 IN RP mbox-dname txt-dname
9696 rp02 3600 IN RP . .
9797 rrsig01 3600 IN RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY=
98 rrsig02 3600 IN RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY=
9899 rt01 3600 IN RT 0 intermediate-host
99100 rt02 3600 IN RT 65535 .
100101 s 300 IN NS ns.s
9595 rp01.example. 3600 IN RP mbox-dname.example. txt-dname.example.
9696 rp02.example. 3600 IN RP . .
9797 rrsig01.example. 3600 IN RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo.example. MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY=
98 rrsig02.example. 3600 IN RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo.example. MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY=
9899 rt01.example. 3600 IN RT 0 intermediate-host.example.
99100 rt02.example. 3600 IN RT 65535 .
100101 s.example. 300 IN NS ns.s.example.
9595 rp01 3600 IN RP mbox-dname txt-dname
9696 rp02 3600 IN RP . .
9797 rrsig01 3600 IN RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY=
98 rrsig02 3600 IN RRSIG NSEC 1 3 3600 20200101000000 20030101000000 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY=
9899 rt01 3600 IN RT 0 intermediate-host
99100 rt02 3600 IN RT 65535 .
100101 s 300 IN NS ns.s
3030 def test_float_LOC(self):
3131 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.LOC,
3232 u"30 30 0.000 N 100 30 0.000 W 10.00m 20m 2000m 20m")
33 self.failUnless(rdata.float_latitude == 30.5)
34 self.failUnless(rdata.float_longitude == -100.5)
33 self.assertTrue(rdata.float_latitude == 30.5)
34 self.assertTrue(rdata.float_longitude == -100.5)
3535
3636 def test_SOA_BIND8_TTL(self):
3737 rdata1 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
3838 u"a b 100 1s 1m 1h 1d")
3939 rdata2 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
4040 u"a b 100 1 60 3600 86400")
41 self.failUnless(rdata1 == rdata2)
41 self.assertTrue(rdata1 == rdata2)
4242
4343 def test_TTL_bounds_check(self):
4444 def bad():
4545 dns.ttl.from_text("2147483648")
46 self.failUnlessRaises(dns.ttl.BadTTL, bad)
46 self.assertRaises(dns.ttl.BadTTL, bad)
4747
4848 def test_empty_NSEC3_window(self):
4949 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NSEC3,
5050 u"1 0 100 ABCD SCBCQHKU35969L2A68P3AD59LHF30715")
51 self.failUnless(rdata.windows == [])
51 self.assertTrue(rdata.windows == [])
5252
5353 def test_zero_size_APL(self):
5454 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.APL,
5555 "")
5656 rdata2 = dns.rdata.from_wire(dns.rdataclass.IN, dns.rdatatype.APL,
5757 "", 0, 0)
58 self.failUnless(rdata == rdata2)
58 self.assertTrue(rdata == rdata2)
5959
6060 def test_CAA_from_wire(self):
6161 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CAA,
62 u'0 issue "ca.example.net"')
62 '0 issue "ca.example.net"')
6363 f = BytesIO()
6464 rdata.to_wire(f)
6565 wire = f.getvalue()
6767 wire += b"trailing garbage"
6868 rdata2 = dns.rdata.from_wire(dns.rdataclass.IN, dns.rdatatype.CAA,
6969 wire, 0, rdlen)
70 self.failUnless(rdata == rdata2)
70 self.assertTrue(rdata == rdata2)
7171
7272 def test_trailing_zero_APL(self):
7373 in4 = "!1:127.0.0.0/1"
7474 rd4 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.APL, in4)
7575 out4 = rd4.to_digestable(dns.name.from_text("test"))
7676 text4 = binascii.hexlify(out4).decode('ascii')
77 self.failUnless(text4 == '000101817f')
77 self.assertTrue(text4 == '000101817f')
7878 in6 = "!2:::1000/1"
7979 rd6 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.APL, in6)
8080 out6 = rd6.to_digestable(dns.name.from_text("test"))
8181 text6 = binascii.hexlify(out6).decode('ascii')
82 self.failUnless(text6 == '0002018f000000000000000000000000000010')
82 self.assertTrue(text6 == '0002018f000000000000000000000000000010')
8383
8484 def test_TXT_conversions(self):
8585 t1 = dns.rdtypes.ANY.TXT.TXT(dns.rdataclass.IN, dns.rdatatype.TXT,
9090 'foo')
9191 t4 = dns.rdtypes.ANY.TXT.TXT(dns.rdataclass.IN, dns.rdatatype.TXT,
9292 ['foo'])
93 self.failUnless(t1 == t2)
94 self.failUnless(t1 == t2)
95 self.failUnless(t1 == t4)
93 self.assertTrue(t1 == t2)
94 self.assertTrue(t1 == t2)
95 self.assertTrue(t1 == t4)
9696
9797 if __name__ == '__main__':
9898 unittest.main()
149149 "SOA 14 1 86400 20130929021229 20130921230729 63571 example. CrnCu34EeeRz0fEhL9PLlwjpBKGYW8QjBjFQTwd+ViVLRAS8tNkcDwQE NhSV89NEjj7ze1a/JcCfcJ+/mZgnvH4NHLNg3Tf6KuLZsgs2I4kKQXEk 37oIHravPEOlGYNI")
150150
151151
152
153152 @unittest.skipUnless(dns.dnssec._have_pycrypto,
154153 "Pycryptodome cannot be imported")
155154 class DNSSECValidatorTestCase(unittest.TestCase):
156155
157 def testAbsoluteRSAGood(self): # type: () -> None
156 def testAbsoluteRSAGood(self): # type: () -> None
158157 dns.dnssec.validate(abs_soa, abs_soa_rrsig, abs_keys, None, when)
159158
160 def testDuplicateKeytag(self): # type: () -> None
159 def testDuplicateKeytag(self): # type: () -> None
161160 dns.dnssec.validate(abs_soa, abs_soa_rrsig, abs_keys_duplicate_keytag, None, when)
162161
163 def testAbsoluteRSABad(self): # type: () -> None
164 def bad(): # type: () -> None
162 def testAbsoluteRSABad(self): # type: () -> None
163 def bad(): # type: () -> None
165164 dns.dnssec.validate(abs_other_soa, abs_soa_rrsig, abs_keys, None,
166165 when)
167 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
168
169 def testRelativeRSAGood(self): # type: () -> None
166 self.assertRaises(dns.dnssec.ValidationFailure, bad)
167
168 def testRelativeRSAGood(self): # type: () -> None
170169 dns.dnssec.validate(rel_soa, rel_soa_rrsig, rel_keys,
171170 abs_dnspython_org, when)
172171
173 def testRelativeRSABad(self): # type: () -> None
174 def bad(): # type: () -> None
172 def testRelativeRSABad(self): # type: () -> None
173 def bad(): # type: () -> None
175174 dns.dnssec.validate(rel_other_soa, rel_soa_rrsig, rel_keys,
176175 abs_dnspython_org, when)
177 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
178
179 def testMakeSHA256DS(self): # type: () -> None
180 ds = dns.dnssec.make_ds(abs_dnspython_org, sep_key, 'SHA256')
181 self.failUnless(ds == good_ds)
182
183 def testAbsoluteDSAGood(self): # type: () -> None
176 self.assertRaises(dns.dnssec.ValidationFailure, bad)
177
178 def testAbsoluteDSAGood(self): # type: () -> None
184179 dns.dnssec.validate(abs_dsa_soa, abs_dsa_soa_rrsig, abs_dsa_keys, None,
185180 when2)
186181
187 def testAbsoluteDSABad(self): # type: () -> None
188 def bad(): # type: () -> None
182 def testAbsoluteDSABad(self): # type: () -> None
183 def bad(): # type: () -> None
189184 dns.dnssec.validate(abs_other_dsa_soa, abs_dsa_soa_rrsig,
190185 abs_dsa_keys, None, when2)
191 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
192
193 def testMakeExampleSHA1DS(self): # type: () -> None
194 ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA1')
195 self.failUnless(ds == example_ds_sha1)
196
197 def testMakeExampleSHA256DS(self): # type: () -> None
198 ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA256')
199 self.failUnless(ds == example_ds_sha256)
200
201 @unittest.skipUnless(dns.dnssec._have_ecdsa,
202 "python ECDSA cannot be imported")
203 def testAbsoluteECDSA256Good(self): # type: () -> None
186 self.assertRaises(dns.dnssec.ValidationFailure, bad)
187
188 @unittest.skipUnless(dns.dnssec._have_ecdsa,
189 "python ECDSA cannot be imported")
190 def testAbsoluteECDSA256Good(self): # type: () -> None
204191 dns.dnssec.validate(abs_ecdsa256_soa, abs_ecdsa256_soa_rrsig,
205192 abs_ecdsa256_keys, None, when3)
206193
207194 @unittest.skipUnless(dns.dnssec._have_ecdsa,
208195 "python ECDSA cannot be imported")
209 def testAbsoluteECDSA256Bad(self): # type: () -> None
210 def bad(): # type: () -> None
196 def testAbsoluteECDSA256Bad(self): # type: () -> None
197 def bad(): # type: () -> None
211198 dns.dnssec.validate(abs_other_ecdsa256_soa, abs_ecdsa256_soa_rrsig,
212199 abs_ecdsa256_keys, None, when3)
213 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
214
215 @unittest.skipUnless(dns.dnssec._have_ecdsa,
216 "python ECDSA cannot be imported")
217 def testAbsoluteECDSA384Good(self): # type: () -> None
200 self.assertRaises(dns.dnssec.ValidationFailure, bad)
201
202 @unittest.skipUnless(dns.dnssec._have_ecdsa,
203 "python ECDSA cannot be imported")
204 def testAbsoluteECDSA384Good(self): # type: () -> None
218205 dns.dnssec.validate(abs_ecdsa384_soa, abs_ecdsa384_soa_rrsig,
219206 abs_ecdsa384_keys, None, when4)
220207
221208 @unittest.skipUnless(dns.dnssec._have_ecdsa,
222209 "python ECDSA cannot be imported")
223 def testAbsoluteECDSA384Bad(self): # type: () -> None
224 def bad(): # type: () -> None
210 def testAbsoluteECDSA384Bad(self): # type: () -> None
211 def bad(): # type: () -> None
225212 dns.dnssec.validate(abs_other_ecdsa384_soa, abs_ecdsa384_soa_rrsig,
226213 abs_ecdsa384_keys, None, when4)
227 self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
214 self.assertRaises(dns.dnssec.ValidationFailure, bad)
215
216
217 class DNSSECMakeDSTestCase(unittest.TestCase):
218
219 def testMakeExampleSHA1DS(self): # type: () -> None
220 ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA1')
221 self.assertTrue(ds == example_ds_sha1)
222
223 def testMakeExampleSHA256DS(self): # type: () -> None
224 ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA256')
225 self.assertTrue(ds == example_ds_sha256)
226
227 def testMakeSHA256DS(self): # type: () -> None
228 ds = dns.dnssec.make_ds(abs_dnspython_org, sep_key, 'SHA256')
229 self.assertTrue(ds == good_ds)
228230
229231
230232 if __name__ == '__main__':
5353 data = io.getvalue()
5454 self.assertEqual(data, b'\x00\x01\x18\x00\x01\x02\x03')
5555
56 def testECSOption25(self):
57 opt = dns.edns.ECSOption('1.2.3.255', 25)
58 io = BytesIO()
59 opt.to_wire(io)
60 data = io.getvalue()
61 self.assertEqual(data, b'\x00\x01\x19\x00\x01\x02\x03\x80')
62
5663 def testECSOption_v6(self):
5764 opt = dns.edns.ECSOption('2001:4b98::1')
5865 io = BytesIO()
5966 opt.to_wire(io)
6067 data = io.getvalue()
6168 self.assertEqual(data, b'\x00\x02\x38\x00\x20\x01\x4b\x98\x00\x00\x00')
69
70 def testECSOption_from_text_valid(self):
71 ecs1 = dns.edns.ECSOption.from_text('1.2.3.4/24/0')
72 self.assertEqual(ecs1, dns.edns.ECSOption('1.2.3.4', 24, 0))
73
74 ecs2 = dns.edns.ECSOption.from_text('1.2.3.4/24')
75 self.assertEqual(ecs2, dns.edns.ECSOption('1.2.3.4', 24, 0))
76
77 ecs3 = dns.edns.ECSOption.from_text('ECS 1.2.3.4/24')
78 self.assertEqual(ecs3, dns.edns.ECSOption('1.2.3.4', 24, 0))
79
80 ecs4 = dns.edns.ECSOption.from_text('ECS 1.2.3.4/24/32')
81 self.assertEqual(ecs4, dns.edns.ECSOption('1.2.3.4', 24, 32))
82
83 ecs5 = dns.edns.ECSOption.from_text('2001:4b98::1/64/56')
84 self.assertEqual(ecs5, dns.edns.ECSOption('2001:4b98::1', 64, 56))
85
86 ecs6 = dns.edns.ECSOption.from_text('2001:4b98::1/64')
87 self.assertEqual(ecs6, dns.edns.ECSOption('2001:4b98::1', 64, 0))
88
89 ecs7 = dns.edns.ECSOption.from_text('ECS 2001:4b98::1/0')
90 self.assertEqual(ecs7, dns.edns.ECSOption('2001:4b98::1', 0, 0))
91
92 ecs8 = dns.edns.ECSOption.from_text('ECS 2001:4b98::1/64/128')
93 self.assertEqual(ecs8, dns.edns.ECSOption('2001:4b98::1', 64, 128))
94
95 def testECSOption_from_text_invalid(self):
96 with self.assertRaises(ValueError):
97 dns.edns.ECSOption.from_text('some random text 1.2.3.4/24/0 24')
98
99 with self.assertRaises(ValueError):
100 dns.edns.ECSOption.from_text('1.2.3.4/twentyfour')
101
102 with self.assertRaises(ValueError):
103 dns.edns.ECSOption.from_text('1.2.3.4/24/O') # <-- that's not a zero
104
105 with self.assertRaises(ValueError):
106 dns.edns.ECSOption.from_text('')
107
108 with self.assertRaises(ValueError):
109 dns.edns.ECSOption.from_text('1.2.3.4/2001:4b98::1/24')
2323 class FlagsTestCase(unittest.TestCase):
2424
2525 def test_rcode1(self):
26 self.failUnless(dns.rcode.from_text('FORMERR') == dns.rcode.FORMERR)
26 self.assertTrue(dns.rcode.from_text('FORMERR') == dns.rcode.FORMERR)
2727
2828 def test_rcode2(self):
29 self.failUnless(dns.rcode.to_text(dns.rcode.FORMERR) == "FORMERR")
29 self.assertTrue(dns.rcode.to_text(dns.rcode.FORMERR) == "FORMERR")
3030
3131 def test_rcode3(self):
32 self.failUnless(dns.rcode.to_flags(dns.rcode.FORMERR) == (1, 0))
32 self.assertTrue(dns.rcode.to_flags(dns.rcode.FORMERR) == (1, 0))
3333
3434 def test_rcode4(self):
35 self.failUnless(dns.rcode.to_flags(dns.rcode.BADVERS) == \
35 self.assertTrue(dns.rcode.to_flags(dns.rcode.BADVERS) == \
3636 (0, 0x01000000))
3737
3838 def test_rcode6(self):
39 self.failUnless(dns.rcode.from_flags(0, 0x01000000) == \
39 self.assertTrue(dns.rcode.from_flags(0, 0x01000000) == \
4040 dns.rcode.BADVERS)
4141
4242 def test_rcode7(self):
43 self.failUnless(dns.rcode.from_flags(5, 0) == dns.rcode.REFUSED)
43 self.assertTrue(dns.rcode.from_flags(5, 0) == dns.rcode.REFUSED)
4444
4545 def test_rcode8(self):
4646 def bad():
4747 dns.rcode.to_flags(4096)
48 self.failUnlessRaises(ValueError, bad)
48 self.assertRaises(ValueError, bad)
4949
5050 def test_flags1(self):
51 self.failUnless(dns.flags.from_text("RA RD AA QR") == \
51 self.assertTrue(dns.flags.from_text("RA RD AA QR") == \
5252 dns.flags.QR|dns.flags.AA|dns.flags.RD|dns.flags.RA)
5353
5454 def test_flags2(self):
5555 flags = dns.flags.QR|dns.flags.AA|dns.flags.RD|dns.flags.RA
56 self.failUnless(dns.flags.to_text(flags) == "QR AA RD RA")
56 self.assertTrue(dns.flags.to_text(flags) == "QR AA RD RA")
5757
5858
5959 if __name__ == '__main__':
2525 import dns.rdatatype
2626 import dns.rrset
2727 import dns.zone
28 from dns._compat import long
29
3028 import pprint
3129
3230
132130 $GENERATE 27-28 $.2 PTR zlb${-26}.oob
133131 """
134132
133 example_text11 = """$TTL 1h
134 @ 3600 IN SOA foo bar 1 2 3 4 5
135 @ 3600 IN NS ns1
136 @ 3600 IN NS ns2
137 bar.foo 300 IN MX 0 blaz.foo
138 ns1 3600 IN A 10.0.0.1
139 ns2 3600 IN A 10.0.0.2
140 $GENERATE 27-28 prefix-${0,3} A 10.0.0.$
141 """
142
143
135144 def _rdata_sort(a):
136145 return (a[0], a[2].rdclass, a[2].to_text())
137146
141150 def testFromText(self): # type: () -> None
142151 def bad(): # type: () -> None
143152 dns.zone.from_text(example_text, 'example.', relativize=True)
144 self.failUnlessRaises(dns.zone.NoSOA, bad)
153 self.assertRaises(dns.zone.NoSOA, bad)
145154
146155 def testFromText1(self): # type: () -> None
147156 def bad(): # type: () -> None
148157 dns.zone.from_text(example_text1, 'example.', relativize=True)
149 self.failUnlessRaises(dns.zone.NoSOA, bad)
158 self.assertRaises(dns.zone.NoSOA, bad)
150159
151160 def testIterateAllRdatas2(self): # type: () -> None
152161 z = dns.zone.from_text(example_text2, 'example.', relativize=True)
190199 '10.0.0.5'))]
191200
192201 exl.sort(key=_rdata_sort)
193 self.failUnless(l == exl)
202 self.assertTrue(l == exl)
194203
195204 def testIterateAllRdatas3(self): # type: () -> None
196205 z = dns.zone.from_text(example_text3, 'example.', relativize=True)
230239 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
231240 '10.0.0.8'))]
232241 exl.sort(key=_rdata_sort)
233 self.failUnless(l == exl)
242 self.assertTrue(l == exl)
234243 def testGenerate1(self): # type: () -> None
235244 z = dns.zone.from_text(example_text4, 'example.', relativize=True)
236245 l = list(z.iterate_rdatas())
237246 l.sort(key=_rdata_sort)
238247 exl = [(dns.name.from_text('@', None),
239 long(3600),
240 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
241 'ns1')),
242 (dns.name.from_text('@', None),
243 long(3600),
244 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
245 'ns2')),
246 (dns.name.from_text('@', None),
247 long(3600),
248 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
249 'foo bar 1 2 3 4 5')),
250 (dns.name.from_text('bar.foo', None),
251 long(300),
252 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
253 '0 blaz.foo')),
254 (dns.name.from_text('ns1', None),
255 long(3600),
256 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
257 '10.0.0.1')),
258 (dns.name.from_text('ns2', None),
259 long(3600),
248 3600,
249 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
250 'ns1')),
251 (dns.name.from_text('@', None),
252 3600,
253 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
254 'ns2')),
255 (dns.name.from_text('@', None),
256 3600,
257 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
258 'foo bar 1 2 3 4 5')),
259 (dns.name.from_text('bar.foo', None),
260 300,
261 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
262 '0 blaz.foo')),
263 (dns.name.from_text('ns1', None),
264 3600,
265 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
266 '10.0.0.1')),
267 (dns.name.from_text('ns2', None),
268 3600,
260269 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
261270 '10.0.0.2')),
262271
263272 (dns.name.from_text('wp-db01.services.mozilla.com', None),
264 long(0),
273 0,
265274 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
266275 'SERVER.FOOBAR.')),
267276
268277 (dns.name.from_text('wp-db02.services.mozilla.com', None),
269 long(0),
278 0,
270279 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
271280 'SERVER.FOOBAR.')),
272281
273282 (dns.name.from_text('wp-db03.services.mozilla.com', None),
274 long(0),
283 0,
275284 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
276285 'SERVER.FOOBAR.'))]
277286 exl.sort(key=_rdata_sort)
282291 l = list(z.iterate_rdatas())
283292 l.sort(key=_rdata_sort)
284293 exl = [(dns.name.from_text('@', None),
285 long(3600),
286 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
287 'ns1')),
288 (dns.name.from_text('@', None),
289 long(3600),
290 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
291 'ns2')),
292 (dns.name.from_text('@', None),
293 long(3600),
294 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
295 'foo bar 1 2 3 4 5')),
296 (dns.name.from_text('bar.foo', None),
297 long(300),
298 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
299 '0 blaz.foo')),
300 (dns.name.from_text('ns1', None),
301 long(3600),
302 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
303 '10.0.0.1')),
304 (dns.name.from_text('ns2', None),
305 long(3600),
306 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
307 '10.0.0.2')),
308
309 (dns.name.from_text('wp-db21.services.mozilla.com', None), long(0),
294 3600,
295 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
296 'ns1')),
297 (dns.name.from_text('@', None),
298 3600,
299 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
300 'ns2')),
301 (dns.name.from_text('@', None),
302 3600,
303 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
304 'foo bar 1 2 3 4 5')),
305 (dns.name.from_text('bar.foo', None),
306 300,
307 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
308 '0 blaz.foo')),
309 (dns.name.from_text('ns1', None),
310 3600,
311 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
312 '10.0.0.1')),
313 (dns.name.from_text('ns2', None),
314 3600,
315 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
316 '10.0.0.2')),
317
318 (dns.name.from_text('wp-db21.services.mozilla.com', None), 0,
310319 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
311320 'SERVER.FOOBAR.')),
312321
313 (dns.name.from_text('wp-db22.services.mozilla.com', None), long(0),
322 (dns.name.from_text('wp-db22.services.mozilla.com', None), 0,
314323 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
315324 'SERVER.FOOBAR.')),
316325
317 (dns.name.from_text('wp-db23.services.mozilla.com', None), long(0),
326 (dns.name.from_text('wp-db23.services.mozilla.com', None), 0,
318327 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
319328 'SERVER.FOOBAR.'))]
320329 exl.sort(key=_rdata_sort)
321 self.failUnless(l == exl)
330 self.assertTrue(l == exl)
322331
323332 def testGenerate3(self): # type: () -> None
324333 z = dns.zone.from_text(example_text6, 'example.', relativize=True)
326335 l.sort(key=_rdata_sort)
327336
328337 exl = [(dns.name.from_text('@', None),
329 long(3600),
330 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
331 'ns1')),
332 (dns.name.from_text('@', None),
333 long(3600),
334 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
335 'ns2')),
336 (dns.name.from_text('@', None),
337 long(3600),
338 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
339 'foo bar 1 2 3 4 5')),
340 (dns.name.from_text('bar.foo', None),
341 long(300),
342 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
343 '0 blaz.foo')),
344 (dns.name.from_text('ns1', None),
345 long(3600),
346 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
347 '10.0.0.1')),
348 (dns.name.from_text('ns2', None),
349 long(3600),
350 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
351 '10.0.0.2')),
352 (dns.name.from_text('wp-db21.services.mozilla.com', None), long(0),
338 3600,
339 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
340 'ns1')),
341 (dns.name.from_text('@', None),
342 3600,
343 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
344 'ns2')),
345 (dns.name.from_text('@', None),
346 3600,
347 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
348 'foo bar 1 2 3 4 5')),
349 (dns.name.from_text('bar.foo', None),
350 300,
351 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
352 '0 blaz.foo')),
353 (dns.name.from_text('ns1', None),
354 3600,
355 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
356 '10.0.0.1')),
357 (dns.name.from_text('ns2', None),
358 3600,
359 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
360 '10.0.0.2')),
361 (dns.name.from_text('wp-db21.services.mozilla.com', None), 0,
353362 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
354363 'SERVER.FOOBAR.')),
355364
356 (dns.name.from_text('wp-db22.services.mozilla.com', None), long(0),
365 (dns.name.from_text('wp-db22.services.mozilla.com', None), 0,
357366 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
358367 'SERVER.FOOBAR.')),
359368
360 (dns.name.from_text('wp-db23.services.mozilla.com', None), long(0),
369 (dns.name.from_text('wp-db23.services.mozilla.com', None), 0,
361370 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME,
362371 'SERVER.FOOBAR.'))]
363372 exl.sort(key=_rdata_sort)
364 self.failUnless(l == exl)
373 self.assertTrue(l == exl)
365374
366375 def testGenerate4(self): # type: () -> None
367376 z = dns.zone.from_text(example_text7, 'example.', relativize=True)
368377 l = list(z.iterate_rdatas())
369378 l.sort(key=_rdata_sort)
370379 exl = [(dns.name.from_text('@', None),
371 long(3600),
372 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
373 'ns1')),
374 (dns.name.from_text('@', None),
375 long(3600),
376 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
377 'ns2')),
378 (dns.name.from_text('@', None),
379 long(3600),
380 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
381 'foo bar 1 2 3 4 5')),
382 (dns.name.from_text('bar.foo', None),
383 long(300),
384 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
385 '0 blaz.foo')),
386 (dns.name.from_text('ns1', None),
387 long(3600),
388 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
389 '10.0.0.1')),
390 (dns.name.from_text('ns2', None),
391 long(3600),
392 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
393 '10.0.0.2')),
394
395 (dns.name.from_text('sync1.db', None), long(3600),
380 3600,
381 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
382 'ns1')),
383 (dns.name.from_text('@', None),
384 3600,
385 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
386 'ns2')),
387 (dns.name.from_text('@', None),
388 3600,
389 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
390 'foo bar 1 2 3 4 5')),
391 (dns.name.from_text('bar.foo', None),
392 300,
393 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
394 '0 blaz.foo')),
395 (dns.name.from_text('ns1', None),
396 3600,
397 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
398 '10.0.0.1')),
399 (dns.name.from_text('ns2', None),
400 3600,
401 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
402 '10.0.0.2')),
403
404 (dns.name.from_text('sync1.db', None), 3600,
396405 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
397406 '10.10.16.0')),
398407
399 (dns.name.from_text('sync2.db', None), long(3600),
408 (dns.name.from_text('sync2.db', None), 3600,
400409 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
401410 '10.10.16.0')),
402411
403 (dns.name.from_text('sync3.db', None), long(3600),
412 (dns.name.from_text('sync3.db', None), 3600,
404413 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
405414 '10.10.16.0'))]
406415 exl.sort(key=_rdata_sort)
407 self.failUnless(l == exl)
416 self.assertTrue(l == exl)
408417
409418 def testGenerate6(self): # type: () -> None
410419 z = dns.zone.from_text(example_text9, 'example.', relativize=True)
411420 l = list(z.iterate_rdatas())
412421 l.sort(key=_rdata_sort)
413422 exl = [(dns.name.from_text('@', None),
414 long(3600),
415 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
416 'ns1')),
417 (dns.name.from_text('@', None),
418 long(3600),
419 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
420 'ns2')),
421 (dns.name.from_text('@', None),
422 long(3600),
423 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
424 'foo bar 1 2 3 4 5')),
425 (dns.name.from_text('bar.foo', None),
426 long(300),
427 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
428 '0 blaz.foo')),
429 (dns.name.from_text('ns1', None),
430 long(3600),
431 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
432 '10.0.0.1')),
433 (dns.name.from_text('ns2', None),
434 long(3600),
435 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
436 '10.0.0.2')),
437
438 (dns.name.from_text('wp-db01', None), long(3600),
423 3600,
424 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
425 'ns1')),
426 (dns.name.from_text('@', None),
427 3600,
428 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
429 'ns2')),
430 (dns.name.from_text('@', None),
431 3600,
432 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
433 'foo bar 1 2 3 4 5')),
434 (dns.name.from_text('bar.foo', None),
435 300,
436 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
437 '0 blaz.foo')),
438 (dns.name.from_text('ns1', None),
439 3600,
440 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
441 '10.0.0.1')),
442 (dns.name.from_text('ns2', None),
443 3600,
444 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
445 '10.0.0.2')),
446
447 (dns.name.from_text('wp-db01', None), 3600,
439448 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
440449 '10.10.16.0')),
441 (dns.name.from_text('wp-db02', None), long(3600),
450 (dns.name.from_text('wp-db02', None), 3600,
442451 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
443452 '10.10.16.0')),
444453
445 (dns.name.from_text('sync1.db', None), long(3600),
454 (dns.name.from_text('sync1.db', None), 3600,
446455 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
447456 '10.10.16.0')),
448457
449 (dns.name.from_text('sync2.db', None), long(3600),
458 (dns.name.from_text('sync2.db', None), 3600,
450459 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
451460 '10.10.16.0')),
452461
453 (dns.name.from_text('sync3.db', None), long(3600),
462 (dns.name.from_text('sync3.db', None), 3600,
454463 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
455464 '10.10.16.0'))]
456465 exl.sort(key=_rdata_sort)
457 self.failUnless(l == exl)
466 self.assertTrue(l == exl)
458467
459468 def testGenerate7(self): # type: () -> None
460469 z = dns.zone.from_text(example_text10, 'example.', relativize=True)
461470 l = list(z.iterate_rdatas())
462471 l.sort(key=_rdata_sort)
463472 exl = [(dns.name.from_text('@', None),
464 long(3600),
465 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
466 'ns1')),
467 (dns.name.from_text('@', None),
468 long(3600),
469 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
470 'ns2')),
471 (dns.name.from_text('@', None),
472 long(3600),
473 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
474 'foo bar 1 2 3 4 5')),
475 (dns.name.from_text('bar.foo', None),
476 long(300),
477 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
478 '0 blaz.foo')),
479 (dns.name.from_text('ns1', None),
480 long(3600),
481 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
482 '10.0.0.1')),
483 (dns.name.from_text('ns2', None),
484 long(3600),
485 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
486 '10.0.0.2')),
487
488 (dns.name.from_text('27.2', None), long(3600),
473 3600,
474 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
475 'ns1')),
476 (dns.name.from_text('@', None),
477 3600,
478 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
479 'ns2')),
480 (dns.name.from_text('@', None),
481 3600,
482 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
483 'foo bar 1 2 3 4 5')),
484 (dns.name.from_text('bar.foo', None),
485 300,
486 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
487 '0 blaz.foo')),
488 (dns.name.from_text('ns1', None),
489 3600,
490 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
491 '10.0.0.1')),
492 (dns.name.from_text('ns2', None),
493 3600,
494 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
495 '10.0.0.2')),
496
497 (dns.name.from_text('27.2', None), 3600,
489498 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR,
490499 'zlb1.oob')),
491500
492 (dns.name.from_text('28.2', None), long(3600),
501 (dns.name.from_text('28.2', None), 3600,
493502 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR,
494503 'zlb2.oob'))]
495504
496505 exl.sort(key=_rdata_sort)
497 self.failUnless(l == exl)
506 self.assertTrue(l == exl)
507
508 def testGenerate8(self): # type: () -> None
509 z = dns.zone.from_text(example_text11, 'example.', relativize=True)
510 l = list(z.iterate_rdatas())
511 l.sort(key=_rdata_sort)
512 exl = [(dns.name.from_text('@', None),
513 3600,
514 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
515 'ns1')),
516 (dns.name.from_text('@', None),
517 3600,
518 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,
519 'ns2')),
520 (dns.name.from_text('@', None),
521 3600,
522 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA,
523 'foo bar 1 2 3 4 5')),
524 (dns.name.from_text('bar.foo', None),
525 300,
526 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX,
527 '0 blaz.foo')),
528
529 (dns.name.from_text('prefix-027', None), 3600,
530 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
531 '10.0.0.27')),
532
533 (dns.name.from_text('prefix-028', None), 3600,
534 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
535 '10.0.0.28')),
536
537 (dns.name.from_text('ns1', None),
538 3600,
539 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
540 '10.0.0.1')),
541 (dns.name.from_text('ns2', None),
542 3600,
543 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
544 '10.0.0.2'))]
545
546 exl.sort(key=_rdata_sort)
547 self.assertTrue(l == exl)
498548
499549
500550 if __name__ == '__main__':
2323 import dns.name
2424 import dns.rdataclass
2525 import dns.rdatatype
26 from dns._compat import xrange
2726
2827 query_text = """id 1234
2928 opcode QUERY
9695 def test_comparison_eq1(self):
9796 q1 = dns.message.from_text(query_text)
9897 q2 = dns.message.from_text(query_text)
99 self.failUnless(q1 == q2)
98 self.assertTrue(q1 == q2)
10099
101100 def test_comparison_ne1(self):
102101 q1 = dns.message.from_text(query_text)
103102 q2 = dns.message.from_text(query_text)
104103 q2.id = 10
105 self.failUnless(q1 != q2)
104 self.assertTrue(q1 != q2)
106105
107106 def test_comparison_ne2(self):
108107 q1 = dns.message.from_text(query_text)
109108 q2 = dns.message.from_text(query_text)
110109 q2.question = []
111 self.failUnless(q1 != q2)
110 self.assertTrue(q1 != q2)
112111
113112 def test_comparison_ne3(self):
114113 q1 = dns.message.from_text(query_text)
115 self.failUnless(q1 != 1)
114 self.assertTrue(q1 != 1)
116115
117116 def test_EDNS_to_wire1(self):
118117 q = dns.message.from_text(query_text)
119118 w = q.to_wire()
120 self.failUnless(w == goodwire)
119 self.assertTrue(w == goodwire)
121120
122121 def test_EDNS_from_wire1(self):
123122 m = dns.message.from_wire(goodwire)
126125 def test_EDNS_to_wire2(self):
127126 q = dns.message.from_text(query_text_2)
128127 w = q.to_wire()
129 self.failUnless(w == goodwire3)
128 self.assertTrue(w == goodwire3)
130129
131130 def test_EDNS_from_wire2(self):
132131 m = dns.message.from_wire(goodwire3)
133 self.failUnless(str(m) == query_text_2)
132 self.assertTrue(str(m) == query_text_2)
134133
135134 def test_TooBig(self):
136135 def bad():
137136 q = dns.message.from_text(query_text)
138 for i in xrange(0, 25):
137 for i in range(0, 25):
139138 rrset = dns.rrset.from_text('foo%d.' % i, 3600,
140139 dns.rdataclass.IN,
141140 dns.rdatatype.A,
142141 '10.0.0.%d' % i)
143142 q.additional.append(rrset)
144143 q.to_wire(max_size=512)
145 self.failUnlessRaises(dns.exception.TooBig, bad)
144 self.assertRaises(dns.exception.TooBig, bad)
146145
147146 def test_answer1(self):
148147 a = dns.message.from_text(answer_text)
149148 wire = a.to_wire(want_shuffle=False)
150 self.failUnless(wire == goodwire2)
149 self.assertTrue(wire == goodwire2)
151150
152151 def test_TrailingJunk(self):
153152 def bad():
154153 badwire = goodwire + b'\x00'
155154 dns.message.from_wire(badwire)
156 self.failUnlessRaises(dns.message.TrailingJunk, bad)
155 self.assertRaises(dns.message.TrailingJunk, bad)
157156
158157 def test_ShortHeader(self):
159158 def bad():
160159 badwire = b'\x00' * 11
161160 dns.message.from_wire(badwire)
162 self.failUnlessRaises(dns.message.ShortHeader, bad)
161 self.assertRaises(dns.message.ShortHeader, bad)
163162
164163 def test_RespondingToResponse(self):
165164 def bad():
166165 q = dns.message.make_query('foo', 'A')
167166 r1 = dns.message.make_response(q)
168167 dns.message.make_response(r1)
169 self.failUnlessRaises(dns.exception.FormError, bad)
168 self.assertRaises(dns.exception.FormError, bad)
170169
171170 def test_ExtendedRcodeSetting(self):
172171 m = dns.message.make_query('foo', 'A')
173172 m.set_rcode(4095)
174 self.failUnless(m.rcode() == 4095)
173 self.assertTrue(m.rcode() == 4095)
175174 m.set_rcode(2)
176 self.failUnless(m.rcode() == 2)
175 self.assertTrue(m.rcode() == 2)
177176
178177 def test_EDNSVersionCoherence(self):
179178 m = dns.message.make_query('foo', 'A')
180179 m.use_edns(1)
181 self.failUnless((m.ednsflags >> 16) & 0xFF == 1)
180 self.assertTrue((m.ednsflags >> 16) & 0xFF == 1)
182181
183182 def test_SettingNoEDNSOptionsImpliesNoEDNS(self):
184183 m = dns.message.make_query('foo', 'A')
185 self.failUnless(m.edns == -1)
184 self.assertTrue(m.edns == -1)
186185
187186 def test_SettingEDNSFlagsImpliesEDNS(self):
188187 m = dns.message.make_query('foo', 'A', ednsflags=dns.flags.DO)
189 self.failUnless(m.edns == 0)
188 self.assertTrue(m.edns == 0)
190189
191190 def test_SettingEDNSPayloadImpliesEDNS(self):
192191 m = dns.message.make_query('foo', 'A', payload=4096)
193 self.failUnless(m.edns == 0)
192 self.assertTrue(m.edns == 0)
194193
195194 def test_SettingEDNSRequestPayloadImpliesEDNS(self):
196195 m = dns.message.make_query('foo', 'A', request_payload=4096)
197 self.failUnless(m.edns == 0)
196 self.assertTrue(m.edns == 0)
198197
199198 def test_SettingOptionsImpliesEDNS(self):
200199 m = dns.message.make_query('foo', 'A', options=[])
201 self.failUnless(m.edns == 0)
200 self.assertTrue(m.edns == 0)
202201
203202 def test_FindRRset(self):
204203 a = dns.message.from_text(answer_text)
206205 rrs1 = a.find_rrset(a.answer, n, dns.rdataclass.IN, dns.rdatatype.SOA)
207206 rrs2 = a.find_rrset(dns.message.ANSWER, n, dns.rdataclass.IN,
208207 dns.rdatatype.SOA)
209 self.failUnless(rrs1 == rrs2)
208 self.assertTrue(rrs1 == rrs2)
209
210 def test_CleanTruncated(self):
211 def bad():
212 a = dns.message.from_text(answer_text)
213 a.flags |= dns.flags.TC
214 wire = a.to_wire(want_shuffle=False)
215 dns.message.from_wire(wire)
216 self.assertRaises(dns.message.Truncated, bad)
217
218 def test_MessyTruncated(self):
219 def bad():
220 a = dns.message.from_text(answer_text)
221 a.flags |= dns.flags.TC
222 wire = a.to_wire(want_shuffle=False)
223 dns.message.from_wire(wire[:-3])
224 self.assertRaises(dns.message.Truncated, bad)
210225
211226 if __name__ == '__main__':
212227 unittest.main()
4747
4848 def testFromTextRel4(self):
4949 n = dns.name.from_text('@', origin=None)
50 self.failUnless(n == dns.name.empty)
50 self.assertTrue(n == dns.name.empty)
5151
5252 def testFromTextRel5(self):
5353 n = dns.name.from_text('@', origin=self.origin)
54 self.failUnless(n == self.origin)
54 self.assertTrue(n == self.origin)
5555
5656 def testFromTextAbs1(self):
5757 n = dns.name.from_text('foo.bar.')
100100 def testImmutable1(self):
101101 def bad():
102102 self.origin.labels = ()
103 self.failUnlessRaises(TypeError, bad)
103 self.assertRaises(TypeError, bad)
104104
105105 def testImmutable2(self):
106106 def bad():
107107 self.origin.labels[0] = 'foo'
108 self.failUnlessRaises(TypeError, bad)
108 self.assertRaises(TypeError, bad)
109109
110110 def testAbs1(self):
111 self.failUnless(dns.name.root.is_absolute())
111 self.assertTrue(dns.name.root.is_absolute())
112112
113113 def testAbs2(self):
114 self.failUnless(not dns.name.empty.is_absolute())
114 self.assertTrue(not dns.name.empty.is_absolute())
115115
116116 def testAbs3(self):
117 self.failUnless(self.origin.is_absolute())
117 self.assertTrue(self.origin.is_absolute())
118118
119119 def testAbs4(self):
120120 n = dns.name.from_text('foo', origin=None)
121 self.failUnless(not n.is_absolute())
121 self.assertTrue(not n.is_absolute())
122122
123123 def testWild1(self):
124124 n = dns.name.from_text('*.foo', origin=None)
125 self.failUnless(n.is_wild())
125 self.assertTrue(n.is_wild())
126126
127127 def testWild2(self):
128128 n = dns.name.from_text('*a.foo', origin=None)
129 self.failUnless(not n.is_wild())
129 self.assertTrue(not n.is_wild())
130130
131131 def testWild3(self):
132132 n = dns.name.from_text('a.*.foo', origin=None)
133 self.failUnless(not n.is_wild())
133 self.assertTrue(not n.is_wild())
134134
135135 def testWild4(self):
136 self.failUnless(not dns.name.root.is_wild())
136 self.assertTrue(not dns.name.root.is_wild())
137137
138138 def testWild5(self):
139 self.failUnless(not dns.name.empty.is_wild())
139 self.assertTrue(not dns.name.empty.is_wild())
140140
141141 def testHash1(self):
142142 n1 = dns.name.from_text('fOo.COM')
146146 def testCompare1(self):
147147 n1 = dns.name.from_text('a')
148148 n2 = dns.name.from_text('b')
149 self.failUnless(n1 < n2)
150 self.failUnless(n2 > n1)
149 self.assertTrue(n1 < n2)
150 self.assertTrue(n2 > n1)
151151
152152 def testCompare2(self):
153153 n1 = dns.name.from_text('')
154154 n2 = dns.name.from_text('b')
155 self.failUnless(n1 < n2)
156 self.failUnless(n2 > n1)
155 self.assertTrue(n1 < n2)
156 self.assertTrue(n2 > n1)
157157
158158 def testCompare3(self):
159 self.failUnless(dns.name.empty < dns.name.root)
160 self.failUnless(dns.name.root > dns.name.empty)
159 self.assertTrue(dns.name.empty < dns.name.root)
160 self.assertTrue(dns.name.root > dns.name.empty)
161161
162162 def testCompare4(self):
163 self.failUnless(dns.name.root != 1)
163 self.assertTrue(dns.name.root != 1)
164164
165165 def testSubdomain1(self):
166 self.failUnless(not dns.name.empty.is_subdomain(dns.name.root))
166 self.assertTrue(not dns.name.empty.is_subdomain(dns.name.root))
167167
168168 def testSubdomain2(self):
169 self.failUnless(not dns.name.root.is_subdomain(dns.name.empty))
169 self.assertTrue(not dns.name.root.is_subdomain(dns.name.empty))
170170
171171 def testSubdomain3(self):
172172 n = dns.name.from_text('foo', origin=self.origin)
173 self.failUnless(n.is_subdomain(self.origin))
173 self.assertTrue(n.is_subdomain(self.origin))
174174
175175 def testSubdomain4(self):
176176 n = dns.name.from_text('foo', origin=self.origin)
177 self.failUnless(n.is_subdomain(dns.name.root))
177 self.assertTrue(n.is_subdomain(dns.name.root))
178178
179179 def testSubdomain5(self):
180180 n = dns.name.from_text('foo', origin=self.origin)
181 self.failUnless(n.is_subdomain(n))
181 self.assertTrue(n.is_subdomain(n))
182182
183183 def testSuperdomain1(self):
184 self.failUnless(not dns.name.empty.is_superdomain(dns.name.root))
184 self.assertTrue(not dns.name.empty.is_superdomain(dns.name.root))
185185
186186 def testSuperdomain2(self):
187 self.failUnless(not dns.name.root.is_superdomain(dns.name.empty))
187 self.assertTrue(not dns.name.root.is_superdomain(dns.name.empty))
188188
189189 def testSuperdomain3(self):
190190 n = dns.name.from_text('foo', origin=self.origin)
191 self.failUnless(self.origin.is_superdomain(n))
191 self.assertTrue(self.origin.is_superdomain(n))
192192
193193 def testSuperdomain4(self):
194194 n = dns.name.from_text('foo', origin=self.origin)
195 self.failUnless(dns.name.root.is_superdomain(n))
195 self.assertTrue(dns.name.root.is_superdomain(n))
196196
197197 def testSuperdomain5(self):
198198 n = dns.name.from_text('foo', origin=self.origin)
199 self.failUnless(n.is_superdomain(n))
199 self.assertTrue(n.is_superdomain(n))
200200
201201 def testCanonicalize1(self):
202202 n = dns.name.from_text('FOO.bar', origin=self.origin)
234234 def testToText7(self):
235235 n = dns.name.from_text(r'FOO\.bar', origin=None)
236236 t = n.to_text()
237 self.assertEqual(t, 'FOO\.bar')
237 self.assertEqual(t, r'FOO\.bar')
238238
239239 def testToText8(self):
240240 n = dns.name.from_text(r'\070OO\.bar', origin=None)
241241 t = n.to_text()
242 self.assertEqual(t, 'FOO\.bar')
242 self.assertEqual(t, r'FOO\.bar')
243243
244244 def testToText9(self):
245245 n = dns.name.from_text('FOO bar', origin=None)
254254 t = dns.name.root.to_unicode()
255255 self.assertEqual(t, '.')
256256
257 def testToText12(self):
258 n = dns.name.from_text(r'a\.b.c')
259 t = n.to_unicode()
260 self.assertEqual(t, r'a\.b.c.')
261
262 def testToText13(self):
263 n = dns.name.from_text(r'\150\151\152\153\154\155\156\157\158\159.')
264 t = n.to_text()
265 self.assertEqual(t, r'\150\151\152\153\154\155\156\157\158\159.')
266
267 def testToText14(self):
268 # Something that didn't start as unicode should go to escapes and not
269 # raise due to interpreting arbitrary binary DNS labels as UTF-8.
270 n = dns.name.from_text(r'\150\151\152\153\154\155\156\157\158\159.')
271 t = n.to_unicode()
272 self.assertEqual(t, r'\150\151\152\153\154\155\156\157\158\159.')
273
257274 def testSlice1(self):
258275 n = dns.name.from_text(r'a.b.c.', origin=None)
259276 s = n[:]
272289 def testEmptyLabel1(self):
273290 def bad():
274291 dns.name.Name(['a', '', 'b'])
275 self.failUnlessRaises(dns.name.EmptyLabel, bad)
292 self.assertRaises(dns.name.EmptyLabel, bad)
276293
277294 def testEmptyLabel2(self):
278295 def bad():
279296 dns.name.Name(['', 'b'])
280 self.failUnlessRaises(dns.name.EmptyLabel, bad)
297 self.assertRaises(dns.name.EmptyLabel, bad)
281298
282299 def testEmptyLabel3(self):
283300 n = dns.name.Name(['b', ''])
284 self.failUnless(n)
301 self.assertTrue(n)
285302
286303 def testLongLabel(self):
287304 n = dns.name.Name(['a' * 63])
288 self.failUnless(n)
305 self.assertTrue(n)
289306
290307 def testLabelTooLong(self):
291308 def bad():
292309 dns.name.Name(['a' * 64, 'b'])
293 self.failUnlessRaises(dns.name.LabelTooLong, bad)
310 self.assertRaises(dns.name.LabelTooLong, bad)
294311
295312 def testLongName(self):
296313 n = dns.name.Name(['a' * 63, 'a' * 63, 'a' * 63, 'a' * 62])
297 self.failUnless(n)
314 self.assertTrue(n)
298315
299316 def testNameTooLong(self):
300317 def bad():
301318 dns.name.Name(['a' * 63, 'a' * 63, 'a' * 63, 'a' * 63])
302 self.failUnlessRaises(dns.name.NameTooLong, bad)
319 self.assertRaises(dns.name.NameTooLong, bad)
303320
304321 def testConcat1(self):
305322 n1 = dns.name.Name(['a', 'b'])
306323 n2 = dns.name.Name(['c', 'd'])
307324 e = dns.name.Name(['a', 'b', 'c', 'd'])
308325 r = n1 + n2
309 self.failUnless(r == e)
326 self.assertTrue(r == e)
310327
311328 def testConcat2(self):
312329 n1 = dns.name.Name(['a', 'b'])
313330 n2 = dns.name.Name([])
314331 e = dns.name.Name(['a', 'b'])
315332 r = n1 + n2
316 self.failUnless(r == e)
333 self.assertTrue(r == e)
317334
318335 def testConcat3(self):
319336 n1 = dns.name.Name([])
320337 n2 = dns.name.Name(['a', 'b'])
321338 e = dns.name.Name(['a', 'b'])
322339 r = n1 + n2
323 self.failUnless(r == e)
340 self.assertTrue(r == e)
324341
325342 def testConcat4(self):
326343 n1 = dns.name.Name(['a', 'b', ''])
327344 n2 = dns.name.Name([])
328345 e = dns.name.Name(['a', 'b', ''])
329346 r = n1 + n2
330 self.failUnless(r == e)
347 self.assertTrue(r == e)
331348
332349 def testConcat5(self):
333350 n1 = dns.name.Name(['a', 'b'])
334351 n2 = dns.name.Name(['c', ''])
335352 e = dns.name.Name(['a', 'b', 'c', ''])
336353 r = n1 + n2
337 self.failUnless(r == e)
354 self.assertTrue(r == e)
338355
339356 def testConcat6(self):
340357 def bad():
341358 n1 = dns.name.Name(['a', 'b', ''])
342359 n2 = dns.name.Name(['c'])
343360 return n1 + n2
344 self.failUnlessRaises(dns.name.AbsoluteConcatenation, bad)
361 self.assertRaises(dns.name.AbsoluteConcatenation, bad)
345362
346363 def testBadEscape(self):
347364 def bad():
348365 n = dns.name.from_text(r'a.b\0q1.c.')
349366 print(n)
350 self.failUnlessRaises(dns.name.BadEscape, bad)
367 self.assertRaises(dns.name.BadEscape, bad)
351368
352369 def testDigestable1(self):
353370 n = dns.name.from_text('FOO.bar')
359376 n2 = dns.name.from_text('foo.BAR.')
360377 d1 = n1.to_digestable()
361378 d2 = n2.to_digestable()
362 self.failUnless(d1 == d2)
379 self.assertTrue(d1 == d2)
363380
364381 def testDigestable3(self):
365382 d = dns.name.root.to_digestable()
374391 def bad():
375392 n = dns.name.from_text('FOO.bar', None)
376393 n.to_digestable()
377 self.failUnlessRaises(dns.name.NeedAbsoluteNameOrOrigin, bad)
394 self.assertRaises(dns.name.NeedAbsoluteNameOrOrigin, bad)
378395
379396 def testToWire1(self):
380397 n = dns.name.from_text('FOO.bar')
430447 f = BytesIO()
431448 compress = {} # type: Dict[dns.name.Name,int]
432449 n.to_wire(f, compress)
433 self.failUnlessRaises(dns.name.NeedAbsoluteNameOrOrigin, bad)
450 self.assertRaises(dns.name.NeedAbsoluteNameOrOrigin, bad)
434451
435452 def testSplit1(self):
436453 n = dns.name.from_text('foo.bar.')
437454 (prefix, suffix) = n.split(2)
438455 ep = dns.name.from_text('foo', None)
439456 es = dns.name.from_text('bar.', None)
440 self.failUnless(prefix == ep and suffix == es)
457 self.assertTrue(prefix == ep and suffix == es)
441458
442459 def testSplit2(self):
443460 n = dns.name.from_text('foo.bar.')
444461 (prefix, suffix) = n.split(1)
445462 ep = dns.name.from_text('foo.bar', None)
446463 es = dns.name.from_text('.', None)
447 self.failUnless(prefix == ep and suffix == es)
464 self.assertTrue(prefix == ep and suffix == es)
448465
449466 def testSplit3(self):
450467 n = dns.name.from_text('foo.bar.')
451468 (prefix, suffix) = n.split(0)
452469 ep = dns.name.from_text('foo.bar.', None)
453470 es = dns.name.from_text('', None)
454 self.failUnless(prefix == ep and suffix == es)
471 self.assertTrue(prefix == ep and suffix == es)
455472
456473 def testSplit4(self):
457474 n = dns.name.from_text('foo.bar.')
458475 (prefix, suffix) = n.split(3)
459476 ep = dns.name.from_text('', None)
460477 es = dns.name.from_text('foo.bar.', None)
461 self.failUnless(prefix == ep and suffix == es)
478 self.assertTrue(prefix == ep and suffix == es)
462479
463480 def testBadSplit1(self):
464481 def bad():
465482 n = dns.name.from_text('foo.bar.')
466483 n.split(-1)
467 self.failUnlessRaises(ValueError, bad)
484 self.assertRaises(ValueError, bad)
468485
469486 def testBadSplit2(self):
470487 def bad():
471488 n = dns.name.from_text('foo.bar.')
472489 n.split(4)
473 self.failUnlessRaises(ValueError, bad)
490 self.assertRaises(ValueError, bad)
474491
475492 def testRelativize1(self):
476493 n = dns.name.from_text('a.foo.bar.', None)
477494 o = dns.name.from_text('bar.', None)
478495 e = dns.name.from_text('a.foo', None)
479 self.failUnless(n.relativize(o) == e)
496 self.assertTrue(n.relativize(o) == e)
480497
481498 def testRelativize2(self):
482499 n = dns.name.from_text('a.foo.bar.', None)
483500 o = n
484501 e = dns.name.empty
485 self.failUnless(n.relativize(o) == e)
502 self.assertTrue(n.relativize(o) == e)
486503
487504 def testRelativize3(self):
488505 n = dns.name.from_text('a.foo.bar.', None)
489506 o = dns.name.from_text('blaz.', None)
490507 e = n
491 self.failUnless(n.relativize(o) == e)
508 self.assertTrue(n.relativize(o) == e)
492509
493510 def testRelativize4(self):
494511 n = dns.name.from_text('a.foo', None)
495512 o = dns.name.root
496513 e = n
497 self.failUnless(n.relativize(o) == e)
514 self.assertTrue(n.relativize(o) == e)
498515
499516 def testDerelativize1(self):
500517 n = dns.name.from_text('a.foo', None)
501518 o = dns.name.from_text('bar.', None)
502519 e = dns.name.from_text('a.foo.bar.', None)
503 self.failUnless(n.derelativize(o) == e)
520 self.assertTrue(n.derelativize(o) == e)
504521
505522 def testDerelativize2(self):
506523 n = dns.name.empty
507524 o = dns.name.from_text('a.foo.bar.', None)
508525 e = o
509 self.failUnless(n.derelativize(o) == e)
526 self.assertTrue(n.derelativize(o) == e)
510527
511528 def testDerelativize3(self):
512529 n = dns.name.from_text('a.foo.bar.', None)
513530 o = dns.name.from_text('blaz.', None)
514531 e = n
515 self.failUnless(n.derelativize(o) == e)
532 self.assertTrue(n.derelativize(o) == e)
516533
517534 def testChooseRelativity1(self):
518535 n = dns.name.from_text('a.foo.bar.', None)
519536 o = dns.name.from_text('bar.', None)
520537 e = dns.name.from_text('a.foo', None)
521 self.failUnless(n.choose_relativity(o, True) == e)
538 self.assertTrue(n.choose_relativity(o, True) == e)
522539
523540 def testChooseRelativity2(self):
524541 n = dns.name.from_text('a.foo.bar.', None)
525542 o = dns.name.from_text('bar.', None)
526543 e = n
527 self.failUnless(n.choose_relativity(o, False) == e)
544 self.assertTrue(n.choose_relativity(o, False) == e)
528545
529546 def testChooseRelativity3(self):
530547 n = dns.name.from_text('a.foo', None)
531548 o = dns.name.from_text('bar.', None)
532549 e = dns.name.from_text('a.foo.bar.', None)
533 self.failUnless(n.choose_relativity(o, False) == e)
550 self.assertTrue(n.choose_relativity(o, False) == e)
534551
535552 def testChooseRelativity4(self):
536553 n = dns.name.from_text('a.foo', None)
537554 o = None
538555 e = n
539 self.failUnless(n.choose_relativity(o, True) == e)
556 self.assertTrue(n.choose_relativity(o, True) == e)
540557
541558 def testChooseRelativity5(self):
542559 n = dns.name.from_text('a.foo', None)
543560 o = None
544561 e = n
545 self.failUnless(n.choose_relativity(o, False) == e)
562 self.assertTrue(n.choose_relativity(o, False) == e)
546563
547564 def testChooseRelativity6(self):
548565 n = dns.name.from_text('a.foo.', None)
549566 o = None
550567 e = n
551 self.failUnless(n.choose_relativity(o, True) == e)
568 self.assertTrue(n.choose_relativity(o, True) == e)
552569
553570 def testChooseRelativity7(self):
554571 n = dns.name.from_text('a.foo.', None)
555572 o = None
556573 e = n
557 self.failUnless(n.choose_relativity(o, False) == e)
574 self.assertTrue(n.choose_relativity(o, False) == e)
558575
559576 def testFromWire1(self):
560577 w = b'\x03foo\x00\xc0\x00'
564581 en2 = en1
565582 ecused1 = 5
566583 ecused2 = 2
567 self.failUnless(n1 == en1 and cused1 == ecused1 and \
584 self.assertTrue(n1 == en1 and cused1 == ecused1 and \
568585 n2 == en2 and cused2 == ecused2)
569586
570587 def testFromWire2(self):
581598 ecused1 = 5
582599 ecused2 = 4
583600 ecused3 = 4
584 self.failUnless(n1 == en1 and cused1 == ecused1 and \
601 self.assertTrue(n1 == en1 and cused1 == ecused1 and \
585602 n2 == en2 and cused2 == ecused2 and \
586603 n3 == en3 and cused3 == ecused3)
587604
589606 def bad():
590607 w = b'\x03foo\xc0\x04'
591608 dns.name.from_wire(w, 0)
592 self.failUnlessRaises(dns.name.BadPointer, bad)
609 self.assertRaises(dns.name.BadPointer, bad)
593610
594611 def testBadFromWire2(self):
595612 def bad():
596613 w = b'\x03foo\xc0\x05'
597614 dns.name.from_wire(w, 0)
598 self.failUnlessRaises(dns.name.BadPointer, bad)
615 self.assertRaises(dns.name.BadPointer, bad)
599616
600617 def testBadFromWire3(self):
601618 def bad():
602619 w = b'\xbffoo'
603620 dns.name.from_wire(w, 0)
604 self.failUnlessRaises(dns.name.BadLabelType, bad)
621 self.assertRaises(dns.name.BadLabelType, bad)
605622
606623 def testBadFromWire4(self):
607624 def bad():
608625 w = b'\x41foo'
609626 dns.name.from_wire(w, 0)
610 self.failUnlessRaises(dns.name.BadLabelType, bad)
627 self.assertRaises(dns.name.BadLabelType, bad)
611628
612629 def testParent1(self):
613630 n = dns.name.from_text('foo.bar.')
614 self.failUnless(n.parent() == dns.name.from_text('bar.'))
615 self.failUnless(n.parent().parent() == dns.name.root)
631 self.assertTrue(n.parent() == dns.name.from_text('bar.'))
632 self.assertTrue(n.parent().parent() == dns.name.root)
616633
617634 def testParent2(self):
618635 n = dns.name.from_text('foo.bar', None)
619 self.failUnless(n.parent() == dns.name.from_text('bar', None))
620 self.failUnless(n.parent().parent() == dns.name.empty)
636 self.assertTrue(n.parent() == dns.name.from_text('bar', None))
637 self.assertTrue(n.parent().parent() == dns.name.empty)
621638
622639 def testParent3(self):
623640 def bad():
624641 n = dns.name.root
625642 n.parent()
626 self.failUnlessRaises(dns.name.NoParent, bad)
643 self.assertRaises(dns.name.NoParent, bad)
627644
628645 def testParent4(self):
629646 def bad():
630647 n = dns.name.empty
631648 n.parent()
632 self.failUnlessRaises(dns.name.NoParent, bad)
649 self.assertRaises(dns.name.NoParent, bad)
633650
634651 def testFromUnicode1(self):
635 n = dns.name.from_text(u'foo.bar')
652 n = dns.name.from_text('foo.bar')
636653 self.assertEqual(n.labels, (b'foo', b'bar', b''))
637654
638655 def testFromUnicode2(self):
639 n = dns.name.from_text(u'foo\u1234bar.bar')
656 n = dns.name.from_text('foo\u1234bar.bar')
640657 self.assertEqual(n.labels, (b'xn--foobar-r5z', b'bar', b''))
641658
642659 def testFromUnicodeAlternateDot1(self):
643 n = dns.name.from_text(u'foo\u3002bar')
660 n = dns.name.from_text('foo\u3002bar')
644661 self.assertEqual(n.labels, (b'foo', b'bar', b''))
645662
646663 def testFromUnicodeAlternateDot2(self):
647 n = dns.name.from_text(u'foo\uff0ebar')
664 n = dns.name.from_text('foo\uff0ebar')
648665 self.assertEqual(n.labels, (b'foo', b'bar', b''))
649666
650667 def testFromUnicodeAlternateDot3(self):
651 n = dns.name.from_text(u'foo\uff61bar')
668 n = dns.name.from_text('foo\uff61bar')
652669 self.assertEqual(n.labels, (b'foo', b'bar', b''))
653670
671 def testFromUnicodeRoot(self):
672 n = dns.name.from_text('.')
673 self.assertEqual(n.labels, (b'',))
674
675 def testFromUnicodeAlternateRoot1(self):
676 n = dns.name.from_text('\u3002')
677 self.assertEqual(n.labels, (b'',))
678
679 def testFromUnicodeAlternateRoot2(self):
680 n = dns.name.from_text('\uff0e')
681 self.assertEqual(n.labels, (b'',))
682
683 def testFromUnicodeAlternateRoot3(self):
684 n = dns.name.from_text('\uff61')
685 self.assertEqual(n.labels, (b'', ))
686
654687 def testFromUnicodeIDNA2003Explicit(self):
655 t = u'Königsgäßchen'
688 t = 'Königsgäßchen'
656689 e = dns.name.from_unicode(t, idna_codec=dns.name.IDNA_2003)
657690 self.assertEqual(str(e), 'xn--knigsgsschen-lcb0w.')
658691
659692 def testFromUnicodeIDNA2003Default(self):
660 t = u'Königsgäßchen'
693 t = 'Königsgäßchen'
661694 e = dns.name.from_unicode(t)
662695 self.assertEqual(str(e), 'xn--knigsgsschen-lcb0w.')
663696
664697 def testFromUnicodeIDNA2008(self):
665698 if dns.name.have_idna_2008:
666 t = u'Königsgäßchen'
699 t = 'Königsgäßchen'
667700 def bad():
668701 codec = dns.name.IDNA_2008_Strict
669702 return dns.name.from_unicode(t, idna_codec=codec)
670 self.failUnlessRaises(dns.name.IDNAException, bad)
703 self.assertRaises(dns.name.IDNAException, bad)
671704 e1 = dns.name.from_unicode(t, idna_codec=dns.name.IDNA_2008)
672705 self.assertEqual(str(e1), 'xn--knigsgchen-b4a3dun.')
673706 c2 = dns.name.IDNA_2008_Transitional
676709
677710 def testFromUnicodeIDNA2008Mixed(self):
678711 # the IDN rules for names are very restrictive, disallowing
679 # practical names like u'_sip._tcp.Königsgäßchen'. Dnspython
712 # practical names like '_sip._tcp.Königsgäßchen'. Dnspython
680713 # has a "practical" mode which permits labels which are purely
681714 # ASCII to go straight through, and thus not invalid useful
682715 # things in the real world.
683716 if dns.name.have_idna_2008:
684 t = u'_sip._tcp.Königsgäßchen'
717 t = '_sip._tcp.Königsgäßchen'
685718 def bad1():
686719 codec = dns.name.IDNA_2008_Strict
687720 return dns.name.from_unicode(t, idna_codec=codec)
691724 def bad3():
692725 codec = dns.name.IDNA_2008_Transitional
693726 return dns.name.from_unicode(t, idna_codec=codec)
694 self.failUnlessRaises(dns.name.IDNAException, bad1)
695 self.failUnlessRaises(dns.name.IDNAException, bad2)
696 self.failUnlessRaises(dns.name.IDNAException, bad3)
727 self.assertRaises(dns.name.IDNAException, bad1)
728 self.assertRaises(dns.name.IDNAException, bad2)
729 self.assertRaises(dns.name.IDNAException, bad3)
697730 e = dns.name.from_unicode(t,
698731 idna_codec=dns.name.IDNA_2008_Practical)
699732 self.assertEqual(str(e), '_sip._tcp.xn--knigsgchen-b4a3dun.')
700733
701734 def testToUnicode1(self):
702 n = dns.name.from_text(u'foo.bar')
735 n = dns.name.from_text('foo.bar')
703736 s = n.to_unicode()
704 self.assertEqual(s, u'foo.bar.')
737 self.assertEqual(s, 'foo.bar.')
705738
706739 def testToUnicode2(self):
707 n = dns.name.from_text(u'foo\u1234bar.bar')
740 n = dns.name.from_text('foo\u1234bar.bar')
708741 s = n.to_unicode()
709 self.assertEqual(s, u'foo\u1234bar.bar.')
742 self.assertEqual(s, 'foo\u1234bar.bar.')
710743
711744 def testToUnicode3(self):
712745 n = dns.name.from_text('foo.bar')
713746 s = n.to_unicode()
714 self.assertEqual(s, u'foo.bar.')
747 self.assertEqual(s, 'foo.bar.')
715748
716749 def testToUnicode4(self):
717750 if dns.name.have_idna_2008:
718 n = dns.name.from_text(u'ドメイン.テスト',
751 n = dns.name.from_text('ドメイン.テスト',
719752 idna_codec=dns.name.IDNA_2008)
720753 s = n.to_unicode()
721754 self.assertEqual(str(n), 'xn--eckwd4c7c.xn--zckzah.')
722 self.assertEqual(s, u'ドメイン.テスト.')
755 self.assertEqual(s, 'ドメイン.テスト.')
723756
724757 def testDefaultDecodeIsJustPunycode(self):
725758 # groß.com. in IDNA2008 form, pre-encoded.
726759 n = dns.name.from_text('xn--gro-7ka.com')
727760 # output using default codec which just decodes the punycode and
728761 # doesn't test for IDNA2003 or IDNA2008.
729 self.assertEqual(n.to_unicode(), u'groß.com.')
762 self.assertEqual(n.to_unicode(), 'groß.com.')
730763
731764 def testStrictINDA2003Decode(self):
732765 # groß.com. in IDNA2008 form, pre-encoded.
734767 def bad():
735768 # This throws in IDNA2003 because it doesn't "round trip".
736769 n.to_unicode(idna_codec=dns.name.IDNA_2003_Strict)
737 self.failUnlessRaises(dns.name.IDNAException, bad)
770 self.assertRaises(dns.name.IDNAException, bad)
738771
739772 def testReverseIPv4(self):
740773 e = dns.name.from_text('1.0.0.127.in-addr.arpa.')
749782 def testReverseIPv6MappedIpv4(self):
750783 e = dns.name.from_text('1.0.0.127.in-addr.arpa.')
751784 n = dns.reversename.from_address('::ffff:127.0.0.1')
752 self.failUnless(e == n)
785 self.assertTrue(e == n)
753786
754787 def testBadReverseIPv4(self):
755788 def bad():
756789 dns.reversename.from_address('127.0.foo.1')
757 self.failUnlessRaises(dns.exception.SyntaxError, bad)
790 self.assertRaises(dns.exception.SyntaxError, bad)
758791
759792 def testBadReverseIPv6(self):
760793 def bad():
761794 dns.reversename.from_address('::1::1')
762 self.failUnlessRaises(dns.exception.SyntaxError, bad)
795 self.assertRaises(dns.exception.SyntaxError, bad)
763796
764797 def testForwardIPv4(self):
765798 n = dns.name.from_text('1.0.0.127.in-addr.arpa.')
777810 text = '+1 650 555 1212'
778811 e = dns.name.from_text('2.1.2.1.5.5.5.0.5.6.1.e164.arpa.')
779812 n = dns.e164.from_e164(text)
780 self.failUnless(n == e)
813 self.assertTrue(n == e)
781814
782815 def testEnumToE164(self):
783816 n = dns.name.from_text('2.1.2.1.5.5.5.0.5.6.1.e164.arpa.')
3434 self.rndict[n2] = 2
3535
3636 def testDepth(self):
37 self.failUnless(self.ndict.max_depth == 3)
37 self.assertTrue(self.ndict.max_depth == 3)
3838
3939 def testLookup1(self):
4040 k = dns.name.from_text('foo.bar.')
41 self.failUnless(self.ndict[k] == 1)
41 self.assertTrue(self.ndict[k] == 1)
4242
4343 def testLookup2(self):
4444 k = dns.name.from_text('foo.bar.')
45 self.failUnless(self.ndict.get_deepest_match(k)[1] == 1)
45 self.assertTrue(self.ndict.get_deepest_match(k)[1] == 1)
4646
4747 def testLookup3(self):
4848 k = dns.name.from_text('a.b.c.foo.bar.')
49 self.failUnless(self.ndict.get_deepest_match(k)[1] == 1)
49 self.assertTrue(self.ndict.get_deepest_match(k)[1] == 1)
5050
5151 def testLookup4(self):
5252 k = dns.name.from_text('a.b.c.bar.')
53 self.failUnless(self.ndict.get_deepest_match(k)[1] == 2)
53 self.assertTrue(self.ndict.get_deepest_match(k)[1] == 2)
5454
5555 def testLookup5(self):
5656 def bad():
5757 n = dns.name.from_text('a.b.c.')
5858 self.ndict.get_deepest_match(n)
59 self.failUnlessRaises(KeyError, bad)
59 self.assertRaises(KeyError, bad)
6060
6161 def testLookup6(self):
6262 def bad():
6363 self.ndict.get_deepest_match(dns.name.empty)
64 self.failUnlessRaises(KeyError, bad)
64 self.assertRaises(KeyError, bad)
6565
6666 def testLookup7(self):
6767 self.ndict[dns.name.empty] = 100
6868 n = dns.name.from_text('a.b.c.')
6969 v = self.ndict.get_deepest_match(n)[1]
70 self.failUnless(v == 100)
70 self.assertTrue(v == 100)
7171
7272 def testLookup8(self):
7373 def bad():
7474 self.ndict['foo'] = 100
75 self.failUnlessRaises(ValueError, bad)
75 self.assertRaises(ValueError, bad)
7676
7777 def testRelDepth(self):
78 self.failUnless(self.rndict.max_depth == 2)
78 self.assertTrue(self.rndict.max_depth == 2)
7979
8080 def testRelLookup1(self):
8181 k = dns.name.from_text('foo.bar', None)
82 self.failUnless(self.rndict[k] == 1)
82 self.assertTrue(self.rndict[k] == 1)
8383
8484 def testRelLookup2(self):
8585 k = dns.name.from_text('foo.bar', None)
86 self.failUnless(self.rndict.get_deepest_match(k)[1] == 1)
86 self.assertTrue(self.rndict.get_deepest_match(k)[1] == 1)
8787
8888 def testRelLookup3(self):
8989 k = dns.name.from_text('a.b.c.foo.bar', None)
90 self.failUnless(self.rndict.get_deepest_match(k)[1] == 1)
90 self.assertTrue(self.rndict.get_deepest_match(k)[1] == 1)
9191
9292 def testRelLookup4(self):
9393 k = dns.name.from_text('a.b.c.bar', None)
94 self.failUnless(self.rndict.get_deepest_match(k)[1] == 2)
94 self.assertTrue(self.rndict.get_deepest_match(k)[1] == 2)
9595
9696 def testRelLookup7(self):
9797 self.rndict[dns.name.empty] = 100
9898 n = dns.name.from_text('a.b.c', None)
9999 v = self.rndict.get_deepest_match(n)[1]
100 self.failUnless(v == 100)
100 self.assertTrue(v == 100)
101101
102102 if __name__ == '__main__':
103103 unittest.main()
2828 u"1 0 100 ABCD SCBCQHKU35969L2A68P3AD59LHF30715 A CAA TYPE65534")
2929 bitmap = bytearray(b'\0' * 32)
3030 bitmap[31] = bitmap[31] | 2
31 self.assertEqual(rdata.windows, [(0, bytearray(b'@')),
32 (1, bytearray(b'@')), # CAA = 257
31 self.assertEqual(rdata.windows, [(0, b'@'),
32 (1, b'@'), # CAA = 257
3333 (255, bitmap)
3434 ])
3535
3838
3939 def test_aton1(self):
4040 a = aton6('::')
41 self.failUnless(a == b'\x00' * 16)
41 self.assertTrue(a == b'\x00' * 16)
4242
4343 def test_aton2(self):
4444 a = aton6('::1')
45 self.failUnless(a == b'\x00' * 15 + b'\x01')
45 self.assertTrue(a == b'\x00' * 15 + b'\x01')
4646
4747 def test_aton3(self):
4848 a = aton6('::10.0.0.1')
49 self.failUnless(a == b'\x00' * 12 + b'\x0a\x00\x00\x01')
49 self.assertTrue(a == b'\x00' * 12 + b'\x0a\x00\x00\x01')
5050
5151 def test_aton4(self):
5252 a = aton6('abcd::dcba')
53 self.failUnless(a == b'\xab\xcd' + b'\x00' * 12 + b'\xdc\xba')
53 self.assertTrue(a == b'\xab\xcd' + b'\x00' * 12 + b'\xdc\xba')
5454
5555 def test_aton5(self):
5656 a = aton6('1:2:3:4:5:6:7:8')
6060 def test_bad_aton1(self):
6161 def bad():
6262 aton6('abcd:dcba')
63 self.failUnlessRaises(dns.exception.SyntaxError, bad)
63 self.assertRaises(dns.exception.SyntaxError, bad)
6464
6565 def test_bad_aton2(self):
6666 def bad():
6767 aton6('abcd::dcba::1')
68 self.failUnlessRaises(dns.exception.SyntaxError, bad)
68 self.assertRaises(dns.exception.SyntaxError, bad)
6969
7070 def test_bad_aton3(self):
7171 def bad():
7272 aton6('1:2:3:4:5:6:7:8:9')
73 self.failUnlessRaises(dns.exception.SyntaxError, bad)
73 self.assertRaises(dns.exception.SyntaxError, bad)
7474
7575 def test_aton6(self):
7676 a = aton6('::')
161161 def test_bad_ntoa1(self):
162162 def bad():
163163 ntoa6('')
164 self.failUnlessRaises(ValueError, bad)
164 self.assertRaises(ValueError, bad)
165165
166166 def test_bad_ntoa2(self):
167167 def bad():
168168 ntoa6('\x00' * 17)
169 self.failUnlessRaises(ValueError, bad)
169 self.assertRaises(ValueError, bad)
170170
171171 def test_good_v4_aton(self):
172172 pairs = [('1.2.3.4', b'\x01\x02\x03\x04'),
185185 return bad
186186 for addr in v4_bad_addrs:
187187 print(addr)
188 self.failUnlessRaises(dns.exception.SyntaxError, make_bad(addr))
188 self.assertRaises(dns.exception.SyntaxError, make_bad(addr))
189189
190190 def test_bad_v6_aton(self):
191191 addrs = ['+::0', '0::0::', '::0::', '1:2:3:4:5:6:7:8:9',
197197 x = aton6(a)
198198 return bad
199199 for addr in addrs:
200 self.failUnlessRaises(dns.exception.SyntaxError, make_bad(addr))
200 self.assertRaises(dns.exception.SyntaxError, make_bad(addr))
201201
202202 def test_rfc5952_section_4_2_2(self):
203203 addr = '2001:db8:0:1:1:1:1:1'
209209 t1 = '2001:db8:0:1:1:1:1:1'
210210 t2 = '::ffff:127.0.0.1'
211211 t3 = '1::ffff:127.0.0.1'
212 self.failIf(dns.ipv6.is_mapped(aton6(t1)))
213 self.failUnless(dns.ipv6.is_mapped(aton6(t2)))
214 self.failIf(dns.ipv6.is_mapped(aton6(t3)))
212 self.assertFalse(dns.ipv6.is_mapped(aton6(t1)))
213 self.assertTrue(dns.ipv6.is_mapped(aton6(t2)))
214 self.assertFalse(dns.ipv6.is_mapped(aton6(t3)))
215215
216216 def test_is_multicast(self):
217217 t1 = '223.0.0.1'
220220 t4 = '239.0.0.1'
221221 t5 = 'fe00::1'
222222 t6 = 'ff00::1'
223 self.failIf(dns.inet.is_multicast(t1))
224 self.failIf(dns.inet.is_multicast(t2))
225 self.failUnless(dns.inet.is_multicast(t3))
226 self.failUnless(dns.inet.is_multicast(t4))
227 self.failIf(dns.inet.is_multicast(t5))
228 self.failUnless(dns.inet.is_multicast(t6))
223 self.assertFalse(dns.inet.is_multicast(t1))
224 self.assertFalse(dns.inet.is_multicast(t2))
225 self.assertTrue(dns.inet.is_multicast(t3))
226 self.assertTrue(dns.inet.is_multicast(t4))
227 self.assertFalse(dns.inet.is_multicast(t5))
228 self.assertTrue(dns.inet.is_multicast(t6))
229229
230230 if __name__ == '__main__':
231231 unittest.main()
2626
2727 def test_str(self):
2828 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, "1.2.3.4")
29 self.failUnless(rdata.address == "1.2.3.4")
29 self.assertTrue(rdata.address == "1.2.3.4")
3030
3131 def test_unicode(self):
3232 rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, u"1.2.3.4")
33 self.failUnless(rdata.address == "1.2.3.4")
33 self.assertTrue(rdata.address == "1.2.3.4")
3434
3535 def test_module_registration(self):
3636 TTXT = 64001
3737 dns.rdata.register_type(tests.ttxt_module, TTXT, 'TTXT')
3838 rdata = dns.rdata.from_text(dns.rdataclass.IN, TTXT, 'hello world')
39 self.failUnless(rdata.strings == [b'hello', b'world'])
40 self.failUnless(dns.rdatatype.to_text(TTXT) == 'TTXT')
41 self.failUnless(dns.rdatatype.from_text('TTXT') == TTXT)
39 self.assertTrue(rdata.strings == [b'hello', b'world'])
40 self.assertTrue(dns.rdatatype.to_text(TTXT) == 'TTXT')
41 self.assertTrue(dns.rdatatype.from_text('TTXT') == TTXT)
4242
4343 def test_module_reregistration(self):
4444 def bad():
4545 TTXTTWO = dns.rdatatype.TXT
4646 dns.rdata.register_type(tests.ttxt_module, TTXTTWO, 'TTXTTWO')
47 self.failUnlessRaises(dns.rdata.RdatatypeExists, bad)
47 self.assertRaises(dns.rdata.RdatatypeExists, bad)
4848
4949 if __name__ == '__main__':
5050 unittest.main()
2424 # Classes
2525
2626 def test_class_meta1(self):
27 self.failUnless(dns.rdataclass.is_metaclass(dns.rdataclass.ANY))
27 self.assertTrue(dns.rdataclass.is_metaclass(dns.rdataclass.ANY))
2828
2929 def test_class_meta2(self):
30 self.failUnless(not dns.rdataclass.is_metaclass(dns.rdataclass.IN))
30 self.assertTrue(not dns.rdataclass.is_metaclass(dns.rdataclass.IN))
3131
3232 def test_class_bytext1(self):
33 self.failUnless(dns.rdataclass.from_text('IN') == dns.rdataclass.IN)
33 self.assertTrue(dns.rdataclass.from_text('IN') == dns.rdataclass.IN)
3434
3535 def test_class_bytext2(self):
36 self.failUnless(dns.rdataclass.from_text('CLASS1') ==
36 self.assertTrue(dns.rdataclass.from_text('CLASS1') ==
3737 dns.rdataclass.IN)
3838
3939 def test_class_bytext_bounds1(self):
40 self.failUnless(dns.rdataclass.from_text('CLASS0') == 0)
41 self.failUnless(dns.rdataclass.from_text('CLASS65535') == 65535)
40 self.assertTrue(dns.rdataclass.from_text('CLASS0') == 0)
41 self.assertTrue(dns.rdataclass.from_text('CLASS65535') == 65535)
4242
4343 def test_class_bytext_bounds2(self):
4444 def bad():
4545 dns.rdataclass.from_text('CLASS65536')
46 self.failUnlessRaises(ValueError, bad)
46 self.assertRaises(ValueError, bad)
4747
4848 def test_class_bytext_unknown(self):
4949 def bad():
5050 dns.rdataclass.from_text('XXX')
51 self.failUnlessRaises(dns.rdataclass.UnknownRdataclass, bad)
51 self.assertRaises(dns.rdataclass.UnknownRdataclass, bad)
5252
5353 def test_class_totext1(self):
54 self.failUnless(dns.rdataclass.to_text(dns.rdataclass.IN) == 'IN')
54 self.assertTrue(dns.rdataclass.to_text(dns.rdataclass.IN) == 'IN')
5555
5656 def test_class_totext2(self):
57 self.failUnless(dns.rdataclass.to_text(999) == 'CLASS999')
57 self.assertTrue(dns.rdataclass.to_text(999) == 'CLASS999')
5858
5959 def test_class_totext_bounds1(self):
6060 def bad():
6161 dns.rdataclass.to_text(-1)
62 self.failUnlessRaises(ValueError, bad)
62 self.assertRaises(ValueError, bad)
6363
6464 def test_class_totext_bounds2(self):
6565 def bad():
6666 dns.rdataclass.to_text(65536)
67 self.failUnlessRaises(ValueError, bad)
67 self.assertRaises(ValueError, bad)
6868
6969 # Types
7070
7171 def test_type_meta1(self):
72 self.failUnless(dns.rdatatype.is_metatype(dns.rdatatype.ANY))
72 self.assertTrue(dns.rdatatype.is_metatype(dns.rdatatype.ANY))
7373
7474 def test_type_meta2(self):
75 self.failUnless(dns.rdatatype.is_metatype(dns.rdatatype.OPT))
75 self.assertTrue(dns.rdatatype.is_metatype(dns.rdatatype.OPT))
7676
7777 def test_type_meta3(self):
78 self.failUnless(not dns.rdatatype.is_metatype(dns.rdatatype.A))
78 self.assertTrue(not dns.rdatatype.is_metatype(dns.rdatatype.A))
7979
8080 def test_type_singleton1(self):
81 self.failUnless(dns.rdatatype.is_singleton(dns.rdatatype.SOA))
81 self.assertTrue(dns.rdatatype.is_singleton(dns.rdatatype.SOA))
8282
8383 def test_type_singleton2(self):
84 self.failUnless(not dns.rdatatype.is_singleton(dns.rdatatype.A))
84 self.assertTrue(not dns.rdatatype.is_singleton(dns.rdatatype.A))
8585
8686 def test_type_bytext1(self):
87 self.failUnless(dns.rdatatype.from_text('A') == dns.rdatatype.A)
87 self.assertTrue(dns.rdatatype.from_text('A') == dns.rdatatype.A)
8888
8989 def test_type_bytext2(self):
90 self.failUnless(dns.rdatatype.from_text('TYPE1') ==
90 self.assertTrue(dns.rdatatype.from_text('TYPE1') ==
9191 dns.rdatatype.A)
9292
9393 def test_type_bytext_bounds1(self):
94 self.failUnless(dns.rdatatype.from_text('TYPE0') == 0)
95 self.failUnless(dns.rdatatype.from_text('TYPE65535') == 65535)
94 self.assertTrue(dns.rdatatype.from_text('TYPE0') == 0)
95 self.assertTrue(dns.rdatatype.from_text('TYPE65535') == 65535)
9696
9797 def test_type_bytext_bounds2(self):
9898 def bad():
9999 dns.rdatatype.from_text('TYPE65536')
100 self.failUnlessRaises(ValueError, bad)
100 self.assertRaises(ValueError, bad)
101101
102102 def test_type_bytext_unknown(self):
103103 def bad():
104104 dns.rdatatype.from_text('XXX')
105 self.failUnlessRaises(dns.rdatatype.UnknownRdatatype, bad)
105 self.assertRaises(dns.rdatatype.UnknownRdatatype, bad)
106106
107107 def test_type_totext1(self):
108 self.failUnless(dns.rdatatype.to_text(dns.rdatatype.A) == 'A')
108 self.assertTrue(dns.rdatatype.to_text(dns.rdatatype.A) == 'A')
109109
110110 def test_type_totext2(self):
111 self.failUnless(dns.rdatatype.to_text(999) == 'TYPE999')
111 self.assertTrue(dns.rdatatype.to_text(999) == 'TYPE999')
112112
113113 def test_type_totext_bounds1(self):
114114 def bad():
115115 dns.rdatatype.to_text(-1)
116 self.failUnlessRaises(ValueError, bad)
116 self.assertRaises(ValueError, bad)
117117
118118 def test_type_totext_bounds2(self):
119119 def bad():
120120 dns.rdatatype.to_text(65536)
121 self.failUnlessRaises(ValueError, bad)
121 self.assertRaises(ValueError, bad)
122
123 def test_type0_totext(self):
124 self.assertTrue(dns.rdatatype.to_text(0) == 'TYPE0')
122125
123126 if __name__ == '__main__':
124127 unittest.main()
2727 good_s = set() #type: Set[str]
2828 good_f = 0
2929 from_flags = dns.rdtypes.ANY.DNSKEY.flags_to_text_set(good_f)
30 self.failUnless(from_flags == good_s,
30 self.assertTrue(from_flags == good_s,
3131 '"{}" != "{}"'.format(from_flags, good_s))
3232 from_set = dns.rdtypes.ANY.DNSKEY.flags_from_text_set(good_s)
33 self.failUnless(from_set == good_f,
33 self.assertTrue(from_set == good_f,
3434 '"0x{:x}" != "0x{:x}"'.format(from_set, good_f))
3535
3636 def testFlagsAll(self): # type: () -> None
3838 good_s = {'SEP', 'REVOKE', 'ZONE'}
3939 good_f = 0x181
4040 from_flags = dns.rdtypes.ANY.DNSKEY.flags_to_text_set(good_f)
41 self.failUnless(from_flags == good_s,
41 self.assertTrue(from_flags == good_s,
4242 '"{}" != "{}"'.format(from_flags, good_s))
4343 from_text = dns.rdtypes.ANY.DNSKEY.flags_from_text_set(good_s)
44 self.failUnless(from_text == good_f,
44 self.assertTrue(from_text == good_f,
4545 '"0x{:x}" != "0x{:x}"'.format(from_text, good_f))
4646
4747 def testFlagsUnknownToText(self): # type: () -> None
4848 '''Test that undefined flags are returned in hexadecimal notation.'''
4949 unk_s = {'0x8000'}
5050 flags_s = dns.rdtypes.ANY.DNSKEY.flags_to_text_set(0x8000)
51 self.failUnless(flags_s == unk_s, '"{}" != "{}"'.format(flags_s, unk_s))
51 self.assertTrue(flags_s == unk_s, '"{}" != "{}"'.format(flags_s, unk_s))
5252
5353 def testFlagsUnknownToFlags(self): # type: () -> None
5454 '''Test that conversion from undefined mnemonic raises error.'''
55 self.failUnlessRaises(NotImplementedError,
55 self.assertRaises(NotImplementedError,
5656 dns.rdtypes.ANY.DNSKEY.flags_from_text_set,
5757 (['0x8000']))
5858
6161 rr = dns.rrset.from_text('foo', 300, 'IN', 'DNSKEY', '257 3 8 KEY=')[0]
6262 rr_s = {'ZONE', 'SEP'}
6363 flags_s = rr.flags_to_text_set()
64 self.failUnless(flags_s == rr_s, '"{}" != "{}"'.format(flags_s, rr_s))
64 self.assertTrue(flags_s == rr_s, '"{}" != "{}"'.format(flags_s, rr_s))
6565
6666
6767 if __name__ == '__main__':
2727 r2 = dns.rrset.from_text('FOO', 600, 'in', 'loc',
2828 '49 11 42.400 N 16 36 29.600 E 227.64m '
2929 '1.00m 10000.00m 10.00m')
30 self.failUnless(r1 == r2, '"{}" != "{}"'.format(r1, r2))
30 self.assertTrue(r1 == r2, '"{}" != "{}"'.format(r1, r2))
3131
3232 def testEqual2(self):
3333 '''Test default values for size, horizontal and vertical precision.'''
3838 (16, 36, 29, 600, 1),
3939 22764.0, # centimeters
4040 100.0, 1000000.00, 1000.0) # centimeters
41 self.failUnless(r1 == r2, '"{}" != "{}"'.format(r1, r2))
41 self.assertTrue(r1 == r2, '"{}" != "{}"'.format(r1, r2))
4242
4343 def testEqual3(self):
4444 '''Test size, horizontal and vertical precision parsers: 100 cm == 1 m.
5050 r2 = dns.rrset.from_text('FOO', 600, 'in', 'loc',
5151 '49 11 42.400 N 16 36 29.600 E 227.64m '
5252 '2.00m 10.00m 2.00m')[0]
53 self.failUnless(r1 == r2, '"{}" != "{}"'.format(r1, r2))
53 self.assertTrue(r1 == r2, '"{}" != "{}"'.format(r1, r2))
5454
5555 def testEqual4(self):
5656 '''Test size, horizontal and vertical precision parsers without unit.
6363 r2 = dns.rrset.from_text('FOO', 600, 'in', 'loc',
6464 '49 11 42.400 N 16 36 29.600 E 227.64 '
6565 '2 10 2')[0] # meters without explicit unit
66 self.failUnless(r1 == r2, '"{}" != "{}"'.format(r1, r2))
66 self.assertTrue(r1 == r2, '"{}" != "{}"'.format(r1, r2))
6767
6868 if __name__ == '__main__':
6969 unittest.main()
2626 import dns.rdataclass
2727 import dns.rdatatype
2828 import dns.resolver
29 from dns._compat import xrange, PY3
3029
3130 # Some tests require the internet to be available to run, so let's
3231 # skip those if it's not there.
107106 def testRead(self):
108107 f = StringIO(resolv_conf)
109108 r = dns.resolver.Resolver(f)
110 self.failUnless(r.nameservers == ['10.0.0.1', '10.0.0.2'] and
109 self.assertTrue(r.nameservers == ['10.0.0.1', '10.0.0.2'] and
111110 r.domain == dns.name.from_text('foo'))
112111
113112 def testCacheExpiration(self):
118117 cache = dns.resolver.Cache()
119118 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
120119 time.sleep(2)
121 self.failUnless(cache.get((name, dns.rdatatype.A, dns.rdataclass.IN))
120 self.assertTrue(cache.get((name, dns.rdatatype.A, dns.rdataclass.IN))
122121 is None)
123122
124123 def testCacheCleaning(self):
129128 cache = dns.resolver.Cache(cleaning_interval=1.0)
130129 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
131130 time.sleep(2)
132 self.failUnless(cache.get((name, dns.rdatatype.A, dns.rdataclass.IN))
131 self.assertTrue(cache.get((name, dns.rdatatype.A, dns.rdataclass.IN))
133132 is None)
134133
135134 def testIndexErrorOnEmptyRRsetAccess(self):
140139 dns.rdataclass.IN, message,
141140 False)
142141 return answer[0]
143 self.failUnlessRaises(IndexError, bad)
142 self.assertRaises(IndexError, bad)
144143
145144 def testIndexErrorOnEmptyRRsetDelete(self):
146145 def bad():
150149 dns.rdataclass.IN, message,
151150 False)
152151 del answer[0]
153 self.failUnlessRaises(IndexError, bad)
152 self.assertRaises(IndexError, bad)
154153
155154 @unittest.skipIf(not _network_available, "Internet not reachable")
156155 def testZoneForName1(self):
157156 name = dns.name.from_text('www.dnspython.org.')
158157 ezname = dns.name.from_text('dnspython.org.')
159158 zname = dns.resolver.zone_for_name(name)
160 self.failUnless(zname == ezname)
159 self.assertTrue(zname == ezname)
161160
162161 @unittest.skipIf(not _network_available, "Internet not reachable")
163162 def testZoneForName2(self):
164163 name = dns.name.from_text('a.b.www.dnspython.org.')
165164 ezname = dns.name.from_text('dnspython.org.')
166165 zname = dns.resolver.zone_for_name(name)
167 self.failUnless(zname == ezname)
166 self.assertTrue(zname == ezname)
168167
169168 @unittest.skipIf(not _network_available, "Internet not reachable")
170169 def testZoneForName3(self):
171170 name = dns.name.from_text('dnspython.org.')
172171 ezname = dns.name.from_text('dnspython.org.')
173172 zname = dns.resolver.zone_for_name(name)
174 self.failUnless(zname == ezname)
173 self.assertTrue(zname == ezname)
175174
176175 def testZoneForName4(self):
177176 def bad():
178177 name = dns.name.from_text('dnspython.org', None)
179178 dns.resolver.zone_for_name(name)
180 self.failUnlessRaises(dns.resolver.NotAbsolute, bad)
179 self.assertRaises(dns.resolver.NotAbsolute, bad)
181180
182181 def testLRUReplace(self):
183182 cache = dns.resolver.LRUCache(4)
184 for i in xrange(0, 5):
183 for i in range(0, 5):
185184 name = dns.name.from_text('example%d.' % i)
186185 answer = FakeAnswer(time.time() + 1)
187186 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
188 for i in xrange(0, 5):
187 for i in range(0, 5):
189188 name = dns.name.from_text('example%d.' % i)
190189 if i == 0:
191 self.failUnless(cache.get((name, dns.rdatatype.A,
190 self.assertTrue(cache.get((name, dns.rdatatype.A,
192191 dns.rdataclass.IN))
193192 is None)
194193 else:
195 self.failUnless(not cache.get((name, dns.rdatatype.A,
194 self.assertTrue(not cache.get((name, dns.rdatatype.A,
196195 dns.rdataclass.IN))
197196 is None)
198197
199198 def testLRUDoesLRU(self):
200199 cache = dns.resolver.LRUCache(4)
201 for i in xrange(0, 4):
200 for i in range(0, 4):
202201 name = dns.name.from_text('example%d.' % i)
203202 answer = FakeAnswer(time.time() + 1)
204203 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
208207 name = dns.name.from_text('example4.')
209208 answer = FakeAnswer(time.time() + 1)
210209 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
211 for i in xrange(0, 5):
210 for i in range(0, 5):
212211 name = dns.name.from_text('example%d.' % i)
213212 if i == 1:
214 self.failUnless(cache.get((name, dns.rdatatype.A,
213 self.assertTrue(cache.get((name, dns.rdatatype.A,
215214 dns.rdataclass.IN))
216215 is None)
217216 else:
218 self.failUnless(not cache.get((name, dns.rdatatype.A,
217 self.assertTrue(not cache.get((name, dns.rdatatype.A,
219218 dns.rdataclass.IN))
220219 is None)
221220
222221 def testLRUExpiration(self):
223222 cache = dns.resolver.LRUCache(4)
224 for i in xrange(0, 4):
223 for i in range(0, 4):
225224 name = dns.name.from_text('example%d.' % i)
226225 answer = FakeAnswer(time.time() + 1)
227226 cache.put((name, dns.rdatatype.A, dns.rdataclass.IN), answer)
228227 time.sleep(2)
229 for i in xrange(0, 4):
230 name = dns.name.from_text('example%d.' % i)
231 self.failUnless(cache.get((name, dns.rdatatype.A,
228 for i in range(0, 4):
229 name = dns.name.from_text('example%d.' % i)
230 self.assertTrue(cache.get((name, dns.rdatatype.A,
232231 dns.rdataclass.IN))
233232 is None)
234233
282281 try:
283282 raise dns.resolver.NXDOMAIN
284283 except dns.exception.DNSException as e:
285 if not PY3:
286 # pylint: disable=exception-message-attribute
287 self.assertTrue((e.message == e.__doc__))
288284 self.assertTrue((e.args == (e.__doc__,)))
289285 self.assertTrue(('kwargs' in dir(e)))
290286 self.assertTrue((str(e) == e.__doc__), str(e))
294290 try:
295291 raise dns.resolver.NXDOMAIN("errmsg")
296292 except dns.exception.DNSException as e:
297 if not PY3:
298 # pylint: disable=exception-message-attribute
299 self.assertTrue((e.message == "errmsg"))
300293 self.assertTrue((e.args == ("errmsg",)))
301294 self.assertTrue(('kwargs' in dir(e)))
302295 self.assertTrue((str(e) == "errmsg"), str(e))
306299 try:
307300 raise dns.resolver.NXDOMAIN("errmsg", -1)
308301 except dns.exception.DNSException as e:
309 if not PY3:
310 # pylint: disable=exception-message-attribute
311 self.assertTrue((e.message == ""))
312302 self.assertTrue((e.args == ("errmsg", -1)))
313303 self.assertTrue(('kwargs' in dir(e)))
314304 self.assertTrue((str(e) == "('errmsg', -1)"), str(e))
334324 raise dns.resolver.NXDOMAIN(qnames=[n1])
335325 except dns.exception.DNSException as e:
336326 MSG = "The DNS query name does not exist: a.b."
337 if not PY3:
338 # pylint: disable=exception-message-attribute
339 self.assertTrue((e.message == MSG), e.message)
340327 self.assertTrue((e.args == (MSG,)), repr(e.args))
341328 self.assertTrue(('kwargs' in dir(e)))
342329 self.assertTrue((str(e) == MSG), str(e))
351338 e0 = dns.resolver.NXDOMAIN("errmsg")
352339 e = e0 + e
353340 MSG = "None of DNS query names exist: a.b.s., a.b."
354 if not PY3:
355 # pylint: disable=exception-message-attribute
356 self.assertTrue((e.message == MSG), e.message)
357341 self.assertTrue((e.args == (MSG,)), repr(e.args))
358342 self.assertTrue(('kwargs' in dir(e)))
359343 self.assertTrue((str(e) == MSG), str(e))
371355 raise dns.resolver.NXDOMAIN(qnames=[n1], responses={n1: 'r1.1'})
372356 except dns.resolver.NXDOMAIN as e:
373357 MSG = "The DNS query name does not exist: a.b."
374 if not PY3:
375 # pylint: disable=exception-message-attribute
376 self.assertTrue((e.message == MSG), e.message)
377358 self.assertTrue((e.args == (MSG,)), repr(e.args))
378359 self.assertTrue(('kwargs' in dir(e)))
379360 self.assertTrue((str(e) == MSG), str(e))
2323 def testEqual1(self):
2424 r1 = dns.rrset.from_text('foo', 300, 'in', 'a', '10.0.0.1', '10.0.0.2')
2525 r2 = dns.rrset.from_text('FOO', 300, 'in', 'a', '10.0.0.2', '10.0.0.1')
26 self.failUnless(r1 == r2)
26 self.assertTrue(r1 == r2)
2727
2828 def testEqual2(self):
2929 r1 = dns.rrset.from_text('foo', 300, 'in', 'a', '10.0.0.1', '10.0.0.2')
3030 r2 = dns.rrset.from_text('FOO', 600, 'in', 'a', '10.0.0.2', '10.0.0.1')
31 self.failUnless(r1 == r2)
31 self.assertTrue(r1 == r2)
3232
3333 def testNotEqual1(self):
3434 r1 = dns.rrset.from_text('fooa', 30, 'in', 'a', '10.0.0.1', '10.0.0.2')
3535 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
36 self.failUnless(r1 != r2)
36 self.assertTrue(r1 != r2)
3737
3838 def testNotEqual2(self):
3939 r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1', '10.0.0.3')
4040 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
41 self.failUnless(r1 != r2)
41 self.assertTrue(r1 != r2)
4242
4343 def testNotEqual3(self):
4444 r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1', '10.0.0.2',
4545 '10.0.0.3')
4646 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
47 self.failUnless(r1 != r2)
47 self.assertTrue(r1 != r2)
4848
4949 def testNotEqual4(self):
5050 r1 = dns.rrset.from_text('foo', 30, 'in', 'a', '10.0.0.1')
5151 r2 = dns.rrset.from_text('FOO', 30, 'in', 'a', '10.0.0.2', '10.0.0.1')
52 self.failUnless(r1 != r2)
52 self.assertTrue(r1 != r2)
5353
5454 if __name__ == '__main__':
5555 unittest.main()
2525
2626 def testLen1(self):
2727 s1 = S()
28 self.failUnless(len(s1) == 0)
28 self.assertTrue(len(s1) == 0)
2929
3030 def testLen2(self):
3131 s1 = S([1, 2, 3])
32 self.failUnless(len(s1) == 3)
32 self.assertTrue(len(s1) == 3)
3333
3434 def testLen3(self):
3535 s1 = S([1, 2, 3, 3, 3])
36 self.failUnless(len(s1) == 3)
36 self.assertTrue(len(s1) == 3)
3737
3838 def testUnion1(self):
3939 s1 = S([1, 2, 3])
4040 s2 = S([1, 2, 3])
4141 e = S([1, 2, 3])
42 self.failUnless(s1 | s2 == e)
42 self.assertTrue(s1 | s2 == e)
4343
4444 def testUnion2(self):
4545 s1 = S([1, 2, 3])
4646 s2 = S([])
4747 e = S([1, 2, 3])
48 self.failUnless(s1 | s2 == e)
48 self.assertTrue(s1 | s2 == e)
4949
5050 def testUnion3(self):
5151 s1 = S([1, 2, 3])
5252 s2 = S([3, 4])
5353 e = S([1, 2, 3, 4])
54 self.failUnless(s1 | s2 == e)
54 self.assertTrue(s1 | s2 == e)
5555
5656 def testIntersection1(self):
5757 s1 = S([1, 2, 3])
5858 s2 = S([1, 2, 3])
5959 e = S([1, 2, 3])
60 self.failUnless(s1 & s2 == e)
60 self.assertTrue(s1 & s2 == e)
6161
6262 def testIntersection2(self):
6363 s1 = S([0, 1, 2, 3])
6464 s2 = S([1, 2, 3, 4])
6565 e = S([1, 2, 3])
66 self.failUnless(s1 & s2 == e)
66 self.assertTrue(s1 & s2 == e)
6767
6868 def testIntersection3(self):
6969 s1 = S([1, 2, 3])
7070 s2 = S([])
7171 e = S([])
72 self.failUnless(s1 & s2 == e)
72 self.assertTrue(s1 & s2 == e)
7373
7474 def testIntersection4(self):
7575 s1 = S([1, 2, 3])
7676 s2 = S([5, 4])
7777 e = S([])
78 self.failUnless(s1 & s2 == e)
78 self.assertTrue(s1 & s2 == e)
7979
8080 def testDifference1(self):
8181 s1 = S([1, 2, 3])
8282 s2 = S([5, 4])
8383 e = S([1, 2, 3])
84 self.failUnless(s1 - s2 == e)
84 self.assertTrue(s1 - s2 == e)
8585
8686 def testDifference2(self):
8787 s1 = S([1, 2, 3])
8888 s2 = S([])
8989 e = S([1, 2, 3])
90 self.failUnless(s1 - s2 == e)
90 self.assertTrue(s1 - s2 == e)
9191
9292 def testDifference3(self):
9393 s1 = S([1, 2, 3])
9494 s2 = S([3, 2])
9595 e = S([1])
96 self.failUnless(s1 - s2 == e)
96 self.assertTrue(s1 - s2 == e)
9797
9898 def testDifference4(self):
9999 s1 = S([1, 2, 3])
100100 s2 = S([3, 2, 1])
101101 e = S([])
102 self.failUnless(s1 - s2 == e)
102 self.assertTrue(s1 - s2 == e)
103103
104104 def testSubset1(self):
105105 s1 = S([1, 2, 3])
106106 s2 = S([3, 2, 1])
107 self.failUnless(s1.issubset(s2))
107 self.assertTrue(s1.issubset(s2))
108108
109109 def testSubset2(self):
110110 s1 = S([1, 2, 3])
111 self.failUnless(s1.issubset(s1))
111 self.assertTrue(s1.issubset(s1))
112112
113113 def testSubset3(self):
114114 s1 = S([])
115115 s2 = S([1, 2, 3])
116 self.failUnless(s1.issubset(s2))
116 self.assertTrue(s1.issubset(s2))
117117
118118 def testSubset4(self):
119119 s1 = S([1])
120120 s2 = S([1, 2, 3])
121 self.failUnless(s1.issubset(s2))
121 self.assertTrue(s1.issubset(s2))
122122
123123 def testSubset5(self):
124124 s1 = S([])
125125 s2 = S([])
126 self.failUnless(s1.issubset(s2))
126 self.assertTrue(s1.issubset(s2))
127127
128128 def testSubset6(self):
129129 s1 = S([1, 4])
130130 s2 = S([1, 2, 3])
131 self.failUnless(not s1.issubset(s2))
131 self.assertTrue(not s1.issubset(s2))
132132
133133 def testSuperset1(self):
134134 s1 = S([1, 2, 3])
135135 s2 = S([3, 2, 1])
136 self.failUnless(s1.issuperset(s2))
136 self.assertTrue(s1.issuperset(s2))
137137
138138 def testSuperset2(self):
139139 s1 = S([1, 2, 3])
140 self.failUnless(s1.issuperset(s1))
140 self.assertTrue(s1.issuperset(s1))
141141
142142 def testSuperset3(self):
143143 s1 = S([1, 2, 3])
144144 s2 = S([])
145 self.failUnless(s1.issuperset(s2))
145 self.assertTrue(s1.issuperset(s2))
146146
147147 def testSuperset4(self):
148148 s1 = S([1, 2, 3])
149149 s2 = S([1])
150 self.failUnless(s1.issuperset(s2))
150 self.assertTrue(s1.issuperset(s2))
151151
152152 def testSuperset5(self):
153153 s1 = S([])
154154 s2 = S([])
155 self.failUnless(s1.issuperset(s2))
155 self.assertTrue(s1.issuperset(s2))
156156
157157 def testSuperset6(self):
158158 s1 = S([1, 2, 3])
159159 s2 = S([1, 4])
160 self.failUnless(not s1.issuperset(s2))
160 self.assertTrue(not s1.issuperset(s2))
161161
162162 def testUpdate1(self):
163163 s1 = S([1, 2, 3])
164164 u = (4, 5, 6)
165165 e = S([1, 2, 3, 4, 5, 6])
166166 s1.update(u)
167 self.failUnless(s1 == e)
167 self.assertTrue(s1 == e)
168168
169169 def testUpdate2(self):
170170 s1 = S([1, 2, 3])
171171 u = []
172172 e = S([1, 2, 3])
173173 s1.update(u)
174 self.failUnless(s1 == e)
174 self.assertTrue(s1 == e)
175175
176176 def testGetitem(self):
177177 s1 = S([1, 2, 3])
179179 i1 = s1[1]
180180 i2 = s1[2]
181181 s2 = S([i0, i1, i2])
182 self.failUnless(s1 == s2)
182 self.assertTrue(s1 == s2)
183183
184184 def testGetslice(self):
185185 s1 = S([1, 2, 3])
186186 slice = s1[0:2]
187 self.failUnless(len(slice) == 2)
187 self.assertTrue(len(slice) == 2)
188188 item = s1[2]
189189 slice.append(item)
190190 s2 = S(slice)
191 self.failUnless(s1 == s2)
191 self.assertTrue(s1 == s2)
192192
193193 def testDelitem(self):
194194 s1 = S([1, 2, 3])
195195 del s1[0]
196196 i1 = s1[0]
197197 i2 = s1[1]
198 self.failUnless(i1 != i2)
199 self.failUnless(i1 == 1 or i1 == 2 or i1 == 3)
200 self.failUnless(i2 == 1 or i2 == 2 or i2 == 3)
198 self.assertTrue(i1 != i2)
199 self.assertTrue(i1 == 1 or i1 == 2 or i1 == 3)
200 self.assertTrue(i2 == 1 or i2 == 2 or i2 == 3)
201201
202202 def testDelslice(self):
203203 s1 = S([1, 2, 3])
204204 del s1[0:2]
205205 i1 = s1[0]
206 self.failUnless(i1 == 1 or i1 == 2 or i1 == 3)
206 self.assertTrue(i1 == 1 or i1 == 2 or i1 == 3)
207207
208208 if __name__ == '__main__':
209209 unittest.main()
2626 def testStr(self):
2727 tok = dns.tokenizer.Tokenizer('foo')
2828 token = tok.get()
29 self.failUnless(token == Token(dns.tokenizer.IDENTIFIER, 'foo'))
30
31 def testUnicode(self):
32 tok = dns.tokenizer.Tokenizer(u'foo')
33 token = tok.get()
34 self.failUnless(token == Token(dns.tokenizer.IDENTIFIER, 'foo'))
29 self.assertTrue(token == Token(dns.tokenizer.IDENTIFIER, 'foo'))
3530
3631 def testQuotedString1(self):
3732 tok = dns.tokenizer.Tokenizer(r'"foo"')
3833 token = tok.get()
39 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, 'foo'))
34 self.assertTrue(token == Token(dns.tokenizer.QUOTED_STRING, 'foo'))
4035
4136 def testQuotedString2(self):
4237 tok = dns.tokenizer.Tokenizer(r'""')
4338 token = tok.get()
44 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, ''))
39 self.assertTrue(token == Token(dns.tokenizer.QUOTED_STRING, ''))
4540
4641 def testQuotedString3(self):
4742 tok = dns.tokenizer.Tokenizer(r'"\"foo\""')
4843 token = tok.get()
49 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, '"foo"'))
44 self.assertTrue(token == Token(dns.tokenizer.QUOTED_STRING, '"foo"'))
5045
5146 def testQuotedString4(self):
5247 tok = dns.tokenizer.Tokenizer(r'"foo\010bar"')
5348 token = tok.get()
54 self.failUnless(token == Token(dns.tokenizer.QUOTED_STRING, 'foo\x0abar'))
49 self.assertTrue(token == Token(dns.tokenizer.QUOTED_STRING, 'foo\x0abar'))
5550
5651 def testQuotedString5(self):
5752 def bad():
5853 tok = dns.tokenizer.Tokenizer(r'"foo')
5954 tok.get()
60 self.failUnlessRaises(dns.exception.UnexpectedEnd, bad)
55 self.assertRaises(dns.exception.UnexpectedEnd, bad)
6156
6257 def testQuotedString6(self):
6358 def bad():
6459 tok = dns.tokenizer.Tokenizer(r'"foo\01')
6560 tok.get()
66 self.failUnlessRaises(dns.exception.SyntaxError, bad)
61 self.assertRaises(dns.exception.SyntaxError, bad)
6762
6863 def testQuotedString7(self):
6964 def bad():
7065 tok = dns.tokenizer.Tokenizer('"foo\nbar"')
7166 tok.get()
72 self.failUnlessRaises(dns.exception.SyntaxError, bad)
67 self.assertRaises(dns.exception.SyntaxError, bad)
7368
7469 def testEmpty1(self):
7570 tok = dns.tokenizer.Tokenizer('')
7671 token = tok.get()
77 self.failUnless(token.is_eof())
72 self.assertTrue(token.is_eof())
7873
7974 def testEmpty2(self):
8075 tok = dns.tokenizer.Tokenizer('')
8176 token1 = tok.get()
8277 token2 = tok.get()
83 self.failUnless(token1.is_eof() and token2.is_eof())
78 self.assertTrue(token1.is_eof() and token2.is_eof())
8479
8580 def testEOL(self):
8681 tok = dns.tokenizer.Tokenizer('\n')
8782 token1 = tok.get()
8883 token2 = tok.get()
89 self.failUnless(token1.is_eol() and token2.is_eof())
84 self.assertTrue(token1.is_eol() and token2.is_eof())
9085
9186 def testWS1(self):
9287 tok = dns.tokenizer.Tokenizer(' \n')
9388 token1 = tok.get()
94 self.failUnless(token1.is_eol())
89 self.assertTrue(token1.is_eol())
9590
9691 def testWS2(self):
9792 tok = dns.tokenizer.Tokenizer(' \n')
9893 token1 = tok.get(want_leading=True)
99 self.failUnless(token1.is_whitespace())
94 self.assertTrue(token1.is_whitespace())
10095
10196 def testComment1(self):
10297 tok = dns.tokenizer.Tokenizer(' ;foo\n')
10398 token1 = tok.get()
104 self.failUnless(token1.is_eol())
99 self.assertTrue(token1.is_eol())
105100
106101 def testComment2(self):
107102 tok = dns.tokenizer.Tokenizer(' ;foo\n')
108103 token1 = tok.get(want_comment=True)
109104 token2 = tok.get()
110 self.failUnless(token1 == Token(dns.tokenizer.COMMENT, 'foo') and
105 self.assertTrue(token1 == Token(dns.tokenizer.COMMENT, 'foo') and
111106 token2.is_eol())
112107
113108 def testComment3(self):
114109 tok = dns.tokenizer.Tokenizer(' ;foo bar\n')
115110 token1 = tok.get(want_comment=True)
116111 token2 = tok.get()
117 self.failUnless(token1 == Token(dns.tokenizer.COMMENT, 'foo bar') and
112 self.assertTrue(token1 == Token(dns.tokenizer.COMMENT, 'foo bar') and
118113 token2.is_eol())
119114
120115 def testMultiline1(self):
121116 tok = dns.tokenizer.Tokenizer('( foo\n\n bar\n)')
122117 tokens = list(iter(tok))
123 self.failUnless(tokens == [Token(dns.tokenizer.IDENTIFIER, 'foo'),
118 self.assertTrue(tokens == [Token(dns.tokenizer.IDENTIFIER, 'foo'),
124119 Token(dns.tokenizer.IDENTIFIER, 'bar')])
125120
126121 def testMultiline2(self):
127122 tok = dns.tokenizer.Tokenizer('( foo\n\n bar\n)\n')
128123 tokens = list(iter(tok))
129 self.failUnless(tokens == [Token(dns.tokenizer.IDENTIFIER, 'foo'),
124 self.assertTrue(tokens == [Token(dns.tokenizer.IDENTIFIER, 'foo'),
130125 Token(dns.tokenizer.IDENTIFIER, 'bar'),
131126 Token(dns.tokenizer.EOL, '\n')])
132127 def testMultiline3(self):
133128 def bad():
134129 tok = dns.tokenizer.Tokenizer('foo)')
135130 list(iter(tok))
136 self.failUnlessRaises(dns.exception.SyntaxError, bad)
131 self.assertRaises(dns.exception.SyntaxError, bad)
137132
138133 def testMultiline4(self):
139134 def bad():
140135 tok = dns.tokenizer.Tokenizer('((foo)')
141136 list(iter(tok))
142 self.failUnlessRaises(dns.exception.SyntaxError, bad)
137 self.assertRaises(dns.exception.SyntaxError, bad)
143138
144139 def testUnget1(self):
145140 tok = dns.tokenizer.Tokenizer('foo')
146141 t1 = tok.get()
147142 tok.unget(t1)
148143 t2 = tok.get()
149 self.failUnless(t1 == t2 and t1.ttype == dns.tokenizer.IDENTIFIER and \
144 self.assertTrue(t1 == t2 and t1.ttype == dns.tokenizer.IDENTIFIER and \
150145 t1.value == 'foo')
151146
152147 def testUnget2(self):
155150 t1 = tok.get()
156151 tok.unget(t1)
157152 tok.unget(t1)
158 self.failUnlessRaises(dns.tokenizer.UngetBufferFull, bad)
153 self.assertRaises(dns.tokenizer.UngetBufferFull, bad)
159154
160155 def testGetEOL1(self):
161156 tok = dns.tokenizer.Tokenizer('\n')
162157 t = tok.get_eol()
163 self.failUnless(t == '\n')
158 self.assertTrue(t == '\n')
164159
165160 def testGetEOL2(self):
166161 tok = dns.tokenizer.Tokenizer('')
167162 t = tok.get_eol()
168 self.failUnless(t == '')
163 self.assertTrue(t == '')
169164
170165 def testEscapedDelimiter1(self):
171166 tok = dns.tokenizer.Tokenizer(r'ch\ ld')
172167 t = tok.get()
173 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ ld')
168 self.assertTrue(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ ld')
174169
175170 def testEscapedDelimiter2(self):
176171 tok = dns.tokenizer.Tokenizer(r'ch\032ld')
177172 t = tok.get()
178 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\032ld')
173 self.assertTrue(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\032ld')
179174
180175 def testEscapedDelimiter3(self):
181176 tok = dns.tokenizer.Tokenizer(r'ch\ild')
182177 t = tok.get()
183 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ild')
178 self.assertTrue(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ild')
184179
185180 def testEscapedDelimiter1u(self):
186181 tok = dns.tokenizer.Tokenizer(r'ch\ ld')
187182 t = tok.get().unescape()
188 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch ld')
183 self.assertTrue(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch ld')
189184
190185 def testEscapedDelimiter2u(self):
191186 tok = dns.tokenizer.Tokenizer(r'ch\032ld')
192187 t = tok.get().unescape()
193 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == 'ch ld')
188 self.assertTrue(t.ttype == dns.tokenizer.IDENTIFIER and t.value == 'ch ld')
194189
195190 def testEscapedDelimiter3u(self):
196191 tok = dns.tokenizer.Tokenizer(r'ch\ild')
197192 t = tok.get().unescape()
198 self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'child')
193 self.assertTrue(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'child')
199194
200195 if __name__ == '__main__':
201196 unittest.main()
0 # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
1
2 import base64
3 import unittest
4
5 import dns.tsigkeyring
6
7 text_keyring = {
8 'keyname.' : 'NjHwPsMKjdN++dOfE5iAiQ=='
9 }
10
11 rich_keyring = {
12 dns.name.from_text('keyname.') : \
13 base64.decodebytes('NjHwPsMKjdN++dOfE5iAiQ=='.encode())
14 }
15
16 class TSIGKeyRingTestCase(unittest.TestCase):
17
18 def test_from_text(self):
19 """text keyring -> rich keyring"""
20 rkeyring = dns.tsigkeyring.from_text(text_keyring)
21 self.assertEqual(rkeyring, rich_keyring)
22
23 def test_to_text(self):
24 """text keyring -> rich keyring -> text keyring"""
25 tkeyring = dns.tsigkeyring.to_text(rich_keyring)
26 self.assertEqual(tkeyring, text_keyring)
27
28 def test_from_and_to_text(self):
29 """text keyring -> rich keyring -> text keyring"""
30 rkeyring = dns.tsigkeyring.from_text(text_keyring)
31 tkeyring = dns.tsigkeyring.to_text(rkeyring)
32 self.assertEqual(tkeyring, text_keyring)
7474 update.delete('bar', 'a', '10.0.0.4')
7575 update.delete('blaz', 'a')
7676 update.delete('blaz2')
77 self.failUnless(update.to_wire() == goodwire)
77 self.assertTrue(update.to_wire() == goodwire)
7878
7979 def test_to_wire2(self): # type: () -> None
8080 update = dns.update.Update('example')
8989 update.delete('bar', 'a', '10.0.0.4')
9090 update.delete('blaz', 'a')
9191 update.delete('blaz2')
92 self.failUnless(update.to_wire() == goodwire)
92 self.assertTrue(update.to_wire() == goodwire)
9393
9494 def test_to_wire3(self): # type: () -> None
9595 update = dns.update.Update('example')
104104 update.delete('bar', 'a', '10.0.0.4')
105105 update.delete('blaz', 'a')
106106 update.delete('blaz2')
107 self.failUnless(update.to_wire() == goodwire)
107 self.assertTrue(update.to_wire() == goodwire)
108108
109109 def test_from_text1(self): # type: () -> None
110110 update = dns.message.from_text(update_text)
111111 w = update.to_wire(origin=dns.name.from_text('example'),
112112 want_shuffle=False)
113 self.failUnless(w == goodwire)
113 self.assertTrue(w == goodwire)
114114
115115 if __name__ == '__main__':
116116 unittest.main()
5858 """Get data one by one item"""
5959 data = b'0123456789'
6060 inst = WireData(data)
61 for i, byte in enumerate(bytearray(data)):
61 for i, byte in enumerate(data):
6262 self.assertEqual(inst[i], byte)
6363 for i in range(-1, len(data) * -1, -1):
64 self.assertEqual(inst[i], bytearray(data)[i])
64 self.assertEqual(inst[i], data[i])
6565
6666 def testEmptySlice(self):
6767 """Test empty slice"""
146146 finally:
147147 if not _keep_output:
148148 os.unlink(here('example1.out'))
149 self.failUnless(ok)
149 self.assertTrue(ok)
150150
151151 def testFromFile2(self): # type: () -> None
152152 z = dns.zone.from_file(here('example'), 'example', relativize=False)
158158 finally:
159159 if not _keep_output:
160160 os.unlink(here('example2.out'))
161 self.failUnless(ok)
161 self.assertTrue(ok)
162162
163163 def testToFileTextualStream(self): # type: () -> None
164164 z = dns.zone.from_text(example_text, 'example.', relativize=True)
187187 finally:
188188 if not _keep_output:
189189 os.unlink(here('example3-textual.out'))
190 self.failUnless(ok)
190 self.assertTrue(ok)
191191
192192 def testToFileBinary(self): # type: () -> None
193193 z = dns.zone.from_file(here('example'), 'example')
200200 finally:
201201 if not _keep_output:
202202 os.unlink(here('example3-binary.out'))
203 self.failUnless(ok)
203 self.assertTrue(ok)
204204
205205 def testToFileFilename(self): # type: () -> None
206206 z = dns.zone.from_file(here('example'), 'example')
211211 finally:
212212 if not _keep_output:
213213 os.unlink(here('example3-filename.out'))
214 self.failUnless(ok)
214 self.assertTrue(ok)
215215
216216 def testToText(self): # type: () -> None
217217 z = dns.zone.from_file(here('example'), 'example')
226226 finally:
227227 if not _keep_output:
228228 os.unlink(here('example3.out'))
229 self.failUnless(ok)
229 self.assertTrue(ok)
230230
231231 def testFromText(self): # type: () -> None
232232 z = dns.zone.from_text(example_text, 'example.', relativize=True)
235235 names.sort()
236236 for n in names:
237237 f.write(z[n].to_text(n))
238 f.write(u'\n')
238 f.write('\n')
239239 self.assertEqual(f.getvalue(), example_text_output)
240240
241241 def testTorture1(self): # type: () -> None
257257 rd2 = dns.rdata.from_wire(rds.rdclass, rds.rdtype,
258258 wire, 0, len(wire),
259259 origin=o)
260 self.failUnless(rd == rd2)
260 self.assertTrue(rd == rd2)
261261
262262 def testEqual(self): # type: () -> None
263263 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
264264 z2 = dns.zone.from_text(example_text_output, 'example.',
265265 relativize=True)
266 self.failUnless(z1 == z2)
266 self.assertTrue(z1 == z2)
267267
268268 def testNotEqual1(self): # type: () -> None
269269 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
270270 z2 = dns.zone.from_text(something_quite_similar, 'example.',
271271 relativize=True)
272 self.failUnless(z1 != z2)
272 self.assertTrue(z1 != z2)
273273
274274 def testNotEqual2(self): # type: () -> None
275275 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
276276 z2 = dns.zone.from_text(something_different, 'example.',
277277 relativize=True)
278 self.failUnless(z1 != z2)
278 self.assertTrue(z1 != z2)
279279
280280 def testNotEqual3(self): # type: () -> None
281281 z1 = dns.zone.from_text(example_text, 'example.', relativize=True)
282282 z2 = dns.zone.from_text(something_different, 'example2.',
283283 relativize=True)
284 self.failUnless(z1 != z2)
284 self.assertTrue(z1 != z2)
285285
286286 def testFindRdataset1(self): # type: () -> None
287287 z = dns.zone.from_text(example_text, 'example.', relativize=True)
288288 rds = z.find_rdataset('@', 'soa')
289289 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
290 self.failUnless(rds == exrds)
290 self.assertTrue(rds == exrds)
291291
292292 def testFindRdataset2(self): # type: () -> None
293293 def bad(): # type: () -> None
294294 z = dns.zone.from_text(example_text, 'example.', relativize=True)
295295 z.find_rdataset('@', 'loc')
296 self.failUnlessRaises(KeyError, bad)
296 self.assertRaises(KeyError, bad)
297297
298298 def testFindRRset1(self): # type: () -> None
299299 z = dns.zone.from_text(example_text, 'example.', relativize=True)
300300 rrs = z.find_rrset('@', 'soa')
301301 exrrs = dns.rrset.from_text('@', 300, 'IN', 'SOA', 'foo bar 1 2 3 4 5')
302 self.failUnless(rrs == exrrs)
302 self.assertTrue(rrs == exrrs)
303303
304304 def testFindRRset2(self): # type: () -> None
305305 def bad(): # type: () -> None
306306 z = dns.zone.from_text(example_text, 'example.', relativize=True)
307307 z.find_rrset('@', 'loc')
308 self.failUnlessRaises(KeyError, bad)
308 self.assertRaises(KeyError, bad)
309309
310310 def testGetRdataset1(self): # type: () -> None
311311 z = dns.zone.from_text(example_text, 'example.', relativize=True)
312312 rds = z.get_rdataset('@', 'soa')
313313 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
314 self.failUnless(rds == exrds)
314 self.assertTrue(rds == exrds)
315315
316316 def testGetRdataset2(self): # type: () -> None
317317 z = dns.zone.from_text(example_text, 'example.', relativize=True)
318318 rds = z.get_rdataset('@', 'loc')
319 self.failUnless(rds is None)
319 self.assertTrue(rds is None)
320320
321321 def testGetRRset1(self): # type: () -> None
322322 z = dns.zone.from_text(example_text, 'example.', relativize=True)
323323 rrs = z.get_rrset('@', 'soa')
324324 exrrs = dns.rrset.from_text('@', 300, 'IN', 'SOA', 'foo bar 1 2 3 4 5')
325 self.failUnless(rrs == exrrs)
325 self.assertTrue(rrs == exrrs)
326326
327327 def testGetRRset2(self): # type: () -> None
328328 z = dns.zone.from_text(example_text, 'example.', relativize=True)
329329 rrs = z.get_rrset('@', 'loc')
330 self.failUnless(rrs is None)
330 self.assertTrue(rrs is None)
331331
332332 def testReplaceRdataset1(self): # type: () -> None
333333 z = dns.zone.from_text(example_text, 'example.', relativize=True)
334334 rdataset = dns.rdataset.from_text('in', 'ns', 300, 'ns3', 'ns4')
335335 z.replace_rdataset('@', rdataset)
336336 rds = z.get_rdataset('@', 'ns')
337 self.failUnless(rds is rdataset)
337 self.assertTrue(rds is rdataset)
338338
339339 def testReplaceRdataset2(self): # type: () -> None
340340 z = dns.zone.from_text(example_text, 'example.', relativize=True)
341341 rdataset = dns.rdataset.from_text('in', 'txt', 300, '"foo"')
342342 z.replace_rdataset('@', rdataset)
343343 rds = z.get_rdataset('@', 'txt')
344 self.failUnless(rds is rdataset)
344 self.assertTrue(rds is rdataset)
345345
346346 def testDeleteRdataset1(self): # type: () -> None
347347 z = dns.zone.from_text(example_text, 'example.', relativize=True)
348348 z.delete_rdataset('@', 'ns')
349349 rds = z.get_rdataset('@', 'ns')
350 self.failUnless(rds is None)
350 self.assertTrue(rds is None)
351351
352352 def testDeleteRdataset2(self): # type: () -> None
353353 z = dns.zone.from_text(example_text, 'example.', relativize=True)
354354 z.delete_rdataset('ns1', 'a')
355355 node = z.get_node('ns1')
356 self.failUnless(node is None)
356 self.assertTrue(node is None)
357357
358358 def testNodeFindRdataset1(self): # type: () -> None
359359 z = dns.zone.from_text(example_text, 'example.', relativize=True)
360360 node = z['@']
361361 rds = node.find_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
362362 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
363 self.failUnless(rds == exrds)
363 self.assertTrue(rds == exrds)
364364
365365 def testNodeFindRdataset2(self): # type: () -> None
366366 def bad(): # type: () -> None
367367 z = dns.zone.from_text(example_text, 'example.', relativize=True)
368368 node = z['@']
369369 node.find_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
370 self.failUnlessRaises(KeyError, bad)
370 self.assertRaises(KeyError, bad)
371371
372372 def testNodeGetRdataset1(self): # type: () -> None
373373 z = dns.zone.from_text(example_text, 'example.', relativize=True)
374374 node = z['@']
375375 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
376376 exrds = dns.rdataset.from_text('IN', 'SOA', 300, 'foo bar 1 2 3 4 5')
377 self.failUnless(rds == exrds)
377 self.assertTrue(rds == exrds)
378378
379379 def testNodeGetRdataset2(self): # type: () -> None
380380 z = dns.zone.from_text(example_text, 'example.', relativize=True)
381381 node = z['@']
382382 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
383 self.failUnless(rds is None)
383 self.assertTrue(rds is None)
384384
385385 def testNodeDeleteRdataset1(self): # type: () -> None
386386 z = dns.zone.from_text(example_text, 'example.', relativize=True)
387387 node = z['@']
388388 node.delete_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
389389 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
390 self.failUnless(rds is None)
390 self.assertTrue(rds is None)
391391
392392 def testNodeDeleteRdataset2(self): # type: () -> None
393393 z = dns.zone.from_text(example_text, 'example.', relativize=True)
394394 node = z['@']
395395 node.delete_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
396396 rds = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.LOC)
397 self.failUnless(rds is None)
397 self.assertTrue(rds is None)
398398
399399 def testIterateRdatasets(self): # type: () -> None
400400 z = dns.zone.from_text(example_text, 'example.', relativize=True)
401401 ns = [n for n, r in z.iterate_rdatasets('A')]
402402 ns.sort()
403 self.failUnless(ns == [dns.name.from_text('ns1', None),
403 self.assertTrue(ns == [dns.name.from_text('ns1', None),
404404 dns.name.from_text('ns2', None)])
405405
406406 def testIterateAllRdatasets(self): # type: () -> None
407407 z = dns.zone.from_text(example_text, 'example.', relativize=True)
408408 ns = [n for n, r in z.iterate_rdatasets()]
409409 ns.sort()
410 self.failUnless(ns == [dns.name.from_text('@', None),
410 self.assertTrue(ns == [dns.name.from_text('@', None),
411411 dns.name.from_text('@', None),
412412 dns.name.from_text('bar.foo', None),
413413 dns.name.from_text('ns1', None),
425425 3600,
426426 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
427427 '10.0.0.2'))]
428 self.failUnless(l == exl)
428 self.assertTrue(l == exl)
429429
430430 def testIterateAllRdatas(self): # type: () -> None
431431 z = dns.zone.from_text(example_text, 'example.', relativize=True)
456456 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
457457 '10.0.0.2'))]
458458 exl.sort(key=_rdata_sort)
459 self.failUnless(l == exl)
459 self.assertTrue(l == exl)
460460
461461 def testTTLs(self): # type: () -> None
462462 z = dns.zone.from_text(ttl_example_text, 'example.', relativize=True)
463463 n = z['@'] # type: dns.node.Node
464464 rds = cast(dns.rdataset.Rdataset, n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA))
465 self.failUnless(rds.ttl == 3600)
465 self.assertTrue(rds.ttl == 3600)
466466 n = z['ns1']
467467 rds = cast(dns.rdataset.Rdataset, n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A))
468 self.failUnless(rds.ttl == 86401)
468 self.assertTrue(rds.ttl == 86401)
469469 n = z['ns2']
470470 rds = cast(dns.rdataset.Rdataset, n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A))
471 self.failUnless(rds.ttl == 694861)
471 self.assertTrue(rds.ttl == 694861)
472472
473473 def testTTLFromSOA(self): # type: () -> None
474474 z = dns.zone.from_text(ttl_from_soa_text, 'example.', relativize=True)
475475 n = z['@']
476476 rds = cast(dns.rdataset.Rdataset, n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.SOA))
477 self.failUnless(rds.ttl == 3600)
477 self.assertTrue(rds.ttl == 3600)
478478 soa_rd = rds[0]
479479 n = z['ns1']
480480 rds = cast(dns.rdataset.Rdataset, n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A))
481 self.failUnless(rds.ttl == 694861)
481 self.assertTrue(rds.ttl == 694861)
482482 n = z['ns2']
483483 rds = cast(dns.rdataset.Rdataset, n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A))
484 self.failUnless(rds.ttl == soa_rd.minimum)
484 self.assertTrue(rds.ttl == soa_rd.minimum)
485485
486486 def testTTLFromLast(self): # type: () -> None
487487 z = dns.zone.from_text(ttl_from_last_text, 'example.', check_origin=False)
488488 n = z['@']
489489 rds = cast(dns.rdataset.Rdataset, n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.NS))
490 self.failUnless(rds.ttl == 3600)
490 self.assertTrue(rds.ttl == 3600)
491491 n = z['ns1']
492492 rds = cast(dns.rdataset.Rdataset, n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A))
493 self.failUnless(rds.ttl == 3600)
493 self.assertTrue(rds.ttl == 3600)
494494 n = z['ns2']
495495 rds = cast(dns.rdataset.Rdataset, n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A))
496 self.failUnless(rds.ttl == 694861)
496 self.assertTrue(rds.ttl == 694861)
497497
498498 def testNoTTL(self): # type: () -> None
499499 def bad(): # type: () -> None
500500 dns.zone.from_text(no_ttl_text, 'example.', check_origin=False)
501 self.failUnlessRaises(dns.exception.SyntaxError, bad)
501 self.assertRaises(dns.exception.SyntaxError, bad)
502502
503503 def testNoSOA(self): # type: () -> None
504504 def bad(): # type: () -> None
505505 dns.zone.from_text(no_soa_text, 'example.', relativize=True)
506 self.failUnlessRaises(dns.zone.NoSOA, bad)
506 self.assertRaises(dns.zone.NoSOA, bad)
507507
508508 def testNoNS(self): # type: () -> None
509509 def bad(): # type: () -> None
510510 dns.zone.from_text(no_ns_text, 'example.', relativize=True)
511 self.failUnlessRaises(dns.zone.NoNS, bad)
511 self.assertRaises(dns.zone.NoNS, bad)
512512
513513 def testInclude(self): # type: () -> None
514514 z1 = dns.zone.from_text(include_text, 'example.', relativize=True,
515515 allow_include=True)
516516 z2 = dns.zone.from_file(here('example'), 'example.', relativize=True)
517 self.failUnless(z1 == z2)
517 self.assertTrue(z1 == z2)
518518
519519 def testBadDirective(self): # type: () -> None
520520 def bad(): # type: () -> None
521521 dns.zone.from_text(bad_directive_text, 'example.', relativize=True)
522 self.failUnlessRaises(dns.exception.SyntaxError, bad)
522 self.assertRaises(dns.exception.SyntaxError, bad)
523523
524524 def testFirstRRStartsWithWhitespace(self): # type: () -> None
525525 # no name is specified, so default to the initial origin
527527 check_origin=False)
528528 n = z['@']
529529 rds = cast(dns.rdataset.Rdataset, n.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A))
530 self.failUnless(rds.ttl == 300)
530 self.assertTrue(rds.ttl == 300)
531531
532532 def testZoneOrigin(self): # type: () -> None
533533 z = dns.zone.Zone('example.')
534 self.failUnless(z.origin == dns.name.from_text('example.'))
534 self.assertTrue(z.origin == dns.name.from_text('example.'))
535535 def bad1(): # type: () -> None
536536 o = dns.name.from_text('example', None)
537537 dns.zone.Zone(o)
538 self.failUnlessRaises(ValueError, bad1)
538 self.assertRaises(ValueError, bad1)
539539 def bad2(): # type: () -> None
540540 dns.zone.Zone(cast(str, 1.0))
541 self.failUnlessRaises(ValueError, bad2)
541 self.assertRaises(ValueError, bad2)
542542
543543 def testZoneOriginNone(self): # type: () -> None
544544 dns.zone.Zone(cast(str, None))
00 [tox]
11 envlist =
2 py27,
3 py34,
42 py35,
53 py36,
64 py37,
1513 python setup.py test
1614
1715 deps=
18
19 [testenv:py27]
20 deps =
21 typing
22
2316
2417 [testenv:flake8]
2518 commands =