DISPATCH-364 - Forbid normal link attaches from endpoints on inter-router listeners.
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/d42d3ec2 Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/d42d3ec2 Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/d42d3ec2 Branch: refs/heads/0.6.x Commit: d42d3ec20297ea3297d9d68b5fcf60fb1e3db531 Parents: 7a8aa51 Author: Ted Ross <[email protected]> Authored: Tue Jun 7 13:57:48 2016 -0400 Committer: Ted Ross <[email protected]> Committed: Mon Jun 13 17:22:35 2016 -0400 ---------------------------------------------------------------------- src/router_core/connections.c | 25 +++++++++++++++++++++++++ src/router_core/router_core_private.h | 1 + tests/system_tests_link_routes.py | 24 ++++++++++++------------ 3 files changed, 38 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/d42d3ec2/src/router_core/connections.c ---------------------------------------------------------------------- diff --git a/src/router_core/connections.c b/src/router_core/connections.c index e0543ec..cedf115 100644 --- a/src/router_core/connections.c +++ b/src/router_core/connections.c @@ -502,6 +502,7 @@ static void qdr_link_cleanup_CT(qdr_core_t *core, qdr_connection_t *conn, qdr_li if (dlv->tracking_addr) { int link_bit = link->conn->mask_bit; + assert(link_bit >= 0); dlv->tracking_addr->outstanding_deliveries[link_bit]--; dlv->tracking_addr->tracked_deliveries--; dlv->tracking_addr = 0; @@ -601,6 +602,10 @@ void qdr_link_outbound_detach_CT(qdr_core_t *core, qdr_link_t *link, qdr_error_t work->error = qdr_error("qd:forbidden", "Connectivity to the node is forbidden"); break; + case QDR_CONDITION_WRONG_ROLE: + work->error = qdr_error("qd:connection-role", "Link attach forbidden on inter-router connection"); + break; + case QDR_CONDITION_NONE: work->error = 0; break; @@ -877,6 +882,7 @@ static void qdr_connection_opened_CT(qdr_core_t *core, qdr_action_t *action, boo qd_bitmask_clear_bit(core->neighbor_free_mask, conn->mask_bit); else { qd_log(core->log, QD_LOG_CRITICAL, "Exceeded maximum inter-router connection count"); + conn->role = QDR_ROLE_NORMAL; return; } @@ -927,6 +933,12 @@ static void qdr_connection_closed_CT(qdr_core_t *core, qdr_action_t *action, boo qdr_route_connection_closed_CT(core, conn); // + // Give back the router mask-bit. + // + if (conn->role == QDR_ROLE_INTER_ROUTER) + qd_bitmask_set_bit(core->neighbor_free_mask, conn->mask_bit); + + // // TODO - Clean up links associated with this connection // This involves the links and the dispositions of deliveries stored // with the links. @@ -990,6 +1002,19 @@ static void qdr_link_inbound_first_attach_CT(qdr_core_t *core, qdr_action_t *act return; } + // + // Reject ENDPOINT attaches if this is an inter-router connection _and_ there is no + // CONTROL link on the connection. This will prevent endpoints from using inter-router + // listeners for normal traffic but will not prevent routed-links from being established. + // + if (conn->role == QDR_ROLE_INTER_ROUTER && link->link_type == QD_LINK_ENDPOINT && + core->control_links_by_mask_bit[conn->mask_bit] == 0) { + qdr_link_outbound_detach_CT(core, link, 0, QDR_CONDITION_WRONG_ROLE); + qdr_terminus_free(source); + qdr_terminus_free(target); + return; + } + if (dir == QD_INCOMING) { // // Handle incoming link cases http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/d42d3ec2/src/router_core/router_core_private.h ---------------------------------------------------------------------- diff --git a/src/router_core/router_core_private.h b/src/router_core/router_core_private.h index 0fd5546..1cd9438 100644 --- a/src/router_core/router_core_private.h +++ b/src/router_core/router_core_private.h @@ -46,6 +46,7 @@ typedef enum { QDR_CONDITION_NO_ROUTE_TO_DESTINATION, QDR_CONDITION_ROUTED_LINK_LOST, QDR_CONDITION_FORBIDDEN, + QDR_CONDITION_WRONG_ROLE, QDR_CONDITION_NONE } qdr_condition_t; http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/d42d3ec2/tests/system_tests_link_routes.py ---------------------------------------------------------------------- diff --git a/tests/system_tests_link_routes.py b/tests/system_tests_link_routes.py index 420cc96..b3dbac2 100644 --- a/tests/system_tests_link_routes.py +++ b/tests/system_tests_link_routes.py @@ -100,9 +100,9 @@ class LinkRoutePatternTest(TestCase): ) router('C', [ - ('listener', {'host': '0.0.0.0', 'role': 'inter-router', 'port': c_listener_port, 'saslMechanisms': 'ANONYMOUS'}), # The client will exclusively use the following listener to connect to QDR.C ('listener', {'host': '0.0.0.0', 'role': 'normal', 'port': cls.tester.get_port(), 'saslMechanisms': 'ANONYMOUS'}), + ('listener', {'host': '0.0.0.0', 'role': 'inter-router', 'port': c_listener_port, 'saslMechanisms': 'ANONYMOUS'}), # Note here that the linkRoutePattern is set to org.apache. which makes it backward compatible. # The dot(.) at the end is ignored by the address hashing scheme. ('linkRoutePattern', {'prefix': 'org.apache.'}), @@ -176,7 +176,7 @@ class LinkRoutePatternTest(TestCase): Runs qdstat on router C to make sure that router C has two link routes, one 'in' and one 'out' """ - out = self.run_qdstat_linkRoute(self.routers[2].addresses[1]) + out = self.run_qdstat_linkRoute(self.routers[2].addresses[0]) out_list = out.split() self.assertEqual(out_list.count('in'), 2) @@ -193,7 +193,7 @@ class LinkRoutePatternTest(TestCase): hello_world_1 = "Hello World_1!" # Connects to listener #2 on QDR.C - addr = self.routers[2].addresses[1] + addr = self.routers[2].addresses[0] blocking_connection = BlockingConnection(addr) @@ -279,7 +279,7 @@ class LinkRoutePatternTest(TestCase): """ hello_world_3 = "Hello World_3!" # Connects to listener #2 on QDR.C - addr = self.routers[2].addresses[1] + addr = self.routers[2].addresses[0] blocking_connection = BlockingConnection(addr) @@ -316,7 +316,7 @@ class LinkRoutePatternTest(TestCase): made to router QDR.B instead of QDR.C and we expect the message to be link routed successfully. """ hello_world_4 = "Hello World_4!" - addr = self.routers[2].addresses[0] + addr = self.routers[1].addresses[0] blocking_connection = BlockingConnection(addr) @@ -384,7 +384,7 @@ class LinkRoutePatternTest(TestCase): # will not allow a receiver to be created since there is no route to destination. # Connects to listener #2 on QDR.C - addr = self.routers[2].addresses[1] + addr = self.routers[2].addresses[0] # Now delete linkRoutes on QDR.C to eradicate linkRoutes completely local_node = Node.connect(addr, timeout=TIMEOUT) @@ -433,8 +433,8 @@ class LinkRoutePatternTest(TestCase): Tests that the router carries over the delivery tag on a link routed delivery """ listening_address = self.routers[1].addresses[1] - sender_address = self.routers[2].addresses[1] - qdstat_address = self.routers[2].addresses[1] + sender_address = self.routers[2].addresses[0] + qdstat_address = self.routers[2].addresses[0] test = DeliveryTagsTest(sender_address, listening_address, qdstat_address) test.run() self.assertTrue(test.message_received) @@ -446,22 +446,22 @@ class LinkRoutePatternTest(TestCase): self.assertEqual(None, test.error) def test_www_drain_support_all_messages(self): - drain_support = DrainMessagesHandler(self.routers[2].addresses[1]) + drain_support = DrainMessagesHandler(self.routers[2].addresses[0]) drain_support.run() self.assertEqual(None, drain_support.error) def test_www_drain_support_one_message(self): - drain_support = DrainOneMessageHandler(self.routers[2].addresses[1]) + drain_support = DrainOneMessageHandler(self.routers[2].addresses[0]) drain_support.run() self.assertEqual(None, drain_support.error) def test_www_drain_support_no_messages(self): - drain_support = DrainNoMessagesHandler(self.routers[2].addresses[1]) + drain_support = DrainNoMessagesHandler(self.routers[2].addresses[0]) drain_support.run() self.assertEqual(None, drain_support.error) def test_www_drain_support_no_more_messages(self): - drain_support = DrainNoMoreMessagesHandler(self.routers[2].addresses[1]) + drain_support = DrainNoMoreMessagesHandler(self.routers[2].addresses[0]) drain_support.run() self.assertEqual(None, drain_support.error) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
