qdr_auto_link_t *qdr_route_add_auto_link_CT(qdr_core_t *core, qd_field_iterator_t *name, qd_parsed_field_t *addr_field, qd_direction_t dir, int phase, qd_parsed_field_t *conn_id, bool is_container) { qdr_auto_link_t *al = new_qdr_auto_link_t(); // // Set up the auto_link structure // ZERO(al); al->identity = qdr_identifier(core); al->name = name ? (char*) qd_field_iterator_copy(name) : 0; al->dir = dir; al->phase = phase; al->state = QDR_AUTO_LINK_STATE_INACTIVE; // // Find or create an address for the auto_link destination // qd_field_iterator_t *iter = qd_parse_raw(addr_field); qd_address_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH); qd_address_iterator_set_phase(iter, (char) phase + '0'); qd_hash_retrieve(core->addr_hash, iter, (void*) &al->addr); if (!al->addr) { al->addr = qdr_address_CT(core, qdr_treatment_for_address_CT(core, iter, 0, 0)); DEQ_INSERT_TAIL(core->addrs, al->addr); qd_hash_insert(core->addr_hash, iter, al->addr, &al->addr->hash_handle); } al->addr->ref_count++; // // Find or create a connection identifier structure for this auto_link // if (conn_id) { al->conn_id = qdr_route_declare_id_CT(core, qd_parse_raw(conn_id), is_container); DEQ_INSERT_TAIL_N(REF, al->conn_id->auto_link_refs, al); if (al->conn_id->open_connection) qdr_auto_link_activate_CT(core, al, al->conn_id->open_connection); } // // Add the auto_link to the core list // DEQ_INSERT_TAIL(core->auto_links, al); return al; }
qdr_link_route_t *qdr_route_add_link_route_CT(qdr_core_t *core, qd_field_iterator_t *name, qd_parsed_field_t *prefix_field, qd_parsed_field_t *conn_id, bool is_container, qd_address_treatment_t treatment, qd_direction_t dir) { qdr_link_route_t *lr = new_qdr_link_route_t(); // // Set up the link_route structure // ZERO(lr); lr->identity = qdr_identifier(core); lr->name = name ? (char*) qd_field_iterator_copy(name) : 0; lr->dir = dir; lr->treatment = treatment; // // Find or create an address for link-attach routing // qd_field_iterator_t *iter = qd_parse_raw(prefix_field); qd_address_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH); qd_address_iterator_override_prefix(iter, dir == QD_INCOMING ? 'C' : 'D'); qd_hash_retrieve(core->addr_hash, iter, (void*) &lr->addr); if (!lr->addr) { lr->addr = qdr_address_CT(core, treatment); DEQ_INSERT_TAIL(core->addrs, lr->addr); qd_hash_insert(core->addr_hash, iter, lr->addr, &lr->addr->hash_handle); } lr->addr->ref_count++; // // Find or create a connection identifier structure for this link route // if (conn_id) { lr->conn_id = qdr_route_declare_id_CT(core, qd_parse_raw(conn_id), is_container); DEQ_INSERT_TAIL_N(REF, lr->conn_id->link_route_refs, lr); if (lr->conn_id->open_connection) qdr_link_route_activate_CT(core, lr, lr->conn_id->open_connection); } // // Add the link route to the core list // DEQ_INSERT_TAIL(core->link_routes, lr); return lr; }
qd_field_iterator_t *qd_address_iterator_buffer(qd_buffer_t *buffer, int offset, int length, qd_iterator_view_t view) { qd_field_iterator_t *iter = new_qd_field_iterator_t(); if (!iter) return 0; iter->start_pointer.buffer = buffer; iter->start_pointer.cursor = qd_buffer_base(buffer) + offset; iter->start_pointer.length = length; iter->phase = '0'; iter->prefix_override = '\0'; DEQ_INIT(iter->hash_segments); qd_address_iterator_reset_view(iter, view); return iter; }
qd_field_iterator_t* qd_address_iterator_binary(const char *text, int length, qd_iterator_view_t view) { qd_field_iterator_t *iter = new_qd_field_iterator_t(); if (!iter) return 0; iter->start_pointer.buffer = 0; iter->start_pointer.cursor = (unsigned char*) text; iter->start_pointer.length = length; iter->phase = '0'; iter->prefix_override = '\0'; DEQ_INIT(iter->hash_segments); qd_address_iterator_reset_view(iter, view); return iter; }
static qdr_conn_identifier_t *qdr_route_declare_id_CT(qdr_core_t *core, qd_field_iterator_t *conn_id, bool is_container) { char prefix = is_container ? 'C' : 'L'; qdr_conn_identifier_t *cid = 0; qd_address_iterator_reset_view(conn_id, ITER_VIEW_ADDRESS_HASH); qd_address_iterator_override_prefix(conn_id, prefix); qd_hash_retrieve(core->conn_id_hash, conn_id, (void**) &cid); if (!cid) { cid = new_qdr_conn_identifier_t(); ZERO(cid); qd_hash_insert(core->conn_id_hash, conn_id, cid, &cid->hash_handle); } return cid; }
qd_bitmask_t *qd_tracemask_create(qd_tracemask_t *tm, qd_parsed_field_t *tracelist) { qd_bitmask_t *bm = qd_bitmask(0); int idx = 0; assert(qd_parse_is_list(tracelist)); sys_rwlock_rdlock(tm->lock); qd_parsed_field_t *item = qd_parse_sub_value(tracelist, idx); qdtm_router_t *router = 0; while (item) { qd_field_iterator_t *iter = qd_parse_raw(item); qd_address_iterator_reset_view(iter, ITER_VIEW_NODE_HASH); qd_hash_retrieve(tm->hash, iter, (void*) &router); if (router && router->link_maskbit >= 0) qd_bitmask_set_bit(bm, router->link_maskbit); idx++; item = qd_parse_sub_value(tracelist, idx); } sys_rwlock_unlock(tm->lock); return bm; }
void qdr_terminus_copy(qdr_terminus_t *from, pn_terminus_t *to) { if (!from) return; if (from->address) { qd_address_iterator_reset_view(from->address->iterator, ITER_VIEW_ALL); unsigned char *addr = qd_field_iterator_copy(from->address->iterator); pn_terminus_set_address(to, (char*) addr); free(addr); } pn_terminus_set_durability(to, from->durability); pn_terminus_set_expiry_policy(to, from->expiry_policy); pn_terminus_set_timeout(to, from->timeout); pn_terminus_set_dynamic(to, from->dynamic); pn_terminus_set_distribution_mode(to, from->distribution_mode); pn_data_copy(pn_terminus_properties(to), from->properties); pn_data_copy(pn_terminus_filter(to), from->filter); pn_data_copy(pn_terminus_outcomes(to), from->outcomes); pn_data_copy(pn_terminus_capabilities(to), from->capabilities); }
static void qdr_subscribe_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { qdr_field_t *address = action->args.io.address; qdr_subscription_t *sub = action->args.io.subscription; if (!discard) { char aclass = action->args.io.address_class; char phase = action->args.io.address_phase; qdr_address_t *addr = 0; char *astring = (char*) qd_field_iterator_copy(address->iterator); qd_log(core->log, QD_LOG_INFO, "In-process subscription %c/%s", aclass, astring); free(astring); qd_address_iterator_override_prefix(address->iterator, aclass); if (aclass == 'M') qd_address_iterator_set_phase(address->iterator, phase); qd_address_iterator_reset_view(address->iterator, ITER_VIEW_ADDRESS_HASH); qd_hash_retrieve(core->addr_hash, address->iterator, (void**) &addr); if (!addr) { addr = qdr_address_CT(core, action->args.io.treatment); qd_hash_insert(core->addr_hash, address->iterator, addr, &addr->hash_handle); DEQ_ITEM_INIT(addr); DEQ_INSERT_TAIL(core->addrs, addr); } sub->addr = addr; DEQ_ITEM_INIT(sub); DEQ_INSERT_TAIL(addr->subscriptions, sub); qdr_addr_start_inlinks_CT(core, addr); } else free(sub); qdr_field_free(address); }
void qd_address_iterator_override_prefix(qd_field_iterator_t *iter, char prefix) { iter->prefix_override = prefix; qd_address_iterator_reset_view(iter, iter->view); }
static void qdr_add_router_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { int router_maskbit = action->args.route_table.router_maskbit; qdr_field_t *address = action->args.route_table.address; if (discard) { qdr_field_free(address); return; } do { if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "add_router: Router maskbit out of range: %d", router_maskbit); break; } if (core->routers_by_mask_bit[router_maskbit] != 0) { qd_log(core->log, QD_LOG_CRITICAL, "add_router: Router maskbit already in use: %d", router_maskbit); break; } // // Hash lookup the address to ensure there isn't an existing router address. // qd_field_iterator_t *iter = address->iterator; qdr_address_t *addr; qd_address_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH); qd_hash_retrieve(core->addr_hash, iter, (void**) &addr); if (addr) { qd_log(core->log, QD_LOG_CRITICAL, "add_router: Data inconsistency for router-maskbit %d", router_maskbit); assert(addr == 0); // Crash in debug mode. This should never happen break; } // // Create an address record for this router and insert it in the hash table. // 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); qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle); DEQ_INSERT_TAIL(core->addrs, addr); // // Create a router-node record to represent the remote router. // qdr_node_t *rnode = new_qdr_node_t(); DEQ_ITEM_INIT(rnode); rnode->owning_addr = addr; rnode->mask_bit = router_maskbit; rnode->next_hop = 0; rnode->peer_control_link = 0; rnode->peer_data_link = 0; rnode->ref_count = 0; rnode->valid_origins = qd_bitmask(0); DEQ_INSERT_TAIL(core->routers, rnode); // // Link the router record to the address record. // qd_bitmask_set_bit(addr->rnodes, router_maskbit); // // Link the router record to the router address records. // Use the T-class addresses only. // qd_bitmask_set_bit(core->router_addr_T->rnodes, router_maskbit); qd_bitmask_set_bit(core->routerma_addr_T->rnodes, router_maskbit); // // Bump the ref-count by three for each of the above links. // rnode->ref_count += 3; // // Add the router record to the mask-bit index. // core->routers_by_mask_bit[router_maskbit] = rnode; } while (false); qdr_field_free(address); }