# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+import io
import struct
import dns.exception
file.write(struct.pack('!BB', window, len(bitmap)))
file.write(bitmap)
+ def to_digestable(self, origin=None):
+ file = io.BytesIO()
+ file.write(self.next.to_digestable(origin))
+ for (window, bitmap) in self.windows:
+ file.write(struct.pack('!BB', window, len(bitmap)))
+ file.write(bitmap)
+ return file.getvalue()
+
@classmethod
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
(next, cused) = dns.name.from_wire(wire[: current + rdlen], current)
import dns.rdtypes.mxbase
-class KX(dns.rdtypes.mxbase.UncompressedMX):
+class KX(dns.rdtypes.mxbase.UncompressedDowncasingMX):
"""KX record"""
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+import io
import struct
import dns.exception
_write_string(file, self.regexp)
self.replacement.to_wire(file, compress, origin)
+ def to_digestable(self, origin=None):
+ file = io.BytesIO()
+ two_ints = struct.pack("!HH", self.order, self.preference)
+ file.write(two_ints)
+ _write_string(file, self.flags)
+ _write_string(file, self.service)
+ _write_string(file, self.regexp)
+ return file.getvalue() + self.replacement.to_digestable(origin)
+
@classmethod
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
(order, preference) = struct.unpack('!HH', wire[current: current + 4])
self.map822.to_wire(file, None, origin)
self.mapx400.to_wire(file, None, origin)
+ def to_digestable(self, origin=None):
+ return struct.pack("!H", self.preference) + \
+ self.map822.to_digestable(origin) + \
+ self.mapx400.to_digestable(origin)
+
@classmethod
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
(preference, ) = struct.unpack('!H', wire[current: current + 2])
self.target.to_wire(file, compress, origin)
def to_digestable(self, origin=None):
- # TODO how to avoid code duplication here? This is mostly identical to self.to_wire.
f = io.BytesIO()
f.write(struct.pack("!HHH", self.priority, self.weight, self.port))
f.write(self.target.to_digestable(origin))
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+import io
import unittest
import dns.name
import dns.rdata
import dns.rdataclass
+import dns.rdataset
import dns.rdatatype
import tests.stxt_module
idna_codec=dns.name.IDNA_2008)
self.assertEqual(str(rdata.target), 'xn--knigsgchen-b4a3dun')
+ def test_digestable_downcasing(self):
+ # Make sure all the types listed in RFC 4034 section 6.2 are
+ # downcased properly, except for:
+ #
+ # types we don't implement: MD, MF, MB, MG, MR, MINFO, SIG,
+ # NXT, A6
+ #
+ # types that don't have names: HINFO
+ #
+ # types where the canonical form isn't relevant: RRSIG
+ #
+ cases = [
+ ('SOA', 'NAME NAME 1 2 3 4 5'),
+ ('AFSDB', '0 NAME'),
+ ('CNAME', 'NAME'),
+ ('DNAME', 'NAME'),
+ ('KX', '10 NAME'),
+ ('MX', '10 NAME'),
+ ('NS', 'NAME'),
+ ('NSEC', 'NAME A'),
+ ('NAPTR', '0 0 a B c NAME'),
+ ('PTR', 'NAME'),
+ ('PX', '65535 NAME NAME'),
+ ('RP', 'NAME NAME'),
+ ('RT', '0 NAME'),
+ ('SRV', '0 0 0 NAME'),
+ ]
+ for rdtype, text in cases:
+ upper_origin = dns.name.from_text('EXAMPLE')
+ lower_origin = dns.name.from_text('example')
+ canonical_text = text.replace('NAME', 'name')
+ rdata = dns.rdata.from_text(dns.rdataclass.IN, rdtype, text,
+ origin=upper_origin, relativize=False)
+ canonical_rdata = dns.rdata.from_text(dns.rdataclass.IN, rdtype,
+ canonical_text,
+ origin=lower_origin,
+ relativize=False)
+ digestable_wire = rdata.to_digestable()
+ f = io.BytesIO()
+ canonical_rdata.to_wire(f)
+ expected_wire = f.getvalue()
+ self.assertEqual(digestable_wire, expected_wire)
+
if __name__ == '__main__':
unittest.main()