diff --git a/regression-tests.auth-py/paddingoption.py b/regression-tests.auth-py/paddingoption.py new file mode 120000 index 000000000000..eba474cf3d7a --- /dev/null +++ b/regression-tests.auth-py/paddingoption.py @@ -0,0 +1 @@ +../regression-tests.common/paddingoption.py \ No newline at end of file diff --git a/regression-tests.auth-py/test_EDNSPadding.py b/regression-tests.auth-py/test_EDNSPadding.py new file mode 100644 index 000000000000..13470ca8c4cc --- /dev/null +++ b/regression-tests.auth-py/test_EDNSPadding.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python + +import dns +import os +import socket + +import paddingoption + +from authtests import AuthTest + +class AuthEDNSPaddingTest(AuthTest): + _config_template = """ +launch=bind +""" + + _zones = { + 'example.org': """ +example.org. 3600 IN SOA {soa} +example.org. 3600 IN NS ns1.example.org. +example.org. 3600 IN NS ns2.example.org. +ns1.example.org. 3600 IN A 192.0.2.10 +ns2.example.org. 3600 IN A 192.0.2.11 + +www.example.org. 3600 IN A 192.0.2.5 + """, + } + + @classmethod + def setUpClass(cls): + cls.setUpSockets() + + cls.startResponders() + + confdir = os.path.join('configs', cls._confdir) + cls.createConfigDir(confdir) + + cls.generateAllAuthConfig(confdir) + cls.startAuth(confdir, "0.0.0.0") + + print("Launching tests..") + + @classmethod + def setUpSockets(cls): + print("Setting up UDP socket..") + cls._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + cls._sock.settimeout(2.0) + cls._sock.connect((cls._PREFIX + ".2", cls._authPort)) + + def checkPadding(self, message): + self.assertEqual(message.edns, 0) + self.assertEqual(len(message.options), 1) + for option in message.options: + self.assertEqual(option.otype, 12) + + def checkNoEDNS(self, message): + self.assertEqual(message.edns, -1) + +class TestEDNSPadding(AuthEDNSPaddingTest): + + def testQueryWithPadding(self): + name = 'www.example.org.' + expected = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'A', '192.0.2.5') + po = paddingoption.PaddingOption(64) + query = dns.message.make_query(name, 'A', options=[po]) + res = self.sendUDPQuery(query) + self.checkPadding(res) + self.assertRRsetInAnswer(res, expected) + + def testQueryWithoutPadding(self): + name = 'www.example.org.' + expected = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'A', '192.0.2.5') + query = dns.message.make_query(name, 'A') + res = self.sendUDPQuery(query) + self.checkNoEDNS(res) + self.assertRRsetInAnswer(res, expected) diff --git a/regression-tests.common/paddingoption.py b/regression-tests.common/paddingoption.py new file mode 100644 index 000000000000..728da93a7d09 --- /dev/null +++ b/regression-tests.common/paddingoption.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python + +import dns +import dns.edns +import dns.flags +import dns.message +import dns.query + +class PaddingOption(dns.edns.Option): + """Implementation of rfc7830. + """ + + def __init__(self, numberOfBytes): + super(PaddingOption, self).__init__(12) + self.numberOfBytes = numberOfBytes + + def to_wire(self, file=None): + """Create EDNS packet as defined in rfc7830.""" + + if file: + file.write(bytes(self.numberOfBytes)) + else: + return bytes(self.numberOfBytes) + + def from_wire(cls, otype, wire, current, olen): + """Read EDNS packet as defined in rfc7830. + + Returns: + An instance of PaddingOption based on the EDNS packet + """ + + numberOfBytes = olen + + return cls(numberOfBytes) + + from_wire = classmethod(from_wire) + + # needed in 2.0.0 + @classmethod + def from_wire_parser(cls, otype, parser): + data = parser.get_remaining() + return cls(len(data)) + + def __repr__(self): + return '%s(%d)' % ( + self.__class__.__name__, + self.numberOfBytes + ) + + def __eq__(self, other): + if not isinstance(other, PaddingOption): + return False + return self.numberOfBytes == numberOfBytes + + def __ne__(self, other): + return not self.__eq__(other) + + +dns.edns._type_to_class[0x000C] = PaddingOption diff --git a/regression-tests.recursor-dnssec/paddingoption.py b/regression-tests.recursor-dnssec/paddingoption.py deleted file mode 100644 index 728da93a7d09..000000000000 --- a/regression-tests.recursor-dnssec/paddingoption.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python - -import dns -import dns.edns -import dns.flags -import dns.message -import dns.query - -class PaddingOption(dns.edns.Option): - """Implementation of rfc7830. - """ - - def __init__(self, numberOfBytes): - super(PaddingOption, self).__init__(12) - self.numberOfBytes = numberOfBytes - - def to_wire(self, file=None): - """Create EDNS packet as defined in rfc7830.""" - - if file: - file.write(bytes(self.numberOfBytes)) - else: - return bytes(self.numberOfBytes) - - def from_wire(cls, otype, wire, current, olen): - """Read EDNS packet as defined in rfc7830. - - Returns: - An instance of PaddingOption based on the EDNS packet - """ - - numberOfBytes = olen - - return cls(numberOfBytes) - - from_wire = classmethod(from_wire) - - # needed in 2.0.0 - @classmethod - def from_wire_parser(cls, otype, parser): - data = parser.get_remaining() - return cls(len(data)) - - def __repr__(self): - return '%s(%d)' % ( - self.__class__.__name__, - self.numberOfBytes - ) - - def __eq__(self, other): - if not isinstance(other, PaddingOption): - return False - return self.numberOfBytes == numberOfBytes - - def __ne__(self, other): - return not self.__eq__(other) - - -dns.edns._type_to_class[0x000C] = PaddingOption diff --git a/regression-tests.recursor-dnssec/paddingoption.py b/regression-tests.recursor-dnssec/paddingoption.py new file mode 120000 index 000000000000..eba474cf3d7a --- /dev/null +++ b/regression-tests.recursor-dnssec/paddingoption.py @@ -0,0 +1 @@ +../regression-tests.common/paddingoption.py \ No newline at end of file