Repository: qpid-dispatch
Updated Branches:
  refs/heads/master dfab878b9 -> ff60b36af


DISPATCH-1145 - Add proper handling of multiphase addresses in edge connections.
This includes a new feature to allow containers to declare themselves as 
waypoints
during the attach phase.  This permits waypoint behavior without using 
autolinks.


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/ff60b36a
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/ff60b36a
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/ff60b36a

Branch: refs/heads/master
Commit: ff60b36af18a150e59f46662ec5ec4bcc7bc82da
Parents: dfab878
Author: Ted Ross <tr...@redhat.com>
Authored: Tue Dec 11 11:59:21 2018 -0500
Committer: Ted Ross <tr...@redhat.com>
Committed: Tue Dec 11 12:09:59 2018 -0500

----------------------------------------------------------------------
 include/qpid/dispatch/amqp.h                    |  1 +
 src/amqp.c                                      |  1 +
 src/router_core/agent_config_address.c          |  1 +
 src/router_core/connections.c                   | 23 +++++++--------
 src/router_core/core_link_endpoint.c            |  5 ++--
 src/router_core/exchange_bindings.c             | 11 +++----
 .../address_lookup_client/lookup_client.c       | 29 ++++++++++++++----
 .../modules/edge_router/addr_proxy.c            | 30 +++++++++++++++++--
 src/router_core/route_control.c                 | 12 ++++----
 src/router_core/route_tables.c                  | 11 +++++--
 src/router_core/router_core.c                   | 31 ++++++++++++++------
 src/router_core/router_core_private.h           | 10 ++++---
 12 files changed, 117 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/include/qpid/dispatch/amqp.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/amqp.h b/include/qpid/dispatch/amqp.h
index 99315c7..35f7c67 100644
--- a/include/qpid/dispatch/amqp.h
+++ b/include/qpid/dispatch/amqp.h
@@ -127,6 +127,7 @@ extern const char * const QD_CAPABILITY_ANONYMOUS_RELAY;
 extern const char * const QD_CAPABILITY_ROUTER_CONTROL;
 extern const char * const QD_CAPABILITY_ROUTER_DATA;
 extern const char * const QD_CAPABILITY_EDGE_DOWNLINK;
+extern const char * const QD_CAPABILITY_WAYPOINT1;
 /// @}
 
 /** @name Dynamic Node Properties */

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/src/amqp.c
----------------------------------------------------------------------
diff --git a/src/amqp.c b/src/amqp.c
index 0169c68..c1a0f11 100644
--- a/src/amqp.c
+++ b/src/amqp.c
@@ -35,6 +35,7 @@ const int          QD_MA_FILTER_LEN  = 5;  // N tailing 
inbound entries to searc
 const char * const QD_CAPABILITY_ROUTER_CONTROL  = "qd.router";
 const char * const QD_CAPABILITY_ROUTER_DATA     = "qd.router-data";
 const char * const QD_CAPABILITY_EDGE_DOWNLINK   = "qd.router-edge-downlink";
