diff options
| author | Bob Halley <halley@dnspython.org> | 2020-07-17 17:09:42 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-17 17:09:42 -0700 |
| commit | c5b5c805514cb272c61cf98a75677f0c95110a69 (patch) | |
| tree | c62f957bd25005709941487e4a9684a46748bee9 | |
| parent | 1836e45b701352ec86de5517b2c3e017e5189708 (diff) | |
| parent | 19597bc9205c8065433ca05587ba8bf582722f56 (diff) | |
| download | dnspython-c5b5c805514cb272c61cf98a75677f0c95110a69.tar.gz | |
Merge pull request #540 from bwelling/edns-option-registration
Add dns.edns.register_type().
| -rw-r--r-- | dns/edns.py | 10 | ||||
| -rw-r--r-- | doc/message-edns.rst | 1 | ||||
| -rw-r--r-- | tests/test_edns.py | 37 |
3 files changed, 48 insertions, 0 deletions
diff --git a/dns/edns.py b/dns/edns.py index 28718d5..05f76e6 100644 --- a/dns/edns.py +++ b/dns/edns.py @@ -342,3 +342,13 @@ def option_from_wire(otype, wire, current, olen): parser = dns.wire.Parser(wire, current) with parser.restrict_to(olen): return option_from_wire_parser(otype, parser) + +def register_type(implementation, otype): + """Register the implementation of an option type. + + *implementation*, a ``class``, is a subclass of ``dns.edns.Option``. + + *otype*, an ``int``, is the option type. + """ + + _type_to_class[otype] = implementation diff --git a/doc/message-edns.rst b/doc/message-edns.rst index 7317a02..b46cf54 100644 --- a/doc/message-edns.rst +++ b/doc/message-edns.rst @@ -32,3 +32,4 @@ will create a ``dns.edns.ECSOption`` object to represent it. .. autofunction:: dns.edns.get_option_class .. autofunction:: dns.edns.option_from_wire_parser .. autofunction:: dns.edns.option_from_wire +.. autofunction:: dns.edns.register_type diff --git a/tests/test_edns.py b/tests/test_edns.py index a640a74..e5dca06 100644 --- a/tests/test_edns.py +++ b/tests/test_edns.py @@ -17,6 +17,7 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import operator +import struct import unittest from io import BytesIO @@ -138,3 +139,39 @@ class OptionTestCase(unittest.TestCase): self.assertTrue(o1 != o2) self.assertFalse(o1 == 123) self.assertTrue(o1 != 123) + + def test_option_registration(self): + U32OptionType = 9999 + + class U32Option(dns.edns.Option): + def __init__(self, value=None): + super().__init__(U32OptionType) + self.value = value + + def to_wire(self, file=None): + data = struct.pack('!I', self.value) + if file: + file.write(data) + else: + return data + + @classmethod + def from_wire_parser(cls, otype, parser): + (value,) = parser.get_struct('!I') + return cls(value) + + try: + dns.edns.register_type(U32Option, U32OptionType) + generic = dns.edns.GenericOption(U32OptionType, b'\x00\x00\x00\x01') + wire1 = generic.to_wire() + u32 = dns.edns.option_from_wire_parser(U32OptionType, + dns.wire.Parser(wire1)) + self.assertEqual(u32.value, 1) + wire2 = u32.to_wire() + self.assertEqual(wire1, wire2) + self.assertEqual(u32, generic) + finally: + dns.edns._type_to_class.pop(U32OptionType, None) + + opt = dns.edns.option_from_wire_parser(9999, dns.wire.Parser(wire1)) + self.assertEqual(opt, generic) |
