Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
0
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);
}
Example #8
0
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);
}
Example #9
0
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);
}
Example #10
0
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);
}