Skip to content

Commit

Permalink
Crude tests for EDNS padding.
Browse files Browse the repository at this point in the history
  • Loading branch information
miodvallat committed Jan 8, 2025
1 parent 304980c commit 63fd053
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 59 deletions.
1 change: 1 addition & 0 deletions regression-tests.auth-py/paddingoption.py
75 changes: 75 additions & 0 deletions regression-tests.auth-py/test_EDNSPadding.py
Original file line number Diff line number Diff line change
@@ -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)
59 changes: 59 additions & 0 deletions regression-tests.common/paddingoption.py
Original file line number Diff line number Diff line change
@@ -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
59 changes: 0 additions & 59 deletions regression-tests.recursor-dnssec/paddingoption.py

This file was deleted.

1 change: 1 addition & 0 deletions regression-tests.recursor-dnssec/paddingoption.py

0 comments on commit 63fd053

Please sign in to comment.