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(©[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