+const char * const QD_CAPABILITY_WAYPOINT1       = "qd.waypoint.1";
 const char * const QD_CAPABILITY_ANONYMOUS_RELAY = "ANONYMOUS-RELAY";
 
 const char * const QD_DYNAMIC_NODE_PROPERTY_ADDRESS = "x-opt-qd.address";

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/src/router_core/agent_config_address.c
----------------------------------------------------------------------
diff --git a/src/router_core/agent_config_address.c 
b/src/router_core/agent_config_address.c
index 31be6ee..a3e034e 100644
--- a/src/router_core/agent_config_address.c
+++ b/src/router_core/agent_config_address.c
@@ -430,6 +430,7 @@ void qdra_config_address_create_CT(qdr_core_t         *core,
 
         addr = new_qdr_address_config_t();
         DEQ_ITEM_INIT(addr);
+        addr->ref_count = 1; // Represents the reference from the addr_config 
list
         addr->name      = name ? (char*) qd_iterator_copy(name) : 0;
         addr->identity  = qdr_identifier(core);
         addr->treatment = qdra_address_treatment_CT(distrib_field);

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/src/router_core/connections.c
----------------------------------------------------------------------
diff --git a/src/router_core/connections.c b/src/router_core/connections.c
index 17feaea..642fdd5 100644
--- a/src/router_core/connections.c
+++ b/src/router_core/connections.c
@@ -967,7 +967,7 @@ void qdr_link_outbound_second_attach_CT(qdr_core_t *core, 
qdr_link_t *link, qdr_
 }
 
 
-qd_address_treatment_t qdr_treatment_for_address_CT(qdr_core_t *core, 
qdr_connection_t *conn, qd_iterator_t *iter, int *in_phase, int *out_phase, int 
*priority)
+qdr_address_config_t *qdr_config_for_address_CT(qdr_core_t *core, 
qdr_connection_t *conn, qd_iterator_t *iter)
 {
     qdr_address_config_t *addr = 0;
     qd_iterator_view_t old_view = qd_iterator_get_view(iter);
@@ -979,21 +979,19 @@ qd_address_treatment_t 
qdr_treatment_for_address_CT(qdr_core_t *core, qdr_connec
     qd_iterator_annotate_prefix(iter, '\0');
     qd_iterator_reset_view(iter, old_view);
 
-    if (in_phase)  *in_phase  = addr ? addr->in_phase  : 0;
-    if (out_phase) *out_phase = addr ? addr->out_phase : 0;
-    if (priority)  *priority  = addr ? addr->priority  : -1;
-
-
-    return addr ? addr->treatment : core->qd->default_treatment;
+    return addr;
 }
 
 
-qd_address_treatment_t qdr_treatment_for_address_hash_CT(qdr_core_t *core, 
qd_iterator_t *iter)
+qd_address_treatment_t qdr_treatment_for_address_hash_CT(qdr_core_t *core, 
qd_iterator_t *iter, qdr_address_config_t **addr_config)
 {
-    return qdr_treatment_for_address_hash_with_default_CT(core, iter, 
core->qd->default_treatment);
+    return qdr_treatment_for_address_hash_with_default_CT(core, iter, 
core->qd->default_treatment, addr_config);
 }
 
-qd_address_treatment_t 
qdr_treatment_for_address_hash_with_default_CT(qdr_core_t *core, qd_iterator_t 
*iter, qd_address_treatment_t default_treatment)
+qd_address_treatment_t 
qdr_treatment_for_address_hash_with_default_CT(qdr_core_t              *core,
+                                                                      
qd_iterator_t           *iter,
+                                                                      
qd_address_treatment_t   default_treatment,
+                                                                      
qdr_address_config_t   **addr_config)
 {
 #define HASH_STORAGE_SIZE 1000
     char  storage[HASH_STORAGE_SIZE + 1];
@@ -1001,6 +999,7 @@ qd_address_treatment_t 
qdr_treatment_for_address_hash_with_default_CT(qdr_core_t
     bool  on_heap = false;
     int   length  = qd_iterator_length(iter);
     qd_address_treatment_t trt = default_treatment;
+    qdr_address_config_t *addr = 0;
 
     if (length > HASH_STORAGE_SIZE) {
         copy    = (char*) malloc(length + 1);
@@ -1021,7 +1020,6 @@ qd_address_treatment_t 
qdr_treatment_for_address_hash_with_default_CT(qdr_core_t
         // Handle the mobile address case
         //
         qd_iterator_t *config_iter = qd_iterator_string(&copy[2], 
ITER_VIEW_ADDRESS_WITH_SPACE);
-        qdr_address_config_t *addr = 0;
         qd_parse_tree_retrieve_match(core->addr_parse_tree, config_iter, (void 
**) &addr);
         if (addr)
             trt = addr->treatment;
@@ -1031,6 +1029,7 @@ qd_address_treatment_t 
qdr_treatment_for_address_hash_with_default_CT(qdr_core_t
     if (on_heap)
         free(copy);
 
+    *addr_config = addr;
     return trt;
 }
 
@@ -1282,7 +1281,7 @@ static void qdr_attach_link_downlink_CT(qdr_core_t *core, 
qdr_connection_t *conn
 
     qd_hash_retrieve(core->addr_hash, iter, (void**) &addr);
     if (!addr) {
-        addr = qdr_address_CT(core, QD_TREATMENT_ANYCAST_BALANCED);
+       addr = qdr_address_CT(core, QD_TREATMENT_ANYCAST_BALANCED, 0);
         qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle);
         DEQ_INSERT_TAIL(core->addrs, addr);
     }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/src/router_core/core_link_endpoint.c
----------------------------------------------------------------------
diff --git a/src/router_core/core_link_endpoint.c 
b/src/router_core/core_link_endpoint.c
index 66763c9..e1867f7 100644
--- a/src/router_core/core_link_endpoint.c
+++ b/src/router_core/core_link_endpoint.c
@@ -42,10 +42,11 @@ void qdrc_endpoint_bind_mobile_address_CT(qdr_core_t        
   *core,
 
     qd_hash_retrieve(core->addr_hash, iter, (void*) &addr);
     if (!addr) {
-        qd_address_treatment_t treatment = qdr_treatment_for_address_CT(core, 
0, iter, 0, 0, 0);
+        qdr_address_config_t   *addr_config = qdr_config_for_address_CT(core, 
0, iter);
+        qd_address_treatment_t  treatment   = addr_config ? 
addr_config->treatment : QD_TREATMENT_ANYCAST_BALANCED;
         if (treatment == QD_TREATMENT_UNAVAILABLE)
             treatment = QD_TREATMENT_ANYCAST_BALANCED;
-        addr = qdr_address_CT(core, treatment);
+        addr = qdr_address_CT(core, treatment, addr_config);
         DEQ_INSERT_TAIL(core->addrs, addr);
         qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle);
     }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/src/router_core/exchange_bindings.c
----------------------------------------------------------------------
diff --git a/src/router_core/exchange_bindings.c 
b/src/router_core/exchange_bindings.c
index 15d369e..23a58d6 100644
--- a/src/router_core/exchange_bindings.c
+++ b/src/router_core/exchange_bindings.c
@@ -905,8 +905,9 @@ static qdr_exchange_t *qdr_exchange(qdr_core_t *core,
         qd_iterator_annotate_phase(address, (char) phase + '0');
         qd_hash_retrieve(core->addr_hash, address, (void **)&ex->qdr_addr);
         if (!ex->qdr_addr) {
-            ex->qdr_addr = qdr_address_CT(core, 
qdr_treatment_for_address_hash_CT(core,
-                                                                               
   address));
+            qdr_address_config_t   *addr_config;
+            qd_address_treatment_t  treatment = 
qdr_treatment_for_address_hash_CT(core, address, &addr_config);
+            ex->qdr_addr = qdr_address_CT(core, treatment, addr_config);
             qd_hash_insert(core->addr_hash, address, ex->qdr_addr, 
&ex->qdr_addr->hash_handle);
             DEQ_INSERT_TAIL(core->addrs, ex->qdr_addr);
         }
@@ -1046,9 +1047,9 @@ static next_hop_t *next_hop(qdr_exchange_t *ex,
         qd_hash_retrieve(ex->core->addr_hash, address, (void **)&nh->qdr_addr);
         if (!nh->qdr_addr) {
             qdr_core_t *core = ex->core;
-            nh->qdr_addr = qdr_address_CT(core,
-                                          
qdr_treatment_for_address_hash_CT(core,
-                                                                            
address));
+            qdr_address_config_t   *addr_config;
+            qd_address_treatment_t  treatment = 
qdr_treatment_for_address_hash_CT(core, address, &addr_config);
+            nh->qdr_addr = qdr_address_CT(core, treatment, addr_config);
             qd_hash_insert(core->addr_hash, address, nh->qdr_addr, 
&nh->qdr_addr->hash_handle);
             DEQ_INSERT_TAIL(core->addrs, nh->qdr_addr);
         }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/src/router_core/modules/address_lookup_client/lookup_client.c
----------------------------------------------------------------------
diff --git a/src/router_core/modules/address_lookup_client/lookup_client.c 
b/src/router_core/modules/address_lookup_client/lookup_client.c
index ea2449e..0eab118 100644
--- a/src/router_core/modules/address_lookup_client/lookup_client.c
+++ b/src/router_core/modules/address_lookup_client/lookup_client.c
@@ -193,7 +193,7 @@ static qdr_address_t 
*qdr_lookup_terminus_address_CT(qdr_core_t       *core,
             qd_iterator_t *temp_iter = qd_iterator_string(temp_addr, 
ITER_VIEW_ADDRESS_HASH);
             qd_hash_retrieve(core->addr_hash, temp_iter, (void**) &addr);
             if (!addr) {
-                addr = qdr_address_CT(core, QD_TREATMENT_ANYCAST_BALANCED);
+                addr = qdr_address_CT(core, QD_TREATMENT_ANYCAST_BALANCED, 0);
                 qd_hash_insert(core->addr_hash, temp_iter, addr, 
&addr->hash_handle);
                 DEQ_INSERT_TAIL(core->addrs, addr);
                 qdr_terminus_set_address(terminus, temp_addr);
@@ -235,11 +235,27 @@ static qdr_address_t 
*qdr_lookup_terminus_address_CT(qdr_core_t       *core,
     //
     // There was no match for a link-route destination, look for a 
message-route address.
     //
-    int in_phase;
-    int out_phase;
+    int in_phase  = 0;
+    int out_phase = 0;
     int addr_phase;
-    int priority;
-    qd_address_treatment_t treat = qdr_treatment_for_address_CT(core, conn, 
iter, &in_phase, &out_phase, &priority);
+    int priority  = -1;
+    qd_address_treatment_t  treat       = core->qd->default_treatment;
+    qdr_address_config_t   *addr_config = qdr_config_for_address_CT(core, 
conn, iter);
+
+    if (addr_config) {
+        in_phase  = addr_config->in_phase;
+        out_phase = addr_config->out_phase;
+        priority  = addr_config->priority;
+        treat     = addr_config->treatment;
+    }
+
+    //
+    // If the terminus has a waypoint capability, override the configured 
phases and use the waypoint phases.
+    //
+    if (qdr_terminus_has_capability(terminus, QD_CAPABILITY_WAYPOINT1)) {
+        in_phase  = 1;
+        out_phase = 0;
+    }
 
     qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
     qd_iterator_annotate_prefix(iter, '\0'); // Cancel previous override
@@ -260,8 +276,9 @@ static qdr_address_t 
*qdr_lookup_terminus_address_CT(qdr_core_t       *core,
             treat = QD_TREATMENT_ANYCAST_CLOSEST;
         }
 
-        addr = qdr_address_CT(core, treat);
+        addr = qdr_address_CT(core, treat, addr_config);
         if (addr) {
+            addr->config = addr_config;
             qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle);
             DEQ_INSERT_TAIL(core->addrs, addr);
         }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/src/router_core/modules/edge_router/addr_proxy.c
----------------------------------------------------------------------
diff --git a/src/router_core/modules/edge_router/addr_proxy.c 
b/src/router_core/modules/edge_router/addr_proxy.c
index df25621..424bd35 100644
--- a/src/router_core/modules/edge_router/addr_proxy.c
+++ b/src/router_core/modules/edge_router/addr_proxy.c
@@ -92,8 +92,21 @@ static qdr_terminus_t *qdr_terminus_normal(const char *addr)
 static void add_inlink(qcm_edge_addr_proxy_t *ap, const char *key, 
qdr_address_t *addr)
 {
     if (addr->edge_inlink == 0) {
+        qdr_terminus_t *term = qdr_terminus_normal(key + 2);
+
+        if (addr->config && addr->config->out_phase > 0) {
+            //
+            // If this address is configured as multi-phase, check to see if 
it is
+            // an inlink on phase-0.  If so, tell the Interior peer that this 
is
+            // for a waypoint.
+            //
+            const char *key = (char*) qd_hash_key_by_handle(addr->hash_handle);
+            if (key[0] == QD_ITER_HASH_PREFIX_MOBILE && key[1] == '0')
+                qdr_terminus_add_capability(term, QD_CAPABILITY_WAYPOINT1);
+        }
+
         qdr_link_t *link = qdr_create_link_CT(ap->core, ap->edge_conn, 
QD_LINK_ENDPOINT, QD_INCOMING,
-                                              qdr_terminus_normal(key + 2), 
qdr_terminus_normal(0));
+                                              term, qdr_terminus_normal(0));
         qdr_core_bind_address_link_CT(ap->core, addr, link);
         addr->edge_inlink = link;
     }
@@ -119,8 +132,21 @@ static void add_outlink(qcm_edge_addr_proxy_t *ap, const 
char *key, qdr_address_
         // happen later when the interior tells us that there are upstream 
destinations
         // for the address (see on_transfer below).
         //
+        qdr_terminus_t *term = qdr_terminus_normal(key + 2);
+
+        if (addr->config && addr->config->out_phase > 0) {
+            //
+            // If this address is configured as multi-phase, check to see if 
it is
+            // an outlink on phase-1.  If so, tell the Interior peer that this 
is
+            // for a waypoint.
+            //
+            const char *key = (char*) qd_hash_key_by_handle(addr->hash_handle);
+            if (key[0] == QD_ITER_HASH_PREFIX_MOBILE && key[1] == '1')
+                qdr_terminus_add_capability(term, QD_CAPABILITY_WAYPOINT1);
+        }
+
         qdr_link_t *link = qdr_create_link_CT(ap->core, ap->edge_conn, 
QD_LINK_ENDPOINT, QD_OUTGOING,
-                                              qdr_terminus_normal(0), 
qdr_terminus_normal(key + 2));
+                                              qdr_terminus_normal(0), term);
         addr->edge_outlink = link;
     }
 }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/src/router_core/route_control.c
----------------------------------------------------------------------
diff --git a/src/router_core/route_control.c b/src/router_core/route_control.c
index d0bdb4b..b843436 100644
--- a/src/router_core/route_control.c
+++ b/src/router_core/route_control.c
@@ -340,7 +340,7 @@ qdr_link_route_t *qdr_route_add_link_route_CT(qdr_core_t    
         *core,
         qd_iterator_t *a_iter = qd_iterator_string(addr_hash, ITER_VIEW_ALL);
         qd_hash_retrieve(core->addr_hash, a_iter, (void*) &lr->addr);
         if (!lr->addr) {
-            lr->addr = qdr_address_CT(core, treatment);
+            lr->addr = qdr_address_CT(core, treatment, 0);
             if (lr->add_prefix) {
                 lr->addr->add_prefix = (char*) malloc(strlen(lr->add_prefix) + 
1);
                 strcpy(lr->addr->add_prefix, lr->add_prefix);
@@ -489,12 +489,14 @@ qdr_auto_link_t *qdr_route_add_auto_link_CT(qdr_core_t    
      *core,
 
     qd_hash_retrieve(core->addr_hash, iter, (void*) &al->addr);
     if (!al->addr) {
-        qd_address_treatment_t treatment = qdr_treatment_for_address_CT(core, 
0, iter, 0, 0, 0);
+        qdr_address_config_t   *addr_config = qdr_config_for_address_CT(core, 
0, iter);
+        qd_address_treatment_t  treatment   = addr_config ? 
addr_config->treatment : QD_TREATMENT_ANYCAST_BALANCED;
+
         if (treatment == QD_TREATMENT_UNAVAILABLE) {
             //if associated address is not defined, assume balanced
             treatment = QD_TREATMENT_ANYCAST_BALANCED;
         }
-        al->addr = qdr_address_CT(core, treatment);
+        al->addr = qdr_address_CT(core, treatment, addr_config);
         DEQ_INSERT_TAIL(core->addrs, al->addr);
         qd_hash_insert(core->addr_hash, iter, al->addr, 
&al->addr->hash_handle);
     }
@@ -710,7 +712,7 @@ qdr_link_route_t *qdr_route_add_conn_route_CT(qdr_core_t    
         *core,
     lr->pattern   = strdup(addr_pattern);
     lr->parent_conn = conn;
 
-        //
+    //
     // Add the address to the routing hash table and map it as a pattern in the
     // wildcard pattern parse tree
     //
@@ -719,7 +721,7 @@ qdr_link_route_t *qdr_route_add_conn_route_CT(qdr_core_t    
         *core,
         qd_iterator_t *a_iter = qd_iterator_string(addr_hash, ITER_VIEW_ALL);
         qd_hash_retrieve(core->addr_hash, a_iter, (void*) &lr->addr);
         if (!lr->addr) {
-            lr->addr = qdr_address_CT(core, lr->treatment);
+            lr->addr = qdr_address_CT(core, lr->treatment, 0);
             DEQ_INSERT_TAIL(core->addrs, lr->addr);
             qd_hash_insert(core->addr_hash, a_iter, lr->addr, 
&lr->addr->hash_handle);
             qdr_link_route_map_pattern_CT(core, a_iter, lr->addr);

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/src/router_core/route_tables.c
----------------------------------------------------------------------
diff --git a/src/router_core/route_tables.c b/src/router_core/route_tables.c
index 28b1414..3466732 100644
--- a/src/router_core/route_tables.c
+++ b/src/router_core/route_tables.c
@@ -292,7 +292,7 @@ static void qdr_add_router_CT(qdr_core_t *core, 
qdr_action_t *action, bool disca
             // This record will be found whenever a "foreign" topological 
address to this
             // remote router is looked up.
             //
-            addr = qdr_address_CT(core, QD_TREATMENT_ANYCAST_CLOSEST);
+            addr = qdr_address_CT(core, QD_TREATMENT_ANYCAST_CLOSEST, 0);
             qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle);
             DEQ_INSERT_TAIL(core->addrs, addr);
         }
@@ -604,7 +604,12 @@ static void qdr_map_destination_CT(qdr_core_t *core, 
qdr_action_t *action, bool
 
         qd_hash_retrieve(core->addr_hash, iter, (void**) &addr);
         if (!addr) {
-            addr = qdr_address_CT(core, 
qdr_treatment_for_address_hash_with_default_CT(core, iter, 
default_treatment(core, treatment_hint)));
+            qdr_address_config_t   *addr_config;
+            qd_address_treatment_t  treatment = 
qdr_treatment_for_address_hash_with_default_CT(core,
+                                                                               
                iter,
+                                                                               
                default_treatment(core, treatment_hint),
+                                                                               
                &addr_config);
+            addr = qdr_address_CT(core, treatment, addr_config);
             if (!addr) {
                 qd_log(core->log, QD_LOG_CRITICAL, "map_destination: ignored");
                 break;
@@ -712,7 +717,7 @@ static void qdr_subscribe_CT(qdr_core_t *core, qdr_action_t 
*action, bool discar
 
         qd_hash_retrieve(core->addr_hash, address->iterator, (void**) &addr);
         if (!addr) {
-            addr = qdr_address_CT(core, action->args.io.treatment);
+            addr = qdr_address_CT(core, action->args.io.treatment, 0);
             if (addr) {
                 qd_hash_insert(core->addr_hash, address->iterator, addr, 
&addr->hash_handle);
                 DEQ_ITEM_INIT(addr);

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/src/router_core/router_core.c
----------------------------------------------------------------------
diff --git a/src/router_core/router_core.c b/src/router_core/router_core.c
index 6b7e2b8..e1225f8 100644
--- a/src/router_core/router_core.c
+++ b/src/router_core/router_core.c
@@ -289,18 +289,23 @@ void qdr_action_enqueue(qdr_core_t *core, qdr_action_t 
*action)
 }
 
 
-qdr_address_t *qdr_address_CT(qdr_core_t *core, qd_address_treatment_t 
treatment)
+qdr_address_t *qdr_address_CT(qdr_core_t *core, qd_address_treatment_t 
treatment, qdr_address_config_t *config)
 {
     if (treatment == QD_TREATMENT_UNAVAILABLE)
         return 0;
     qdr_address_t *addr = new_qdr_address_t();
     ZERO(addr);
+    addr->config    = config;
     addr->treatment = treatment;
     addr->forwarder = qdr_forwarder_CT(core, treatment);
     addr->rnodes    = qd_bitmask(0);
     addr->add_prefix = 0;
     addr->del_prefix = 0;
     addr->priority   = -1;
+
+    if (config)
+        config->ref_count++;
+
     return addr;
 }
 
@@ -316,7 +321,7 @@ qdr_address_t *qdr_add_local_address_CT(qdr_core_t *core, 
char aclass, const cha
 
     qd_hash_retrieve(core->addr_hash, iter, (void**) &addr);
     if (!addr) {
-        addr = qdr_address_CT(core, treatment);
+        addr = qdr_address_CT(core, treatment, 0);
         if (addr) {
             qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle);
             DEQ_INSERT_TAIL(core->addrs, addr);
@@ -348,7 +353,7 @@ qdr_address_t *qdr_add_mobile_address_CT(qdr_core_t *core, 
const char *prefix, c
 
     qd_hash_retrieve(core->addr_hash, iter, (void**) &addr);
     if (!addr) {
-        addr = qdr_address_CT(core, treatment);
+        addr = qdr_address_CT(core, treatment, 0);
         if (addr) {
             qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle);
             DEQ_INSERT_TAIL(core->addrs, addr);
@@ -393,8 +398,19 @@ void qdr_core_delete_link_route(qdr_core_t *core, 
qdr_link_route_t *lr)
     free_qdr_link_route_t(lr);
 }
 
+static void free_address_config(qdr_address_config_t *addr)
+{
+    free(addr->name);
+    free(addr->pattern);
+    free_qdr_address_config_t(addr);
+}
+
 void qdr_core_remove_address(qdr_core_t *core, qdr_address_t *addr)
 {
+    qdr_address_config_t *config = addr->config;
+    if (config && --config->ref_count == 0)
+        free_address_config(config);
+
     // Remove the address from the list, hash index, and parse tree
     DEQ_REMOVE(core->addrs, addr);
     if (addr->hash_handle) {
@@ -500,14 +516,11 @@ void qdr_core_remove_address_config(qdr_core_t *core, 
qdr_address_config_t *addr
     // Remove the address from the list and the parse tree
     DEQ_REMOVE(core->addr_config, addr);
     qd_parse_tree_remove_pattern(core->addr_parse_tree, pattern);
+    addr->ref_count--;
 
-    // Free resources associated with this address.
-    if (addr->name) {
-        free(addr->name);
-    }
+    if (addr->ref_count == 0)
+        free_address_config(addr);
     qd_iterator_free(pattern);
-    free(addr->pattern);
-    free_qdr_address_config_t(addr);
 }
 
 void qdr_add_link_ref(qdr_link_ref_list_t *ref_list, qdr_link_t *link, int cls)

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ff60b36a/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 f191fad..7177471 100644
--- a/src/router_core/router_core_private.h
+++ b/src/router_core/router_core_private.h
@@ -484,6 +484,7 @@ void qdr_del_connection_ref(qdr_connection_ref_list_t 
*ref_list, qdr_connection_
 
 struct qdr_address_t {
     DEQ_LINKS(qdr_address_t);
+    qdr_address_config_t      *config;
     qdr_subscription_list_t    subscriptions; ///< In-process message 
subscribers
     qdr_connection_ref_list_t  conns;         ///< Local Connections for 
route-destinations
     qdr_link_ref_list_t        rlinks;        ///< Locally-Connected Consumers
@@ -543,7 +544,7 @@ struct qdr_address_t {
 ALLOC_DECLARE(qdr_address_t);
 DEQ_DECLARE(qdr_address_t, qdr_address_list_t);
 
-qdr_address_t *qdr_address_CT(qdr_core_t *core, qd_address_treatment_t 
treatment);
+qdr_address_t *qdr_address_CT(qdr_core_t *core, qd_address_treatment_t 
treatment, qdr_address_config_t *config);
 qdr_address_t *qdr_add_local_address_CT(qdr_core_t *core, char aclass, const 
char *addr, qd_address_treatment_t treatment);
 qdr_address_t *qdr_add_mobile_address_CT(qdr_core_t *core, const char* prefix, 
const char *addr, qd_address_treatment_t treatment, bool edge);
 void qdr_core_remove_address(qdr_core_t *core, qdr_address_t *addr);
@@ -556,6 +557,7 @@ struct qdr_address_config_t {
     DEQ_LINKS(qdr_address_config_t);
     char                   *name;
     uint64_t                identity;
+    uint32_t                ref_count;
     char                   *pattern;
     bool                    is_prefix;
     qd_address_treatment_t  treatment;
@@ -909,9 +911,9 @@ qdr_delivery_t *qdr_forward_new_delivery_CT(qdr_core_t 
*core, qdr_delivery_t *pe
 void qdr_forward_deliver_CT(qdr_core_t *core, qdr_link_t *link, qdr_delivery_t 
*dlv);
 void qdr_connection_free(qdr_connection_t *conn);
 void qdr_connection_activate_CT(qdr_core_t *core, qdr_connection_t *conn);
-qd_address_treatment_t qdr_treatment_for_address_CT(qdr_core_t *core, 
qdr_connection_t *conn, qd_iterator_t *iter, int *in_phase, int *out_phase, int 
*priority);
-qd_address_treatment_t qdr_treatment_for_address_hash_CT(qdr_core_t *core, 
qd_iterator_t *iter);
-qd_address_treatment_t 
qdr_treatment_for_address_hash_with_default_CT(qdr_core_t *core, qd_iterator_t 
*iter, qd_address_treatment_t default_treatment);
+qdr_address_config_t *qdr_config_for_address_CT(qdr_core_t *core, 
qdr_connection_t *conn, qd_iterator_t *iter);
+qd_address_treatment_t qdr_treatment_for_address_hash_CT(qdr_core_t *core, 
qd_iterator_t *iter, qdr_address_config_t **addr_config);
+qd_address_treatment_t 
qdr_treatment_for_address_hash_with_default_CT(qdr_core_t *core, qd_iterator_t 
*iter, qd_address_treatment_t default_treatment, qdr_address_config_t 
**addr_config);
 qdr_edge_t *qdr_edge(qdr_core_t *);
 void qdr_edge_free(qdr_edge_t *);
 void qdr_edge_connection_opened(qdr_edge_t *edge, qdr_connection_t *conn);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to