This is an automated email from the ASF dual-hosted git repository.
kgiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git
The following commit(s) were added to refs/heads/main by this push:
new 1f384f7 DISPATCH-2310: limit router identifiers to 127 characters
maximum
1f384f7 is described below
commit 1f384f7a038a27987016e4ddbaa23d919bc87a37
Author: Kenneth Giusti <[email protected]>
AuthorDate: Wed Jan 19 18:02:25 2022 -0500
DISPATCH-2310: limit router identifiers to 127 characters maximum
---
include/qpid/dispatch/router.h | 2 +
.../qpid_dispatch_internal/management/qdrouter.py | 43 ++++++++++++---------
tests/system_tests_bad_configuration.py | 44 ++++++++++++++++++++++
tests/system_tests_routing_protocol.py | 12 +++---
4 files changed, 79 insertions(+), 22 deletions(-)
diff --git a/include/qpid/dispatch/router.h b/include/qpid/dispatch/router.h
index 2feaa75..a69cf40 100644
--- a/include/qpid/dispatch/router.h
+++ b/include/qpid/dispatch/router.h
@@ -33,6 +33,8 @@
#include <stdbool.h>
+#define QD_ROUTER_ID_MAX 127 // max length of router id in chars
+
typedef struct qdr_core_t qdr_core_t;
typedef struct qd_router_t qd_router_t;
typedef struct qd_address_t qd_address_t;
diff --git a/python/qpid_dispatch_internal/management/qdrouter.py
b/python/qpid_dispatch_internal/management/qdrouter.py
index 2d406ee..e677f7e 100644
--- a/python/qpid_dispatch_internal/management/qdrouter.py
+++ b/python/qpid_dispatch_internal/management/qdrouter.py
@@ -34,6 +34,7 @@ class QdSchema(schema.Schema):
CONFIGURATION_ENTITY = "configurationEntity"
OPERATIONAL_ENTITY = "operationalEntity"
+ ROUTER_ID_MAX_LEN = 127
def __init__(self):
"""Load schema."""
@@ -53,35 +54,43 @@ class QdSchema(schema.Schema):
entities = list(entities) # Iterate twice
super(QdSchema, self).validate_add(attributes, entities)
entities.append(attributes)
- router_mode = listener_connector_role = listener_role = None
+ router_mode = router_id = listener_connector_role = listener_role =
None
for e in entities:
short_type = self.short_name(e['type'])
if short_type == "router":
router_mode = e['mode']
+ if 'id' in e:
+ router_id = e['id']
if short_type in ["listener", "connector"]:
if short_type == "listener":
listener_role = e['role']
list_conn_entity = e
listener_connector_role = e['role']
- # There are 4 roles for listeners - normal, inter-router,
route-container, edge
- if router_mode and listener_connector_role:
- # Standalone routers cannot have inter-router or edge
listeners/connectors
- if router_mode == "standalone" and listener_connector_role in
('inter-router', 'edge'):
- raise schema.ValidationError(
- "role='standalone' not allowed to connect to or accept
connections from other routers.")
+ if router_id is not None:
+ if len(router_id) > self.ROUTER_ID_MAX_LEN:
+ raise schema.ValidationError(
+ 'Router ID "%s" exceeds the maximum allowed length (%d'
+ ' characters)' % (router_id, self.ROUTER_ID_MAX_LEN))
- # Only interior routers can have inter-router
listeners/connectors
- if router_mode != "interior" and listener_connector_role ==
"inter-router":
- raise schema.ValidationError(
- "role='inter-router' only allowed with router
mode='interior' for %s" % list_conn_entity)
+ # There are 4 roles for listeners - normal, inter-router,
route-container, edge
+ if router_mode and listener_connector_role:
+ # Standalone routers cannot have inter-router or edge
listeners/connectors
+ if router_mode == "standalone" and listener_connector_role in
('inter-router', 'edge'):
+ raise schema.ValidationError(
+ "role='standalone' not allowed to connect to or accept
connections from other routers.")
- if router_mode and listener_role:
- # Edge routers cannot have edge listeners. Other edge routers
cannot make connections into this
- # edge router
- if router_mode == "edge" and listener_role == "edge":
- raise schema.ValidationError(
- "role='edge' only allowed with router mode='interior'
for %s" % list_conn_entity)
+ # Only interior routers can have inter-router listeners/connectors
+ if router_mode != "interior" and listener_connector_role ==
"inter-router":
+ raise schema.ValidationError(
+ "role='inter-router' only allowed with router
mode='interior' for %s" % list_conn_entity)
+
+ if router_mode and listener_role:
+ # Edge routers cannot have edge listeners. Other edge routers
cannot make connections into this
+ # edge router
+ if router_mode == "edge" and listener_role == "edge":
+ raise schema.ValidationError(
+ "role='edge' only allowed with router mode='interior' for
%s" % list_conn_entity)
def is_configuration(self, entity_type):
return entity_type and self.configuration_entity in
entity_type.all_bases
diff --git a/tests/system_tests_bad_configuration.py
b/tests/system_tests_bad_configuration.py
index b80fc20..4d52bb8 100644
--- a/tests/system_tests_bad_configuration.py
+++ b/tests/system_tests_bad_configuration.py
@@ -244,3 +244,47 @@ class RouterTestIdFailWhiteSpace(TestCase):
if "AttributeError" not in out:
print("output: ", out)
assert False, "AttributeError not in process output"
+
+
+class RouterTestIdFailTooLong(TestCase):
+ """
+ This test case sets up a router using a configuration router id
+ that is illegal (too long). The router should not start.
+ """
+ @classmethod
+ def setUpClass(cls):
+ super(RouterTestIdFailTooLong, cls).setUpClass()
+ cls.name = "test-router-id-too-long"
+
+ def __init__(self, test_method):
+ TestCase.__init__(self, test_method)
+
+ @classmethod
+ def tearDownClass(cls):
+ super(RouterTestIdFailTooLong, cls).tearDownClass()
+
+ def test_verify_reject_too_long_id(self):
+ """
+ Writes illegal config, runs router, examines console output
+ """
+ bad_name = 'X' * 128 # max valid name < 128 characters
+ parent_path = os.path.dirname(os.getcwd())
+ conf_path = os.path.join(parent_path,
"setUpClass/test-router-long-id.conf")
+ with open(conf_path, 'w') as router_conf:
+ router_conf.write("router { \n")
+ router_conf.write(" id: %s \n" % bad_name)
+ router_conf.write("}")
+ lib_include_path = os.path.join(os.environ["QPID_DISPATCH_HOME"],
"python")
+ p = self.popen(
+ ['qdrouterd', '-c', conf_path, '-I', lib_include_path],
+ stdin=PIPE, stdout=PIPE, stderr=STDOUT, expect=Process.EXIT_FAIL,
+ universal_newlines=True)
+ out = p.communicate(timeout=TIMEOUT)[0]
+ try:
+ p.teardown()
+ except Exception as e:
+ raise Exception("%s\n%s" % (e, out))
+
+ if p.returncode == 0 or "exceeds the maximum allowed length" not in
out:
+ print("output:\n [%s]\n" % out, flush=True)
+ assert False, "Router accepted an ID of illegal length"
diff --git a/tests/system_tests_routing_protocol.py
b/tests/system_tests_routing_protocol.py
index 552baa7..cbb2e40 100644
--- a/tests/system_tests_routing_protocol.py
+++ b/tests/system_tests_routing_protocol.py
@@ -211,6 +211,8 @@ class HugeRouterIdTest(TestCase):
Deploy a mesh of four routers with ids > 64 octets in length.
"""
+ MAX_ID_LEN = 127
+
@classmethod
def setUpClass(cls):
super(HugeRouterIdTest, cls).setUpClass()
@@ -235,27 +237,27 @@ class HugeRouterIdTest(TestCase):
ir_port_C = cls.tester.get_port()
ir_port_D = cls.tester.get_port()
- name_suffix = "." + "X" * 128
+ name_suffix = "X" * (cls.MAX_ID_LEN - 2)
- cls.RA_name = 'A' + name_suffix
+ cls.RA_name = 'A.' + name_suffix
cls.RA = router(cls.RA_name,
[('listener', {'role': 'inter-router', 'port':
ir_port_A}),
('connector', {'role': 'inter-router', 'port':
ir_port_B}),
('connector', {'role': 'inter-router', 'port':
ir_port_C}),
('connector', {'role': 'inter-router', 'port':
ir_port_D})])
- cls.RB_name = 'B' + name_suffix
+ cls.RB_name = 'B.' + name_suffix
cls.RB = router(cls.RB_name,
[('listener', {'role': 'inter-router', 'port':
ir_port_B}),
('connector', {'role': 'inter-router', 'port':
ir_port_C}),
('connector', {'role': 'inter-router', 'port':
ir_port_D})])
- cls.RC_name = 'C' + name_suffix
+ cls.RC_name = 'C.' + name_suffix
cls.RC = router(cls.RC_name,
[('listener', {'role': 'inter-router', 'port':
ir_port_C}),
('connector', {'role': 'inter-router', 'port':
ir_port_D})])
- cls.RD_name = 'D' + name_suffix
+ cls.RD_name = 'D.' + name_suffix
cls.RD = router(cls.RD_name,
[('listener', {'role': 'inter-router', 'port':
ir_port_D})])
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]