commit 0d01ad60bb2a4ea2f0ac1f9626360d5db22858ea Author: Damian Johnson atagar@torproject.org Date: Fri Dec 7 09:13:46 2012 -0800
Support for bridge-ip-versions extrainfo desc lines
Adding parsing support for 'bridge-ip-versions' lines in extra-info descriptors. These are fields only relevant to bridges (though the spec doesn't prohibit them from appearing elsewhere). They're pretty much the same thing as the IPVersions in CLIENTS_SEEN events, so borrowing its parsing.
Spec addition: https://gitweb.torproject.org/torspec.git/commitdiff/9a518d9 Metrics-lib addition: https://gitweb.torproject.org/metrics-lib.git/commitdiff/17e9149 --- stem/descriptor/extrainfo_descriptor.py | 18 ++++++++++++++++++ test/unit/descriptor/extrainfo_descriptor.py | 11 +++++++++++ 2 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/stem/descriptor/extrainfo_descriptor.py b/stem/descriptor/extrainfo_descriptor.py index 582c409..7b901c8 100644 --- a/stem/descriptor/extrainfo_descriptor.py +++ b/stem/descriptor/extrainfo_descriptor.py @@ -824,9 +824,12 @@ class BridgeExtraInfoDescriptor(ExtraInfoDescriptor): """ Bridge extra-info descriptor (`bridge descriptor specification https://metrics.torproject.org/formats.html#bridgedesc`_) + + :var dict ip_versions: mapping of ip protocols to a rounded count for the number of users """
def __init__(self, raw_contents, validate = True): + self.ip_versions = None self._digest = None
super(BridgeExtraInfoDescriptor, self).__init__(raw_contents, validate) @@ -848,6 +851,21 @@ class BridgeExtraInfoDescriptor(ExtraInfoDescriptor):
self._digest = value del entries["router-digest"] + elif keyword == "bridge-ip-versions": + self.ip_versions = {} + + for entry in value.split(','): + if not '=' in entry: + raise stem.ProtocolError("The bridge-ip-versions should be a comma separated listing of '<protocol>=<count>' mappings: %s" % line) + + protocol, count = entry.split('=', 1) + + if not count.isdigit(): + raise stem.ProtocolError("IP protocol count was non-numeric (%s): %s" % (count, line)) + + self.ip_versions[protocol] = int(count) + + del entries["bridge-ip-versions"]
ExtraInfoDescriptor._parse(self, entries, validate)
diff --git a/test/unit/descriptor/extrainfo_descriptor.py b/test/unit/descriptor/extrainfo_descriptor.py index dc64032..c009463 100644 --- a/test/unit/descriptor/extrainfo_descriptor.py +++ b/test/unit/descriptor/extrainfo_descriptor.py @@ -458,6 +458,17 @@ class TestExtraInfoDescriptor(unittest.TestCase): # check that we don't have crypto fields self.assertRaises(AttributeError, getattr, desc, "signature")
+ def test_bridge_ip_versions_line(self): + """ + Parses the 'bridge-ip-versions' line, which only appears in bridges. + """ + + desc = get_bridge_extrainfo_descriptor({"bridge-ip-versions": "v4=16,v6=40"}) + self.assertEquals({'v4': 16, 'v6': 40}, desc.ip_versions) + + desc_text = get_bridge_extrainfo_descriptor({"bridge-ip-versions": "v4=24.5"}, content = True) + self.assertRaises(ValueError, RelayExtraInfoDescriptor, desc_text) + def test_transport_line(self): """ Basic exercise for both a bridge and relay's transport entry.