1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """DNS Names.
19 """
20
21 from io import BytesIO
22 import struct
23 import sys
24 import copy
25 import encodings.idna
26 try:
27 import idna
28 have_idna_2008 = True
29 except ImportError:
30 have_idna_2008 = False
31
32 import dns.exception
33 import dns.wiredata
34
35 from ._compat import long, binary_type, text_type, unichr, maybe_decode
36
37 try:
38 maxint = sys.maxint
39 except AttributeError:
40 maxint = (1 << (8 * struct.calcsize("P"))) // 2 - 1
41
42
43
44
45
46 NAMERELN_NONE = 0
47
48 NAMERELN_SUPERDOMAIN = 1
49
50 NAMERELN_SUBDOMAIN = 2
51
52 NAMERELN_EQUAL = 3
53
54 NAMERELN_COMMONANCESTOR = 4
55
56
58 """A DNS label is empty."""
59
60
62 """An escaped code in a text format of DNS name is invalid."""
63
64
66 """A DNS compression pointer points forward instead of backward."""
67
68
70 """The label type in DNS name wire format is unknown."""
71
72
74 """An attempt was made to convert a non-absolute name to
75 wire when there was also a non-absolute (or missing) origin."""
76
77
80
81
84
85
87 """An attempt was made to append anything other than the
88 empty name to an absolute DNS name."""
89
90
91 -class NoParent(dns.exception.DNSException):
92 """An attempt was made to get the parent of the root name
93 or the empty name."""
94
96 """IDNA 2008 processing was requested but the idna module is not
97 available."""
98
99
101 """IDNA processing raised an exception."""
102
103 supp_kwargs = {'idna_exception'}
104 fmt = "IDNA processing exception: {idna_exception}"
105
106
108 """Abstract base class for IDNA encoder/decoders."""
109
112
114 raise NotImplementedError
115
117
118 downcased = label.lower()
119 if downcased.startswith(b'xn--'):
120 try:
121 label = downcased[4:].decode('punycode')
122 except Exception as e:
123 raise IDNAException(idna_exception=e)
124 else:
125 label = maybe_decode(label)
126 return _escapify(label, True)
127
128
130 """IDNA 2003 encoder/decoder."""
131
132 - def __init__(self, strict_decode=False):
133 """Initialize the IDNA 2003 encoder/decoder.
134
135 *strict_decode* is a ``bool``. If `True`, then IDNA2003 checking
136 is done when decoding. This can cause failures if the name
137 was encoded with IDNA2008. The default is `False`.
138 """
139
140 super(IDNA2003Codec, self).__init__()
141 self.strict_decode = strict_decode
142
144 """Encode *label*."""
145
146 if label == '':
147 return b''
148 try:
149 return encodings.idna.ToASCII(label)
150 except UnicodeError:
151 raise LabelTooLong
152
154 """Decode *label*."""
155 if not self.strict_decode:
156 return super(IDNA2003Codec, self).decode(label)
157 if label == b'':
158 return u''
159 try:
160 return _escapify(encodings.idna.ToUnicode(label), True)
161 except Exception as e:
162 raise IDNAException(idna_exception=e)
163
164
166 """IDNA 2008 encoder/decoder.
167
168 *uts_46* is a ``bool``. If True, apply Unicode IDNA
169 compatibility processing as described in Unicode Technical
170 Standard #46 (http://unicode.org/reports/tr46/).
171 If False, do not apply the mapping. The default is False.
172
173 *transitional* is a ``bool``: If True, use the
174 "transitional" mode described in Unicode Technical Standard
175 #46. The default is False.
176
177 *allow_pure_ascii* is a ``bool``. If True, then a label which
178 consists of only ASCII characters is allowed. This is less
179 strict than regular IDNA 2008, but is also necessary for mixed
180 names, e.g. a name with starting with "_sip._tcp." and ending
181 in an IDN suffix which would otherwise be disallowed. The
182 default is False.
183
184 *strict_decode* is a ``bool``: If True, then IDNA2008 checking
185 is done when decoding. This can cause failures if the name
186 was encoded with IDNA2003. The default is False.
187 """
188
189 - def __init__(self, uts_46=False, transitional=False,
190 allow_pure_ascii=False, strict_decode=False):
191 """Initialize the IDNA 2008 encoder/decoder."""
192 super(IDNA2008Codec, self).__init__()
193 self.uts_46 = uts_46
194 self.transitional = transitional
195 self.allow_pure_ascii = allow_pure_ascii
196 self.strict_decode = strict_decode
197
199 for c in label:
200 if ord(c) > 0x7f:
201 return False
202 return True
203
205 if label == '':
206 return b''
207 if self.allow_pure_ascii and self.is_all_ascii(label):
208 return label.encode('ascii')
209 if not have_idna_2008:
210 raise NoIDNA2008
211 try:
212 if self.uts_46:
213 label = idna.uts46_remap(label, False, self.transitional)
214 return idna.alabel(label)
215 except idna.IDNAError as e:
216 raise IDNAException(idna_exception=e)
217
219 if not self.strict_decode:
220 return super(IDNA2008Codec, self).decode(label)
221 if label == b'':
222 return u''
223 if not have_idna_2008:
224 raise NoIDNA2008
225 try:
226 if self.uts_46:
227 label = idna.uts46_remap(label, False, False)
228 return _escapify(idna.ulabel(label), True)
229 except idna.IDNAError as e:
230 raise IDNAException(idna_exception=e)
231
232 _escaped = bytearray(b'"().;\\@$')
233
234 IDNA_2003_Practical = IDNA2003Codec(False)
235 IDNA_2003_Strict = IDNA2003Codec(True)
236 IDNA_2003 = IDNA_2003_Practical
237 IDNA_2008_Practical = IDNA2008Codec(True, False, True, False)
238 IDNA_2008_UTS_46 = IDNA2008Codec(True, False, False, False)
239 IDNA_2008_Strict = IDNA2008Codec(False, False, False, True)
240 IDNA_2008_Transitional = IDNA2008Codec(True, True, False, False)
241 IDNA_2008 = IDNA_2008_Practical
242
244 """Escape the characters in label which need it.
245 @param unicode_mode: escapify only special and whitespace (<= 0x20)
246 characters
247 @returns: the escaped string
248 @rtype: string"""
249 if not unicode_mode:
250 text = ''
251 if isinstance(label, text_type):
252 label = label.encode()
253 for c in bytearray(label):
254 if c in _escaped:
255 text += '\\' + chr(c)
256 elif c > 0x20 and c < 0x7F:
257 text += chr(c)
258 else:
259 text += '\\%03d' % c
260 return text.encode()
261
262 text = u''
263 if isinstance(label, binary_type):
264 label = label.decode()
265 for c in label:
266 if c > u'\x20' and c < u'\x7f':
267 text += c
268 else:
269 if c >= u'\x7f':
270 text += c
271 else:
272 text += u'\\%03d' % ord(c)
273 return text
274
276 """Check for empty labels in the middle of a label sequence,
277 labels that are too long, and for too many labels.
278
279 Raises ``dns.name.NameTooLong`` if the name as a whole is too long.
280
281 Raises ``dns.name.EmptyLabel`` if a label is empty (i.e. the root
282 label) and appears in a position other than the end of the label
283 sequence
284
285 """
286
287 l = len(labels)
288 total = 0
289 i = -1
290 j = 0
291 for label in labels:
292 ll = len(label)
293 total += ll + 1
294 if ll > 63:
295 raise LabelTooLong
296 if i < 0 and label == b'':
297 i = j
298 j += 1
299 if total > 255:
300 raise NameTooLong
301 if i >= 0 and i != l - 1:
302 raise EmptyLabel
303
304
306 """If label is ``text``, convert it to ``binary``. If it is already
307 ``binary`` just return it.
308
309 """
310
311 if isinstance(label, binary_type):
312 return label
313 if isinstance(label, text_type):
314 return label.encode()
315 raise ValueError
316
317
319
320 """A DNS name.
321
322 The dns.name.Name class represents a DNS name as a tuple of
323 labels. Each label is a `binary` in DNS wire format. Instances
324 of the class are immutable.
325 """
326
327 __slots__ = ['labels']
328
330 """*labels* is any iterable whose values are ``text`` or ``binary``.
331 """
332
333 labels = [_maybe_convert_to_binary(x) for x in labels]
334 super(Name, self).__setattr__('labels', tuple(labels))
335 _validate_labels(self.labels)
336
338
339 raise TypeError("object doesn't support attribute assignment")
340
343
346
348
349 return {'labels': self.labels}
350
354
356 """Is the most significant label of this name the root label?
357
358 Returns a ``bool``.
359 """
360
361 return len(self.labels) > 0 and self.labels[-1] == b''
362
364 """Is this name wild? (I.e. Is the least significant label '*'?)
365
366 Returns a ``bool``.
367 """
368
369 return len(self.labels) > 0 and self.labels[0] == b'*'
370
372 """Return a case-insensitive hash of the name.
373
374 Returns an ``int``.
375 """
376
377 h = long(0)
378 for label in self.labels:
379 for c in bytearray(label.lower()):
380 h += (h << 3) + c
381 return int(h % maxint)
382
384 """Compare two names, returning a 3-tuple
385 ``(relation, order, nlabels)``.
386
387 *relation* describes the relation ship between the names,
388 and is one of: ``dns.name.NAMERELN_NONE``,
389 ``dns.name.NAMERELN_SUPERDOMAIN``, ``dns.name.NAMERELN_SUBDOMAIN``,
390 ``dns.name.NAMERELN_EQUAL``, or ``dns.name.NAMERELN_COMMONANCESTOR``.
391
392 *order* is < 0 if *self* < *other*, > 0 if *self* > *other*, and ==
393 0 if *self* == *other*. A relative name is always less than an
394 absolute name. If both names have the same relativity, then
395 the DNSSEC order relation is used to order them.
396
397 *nlabels* is the number of significant labels that the two names
398 have in common.
399
400 Here are some examples. Names ending in "." are absolute names,
401 those not ending in "." are relative names.
402
403 ============= ============= =========== ===== =======
404 self other relation order nlabels
405 ============= ============= =========== ===== =======
406 www.example. www.example. equal 0 3
407 www.example. example. subdomain > 0 2
408 example. www.example. superdomain < 0 2
409 example1.com. example2.com. common anc. < 0 2
410 example1 example2. none < 0 0
411 example1. example2 none > 0 0
412 ============= ============= =========== ===== =======
413 """
414
415 sabs = self.is_absolute()
416 oabs = other.is_absolute()
417 if sabs != oabs:
418 if sabs:
419 return (NAMERELN_NONE, 1, 0)
420 else:
421 return (NAMERELN_NONE, -1, 0)
422 l1 = len(self.labels)
423 l2 = len(other.labels)
424 ldiff = l1 - l2
425 if ldiff < 0:
426 l = l1
427 else:
428 l = l2
429
430 order = 0
431 nlabels = 0
432 namereln = NAMERELN_NONE
433 while l > 0:
434 l -= 1
435 l1 -= 1
436 l2 -= 1
437 label1 = self.labels[l1].lower()
438 label2 = other.labels[l2].lower()
439 if label1 < label2:
440 order = -1
441 if nlabels > 0:
442 namereln = NAMERELN_COMMONANCESTOR
443 return (namereln, order, nlabels)
444 elif label1 > label2:
445 order = 1
446 if nlabels > 0:
447 namereln = NAMERELN_COMMONANCESTOR
448 return (namereln, order, nlabels)
449 nlabels += 1
450 order = ldiff
451 if ldiff < 0:
452 namereln = NAMERELN_SUPERDOMAIN
453 elif ldiff > 0:
454 namereln = NAMERELN_SUBDOMAIN
455 else:
456 namereln = NAMERELN_EQUAL
457 return (namereln, order, nlabels)
458
459 - def is_subdomain(self, other):
460 """Is self a subdomain of other?
461
462 Note that the notion of subdomain includes equality, e.g.
463 "dnpython.org" is a subdomain of itself.
464
465 Returns a ``bool``.
466 """
467
468 (nr, o, nl) = self.fullcompare(other)
469 if nr == NAMERELN_SUBDOMAIN or nr == NAMERELN_EQUAL:
470 return True
471 return False
472
473 - def is_superdomain(self, other):
474 """Is self a superdomain of other?
475
476 Note that the notion of superdomain includes equality, e.g.
477 "dnpython.org" is a superdomain of itself.
478
479 Returns a ``bool``.
480 """
481
482 (nr, o, nl) = self.fullcompare(other)
483 if nr == NAMERELN_SUPERDOMAIN or nr == NAMERELN_EQUAL:
484 return True
485 return False
486
488 """Return a name which is equal to the current name, but is in
489 DNSSEC canonical form.
490 """
491
492 return Name([x.lower() for x in self.labels])
493
495 if isinstance(other, Name):
496 return self.fullcompare(other)[1] == 0
497 else:
498 return False
499
501 if isinstance(other, Name):
502 return self.fullcompare(other)[1] != 0
503 else:
504 return True
505
507 if isinstance(other, Name):
508 return self.fullcompare(other)[1] < 0
509 else:
510 return NotImplemented
511
513 if isinstance(other, Name):
514 return self.fullcompare(other)[1] <= 0
515 else:
516 return NotImplemented
517
519 if isinstance(other, Name):
520 return self.fullcompare(other)[1] >= 0
521 else:
522 return NotImplemented
523
525 if isinstance(other, Name):
526 return self.fullcompare(other)[1] > 0
527 else:
528 return NotImplemented
529
531 return '<DNS name ' + self.__str__() + '>'
532
535
536 - def to_text(self, omit_final_dot=False):
537 """Convert name to DNS text format.
538
539 *omit_final_dot* is a ``bool``. If True, don't emit the final
540 dot (denoting the root label) for absolute names. The default
541 is False.
542
543 Returns a ``text``.
544 """
545
546 if len(self.labels) == 0:
547 return maybe_decode(b'@')
548 if len(self.labels) == 1 and self.labels[0] == b'':
549 return maybe_decode(b'.')
550 if omit_final_dot and self.is_absolute():
551 l = self.labels[:-1]
552 else:
553 l = self.labels
554 s = b'.'.join(map(_escapify, l))
555 return maybe_decode(s)
556
557 - def to_unicode(self, omit_final_dot=False, idna_codec=None):
558 """Convert name to Unicode text format.
559
560 IDN ACE labels are converted to Unicode.
561
562 *omit_final_dot* is a ``bool``. If True, don't emit the final
563 dot (denoting the root label) for absolute names. The default
564 is False.
565 *idna_codec* specifies the IDNA encoder/decoder. If None, the
566 dns.name.IDNA_2003_Practical encoder/decoder is used.
567 The IDNA_2003_Practical decoder does
568 not impose any policy, it just decodes punycode, so if you
569 don't want checking for compliance, you can use this decoder
570 for IDNA2008 as well.
571
572 Returns a ``text``.
573 """
574
575 if len(self.labels) == 0:
576 return u'@'
577 if len(self.labels) == 1 and self.labels[0] == b'':
578 return u'.'
579 if omit_final_dot and self.is_absolute():
580 l = self.labels[:-1]
581 else:
582 l = self.labels
583 if idna_codec is None:
584 idna_codec = IDNA_2003_Practical
585 return u'.'.join([idna_codec.decode(x) for x in l])
586
588 """Convert name to a format suitable for digesting in hashes.
589
590 The name is canonicalized and converted to uncompressed wire
591 format. All names in wire format are absolute. If the name
592 is a relative name, then an origin must be supplied.
593
594 *origin* is a ``dns.name.Name`` or ``None``. If the name is
595 relative and origin is not ``None``, then origin will be appended
596 to the name.
597
598 Raises ``dns.name.NeedAbsoluteNameOrOrigin`` if the name is
599 relative and no origin was provided.
600
601 Returns a ``binary``.
602 """
603
604 if not self.is_absolute():
605 if origin is None or not origin.is_absolute():
606 raise NeedAbsoluteNameOrOrigin
607 labels = list(self.labels)
608 labels.extend(list(origin.labels))
609 else:
610 labels = self.labels
611 dlabels = [struct.pack('!B%ds' % len(x), len(x), x.lower())
612 for x in labels]
613 return b''.join(dlabels)
614
615 - def to_wire(self, file=None, compress=None, origin=None):
616 """Convert name to wire format, possibly compressing it.
617
618 *file* is the file where the name is emitted (typically a
619 BytesIO file). If ``None`` (the default), a ``binary``
620 containing the wire name will be returned.
621
622 *compress*, a ``dict``, is the compression table to use. If
623 ``None`` (the default), names will not be compressed.
624
625 *origin* is a ``dns.name.Name`` or ``None``. If the name is
626 relative and origin is not ``None``, then *origin* will be appended
627 to it.
628
629 Raises ``dns.name.NeedAbsoluteNameOrOrigin`` if the name is
630 relative and no origin was provided.
631
632 Returns a ``binary`` or ``None``.
633 """
634
635 if file is None:
636 file = BytesIO()
637 want_return = True
638 else:
639 want_return = False
640
641 if not self.is_absolute():
642 if origin is None or not origin.is_absolute():
643 raise NeedAbsoluteNameOrOrigin
644 labels = list(self.labels)
645 labels.extend(list(origin.labels))
646 else:
647 labels = self.labels
648 i = 0
649 for label in labels:
650 n = Name(labels[i:])
651 i += 1
652 if compress is not None:
653 pos = compress.get(n)
654 else:
655 pos = None
656 if pos is not None:
657 value = 0xc000 + pos
658 s = struct.pack('!H', value)
659 file.write(s)
660 break
661 else:
662 if compress is not None and len(n) > 1:
663 pos = file.tell()
664 if pos <= 0x3fff:
665 compress[n] = pos
666 l = len(label)
667 file.write(struct.pack('!B', l))
668 if l > 0:
669 file.write(label)
670 if want_return:
671 return file.getvalue()
672
674 """The length of the name (in labels).
675
676 Returns an ``int``.
677 """
678
679 return len(self.labels)
680
683
686
689
691 """Split a name into a prefix and suffix names at the specified depth.
692
693 *depth* is an ``int`` specifying the number of labels in the suffix
694
695 Raises ``ValueError`` if *depth* was not >= 0 and <= the length of the
696 name.
697
698 Returns the tuple ``(prefix, suffix)``.
699 """
700
701 l = len(self.labels)
702 if depth == 0:
703 return (self, dns.name.empty)
704 elif depth == l:
705 return (dns.name.empty, self)
706 elif depth < 0 or depth > l:
707 raise ValueError(
708 'depth must be >= 0 and <= the length of the name')
709 return (Name(self[: -depth]), Name(self[-depth:]))
710
712 """Return a new name which is the concatenation of self and other.
713
714 Raises ``dns.name.AbsoluteConcatenation`` if the name is
715 absolute and *other* is not the empty name.
716
717 Returns a ``dns.name.Name``.
718 """
719
720 if self.is_absolute() and len(other) > 0:
721 raise AbsoluteConcatenation
722 labels = list(self.labels)
723 labels.extend(list(other.labels))
724 return Name(labels)
725
727 """If the name is a subdomain of *origin*, return a new name which is
728 the name relative to origin. Otherwise return the name.
729
730 For example, relativizing ``www.dnspython.org.`` to origin
731 ``dnspython.org.`` returns the name ``www``. Relativizing ``example.``
732 to origin ``dnspython.org.`` returns ``example.``.
733
734 Returns a ``dns.name.Name``.
735 """
736
737 if origin is not None and self.is_subdomain(origin):
738 return Name(self[: -len(origin)])
739 else:
740 return self
741
743 """If the name is a relative name, return a new name which is the
744 concatenation of the name and origin. Otherwise return the name.
745
746 For example, derelativizing ``www`` to origin ``dnspython.org.``
747 returns the name ``www.dnspython.org.``. Derelativizing ``example.``
748 to origin ``dnspython.org.`` returns ``example.``.
749
750 Returns a ``dns.name.Name``.
751 """
752
753 if not self.is_absolute():
754 return self.concatenate(origin)
755 else:
756 return self
757
759 """Return a name with the relativity desired by the caller.
760
761 If *origin* is ``None``, then the name is returned.
762 Otherwise, if *relativize* is ``True`` the name is
763 relativized, and if *relativize* is ``False`` the name is
764 derelativized.
765
766 Returns a ``dns.name.Name``.
767 """
768
769 if origin:
770 if relativize:
771 return self.relativize(origin)
772 else:
773 return self.derelativize(origin)
774 else:
775 return self
776
778 """Return the parent of the name.
779
780 For example, the parent of ``www.dnspython.org.`` is ``dnspython.org``.
781
782 Raises ``dns.name.NoParent`` if the name is either the root name or the
783 empty name, and thus has no parent.
784
785 Returns a ``dns.name.Name``.
786 """
787
788 if self == root or self == empty:
789 raise NoParent
790 return Name(self.labels[1:])
791
792
793 root = Name([b''])
794
795
796 empty = Name([])
797
799 """Convert unicode text into a Name object.
800
801 Labels are encoded in IDN ACE form according to rules specified by
802 the IDNA codec.
803
804 *text*, a ``text``, is the text to convert into a name.
805
806 *origin*, a ``dns.name.Name``, specifies the origin to
807 append to non-absolute names. The default is the root name.
808
809 *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
810 encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder
811 is used.
812
813 Returns a ``dns.name.Name``.
814 """
815
816 if not isinstance(text, text_type):
817 raise ValueError("input to from_unicode() must be a unicode string")
818 if not (origin is None or isinstance(origin, Name)):
819 raise ValueError("origin must be a Name or None")
820 labels = []
821 label = u''
822 escaping = False
823 edigits = 0
824 total = 0
825 if idna_codec is None:
826 idna_codec = IDNA_2003
827 if text == u'@':
828 text = u''
829 if text:
830 if text == u'.':
831 return Name([b''])
832 for c in text:
833 if escaping:
834 if edigits == 0:
835 if c.isdigit():
836 total = int(c)
837 edigits += 1
838 else:
839 label += c
840 escaping = False
841 else:
842 if not c.isdigit():
843 raise BadEscape
844 total *= 10
845 total += int(c)
846 edigits += 1
847 if edigits == 3:
848 escaping = False
849 label += unichr(total)
850 elif c in [u'.', u'\u3002', u'\uff0e', u'\uff61']:
851 if len(label) == 0:
852 raise EmptyLabel
853 labels.append(idna_codec.encode(label))
854 label = u''
855 elif c == u'\\':
856 escaping = True
857 edigits = 0
858 total = 0
859 else:
860 label += c
861 if escaping:
862 raise BadEscape
863 if len(label) > 0:
864 labels.append(idna_codec.encode(label))
865 else:
866 labels.append(b'')
867
868 if (len(labels) == 0 or labels[-1] != b'') and origin is not None:
869 labels.extend(list(origin.labels))
870 return Name(labels)
871
872
873 -def from_text(text, origin=root, idna_codec=None):
874 """Convert text into a Name object.
875
876 *text*, a ``text``, is the text to convert into a name.
877
878 *origin*, a ``dns.name.Name``, specifies the origin to
879 append to non-absolute names. The default is the root name.
880
881 *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
882 encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder
883 is used.
884
885 Returns a ``dns.name.Name``.
886 """
887
888 if isinstance(text, text_type):
889 return from_unicode(text, origin, idna_codec)
890 if not isinstance(text, binary_type):
891 raise ValueError("input to from_text() must be a string")
892 if not (origin is None or isinstance(origin, Name)):
893 raise ValueError("origin must be a Name or None")
894 labels = []
895 label = b''
896 escaping = False
897 edigits = 0
898 total = 0
899 if text == b'@':
900 text = b''
901 if text:
902 if text == b'.':
903 return Name([b''])
904 for c in bytearray(text):
905 byte_ = struct.pack('!B', c)
906 if escaping:
907 if edigits == 0:
908 if byte_.isdigit():
909 total = int(byte_)
910 edigits += 1
911 else:
912 label += byte_
913 escaping = False
914 else:
915 if not byte_.isdigit():
916 raise BadEscape
917 total *= 10
918 total += int(byte_)
919 edigits += 1
920 if edigits == 3:
921 escaping = False
922 label += struct.pack('!B', total)
923 elif byte_ == b'.':
924 if len(label) == 0:
925 raise EmptyLabel
926 labels.append(label)
927 label = b''
928 elif byte_ == b'\\':
929 escaping = True
930 edigits = 0
931 total = 0
932 else:
933 label += byte_
934 if escaping:
935 raise BadEscape
936 if len(label) > 0:
937 labels.append(label)
938 else:
939 labels.append(b'')
940 if (len(labels) == 0 or labels[-1] != b'') and origin is not None:
941 labels.extend(list(origin.labels))
942 return Name(labels)
943
944
946 """Convert possibly compressed wire format into a Name.
947
948 *message* is a ``binary`` containing an entire DNS message in DNS
949 wire form.
950
951 *current*, an ``int``, is the offset of the beginning of the name
952 from the start of the message
953
954 Raises ``dns.name.BadPointer`` if a compression pointer did not
955 point backwards in the message.
956
957 Raises ``dns.name.BadLabelType`` if an invalid label type was encountered.
958
959 Returns a ``(dns.name.Name, int)`` tuple consisting of the name
960 that was read and the number of bytes of the wire format message
961 which were consumed reading it.
962 """
963
964 if not isinstance(message, binary_type):
965 raise ValueError("input to from_wire() must be a byte string")
966 message = dns.wiredata.maybe_wrap(message)
967 labels = []
968 biggest_pointer = current
969 hops = 0
970 count = message[current]
971 current += 1
972 cused = 1
973 while count != 0:
974 if count < 64:
975 labels.append(message[current: current + count].unwrap())
976 current += count
977 if hops == 0:
978 cused += count
979 elif count >= 192:
980 current = (count & 0x3f) * 256 + message[current]
981 if hops == 0:
982 cused += 1
983 if current >= biggest_pointer:
984 raise BadPointer
985 biggest_pointer = current
986 hops += 1
987 else:
988 raise BadLabelType
989 count = message[current]
990 current += 1
991 if hops == 0:
992 cused += 1
993 labels.append('')
994 return (Name(labels), cused)
995