Example #1
0
static void qdr_route_log_CT(qdr_core_t *core, const char *text, const char *name, uint64_t id, qdr_connection_t *conn)
{
    const char *key = (const char*) qd_hash_key_by_handle(conn->conn_id->connection_hash_handle);
    if (!key)
        key = (const char*) qd_hash_key_by_handle(conn->conn_id->container_hash_handle);
    char  id_string[64];
    const char *log_name = name ? name : id_string;

    if (!name)
        snprintf(id_string, 64, "%"PRId64, id);

    qd_log(core->log, QD_LOG_INFO, "%s '%s' on %s %s",
           text, log_name, key[0] == 'L' ? "connection" : "container", &key[1]);
}
Example #2
0
void qdr_core_bind_address_link_CT(qdr_core_t *core, qdr_address_t *addr, qdr_link_t *link)
{
    const char *key = (const char*) qd_hash_key_by_handle(addr->hash_handle);
    link->owning_addr = addr;
    if (key && (*key == QD_ITER_HASH_PREFIX_MOBILE))
        link->phase = (int) (key[1] - '0');

    if (link->link_direction == QD_OUTGOING) {
        qdr_add_link_ref(&addr->rlinks, link, QDR_LINK_LIST_CLASS_ADDRESS);
        if (DEQ_SIZE(addr->rlinks) == 1) {
            if (key && (*key == QD_ITER_HASH_PREFIX_EDGE_SUMMARY || *key == QD_ITER_HASH_PREFIX_MOBILE))
                qdr_post_mobile_added_CT(core, key, addr->treatment);
            qdr_addr_start_inlinks_CT(core, addr);
            qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_BECAME_LOCAL_DEST, addr);
        } else if (DEQ_SIZE(addr->rlinks) == 2 && qd_bitmask_cardinality(addr->rnodes) == 0)
            qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_TWO_DEST, addr);
    } else {  // link->link_direction == QD_INCOMING
        qdr_add_link_ref(&addr->inlinks, link, QDR_LINK_LIST_CLASS_ADDRESS);
        if (DEQ_SIZE(addr->inlinks) == 1) {
            qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_BECAME_SOURCE, addr);
            if (!!addr->fallback && !link->fallback)
                qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_BECAME_SOURCE, addr->fallback);
        } else if (DEQ_SIZE(addr->inlinks) == 2) {
            qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_TWO_SOURCE, addr);
            if (!!addr->fallback && !link->fallback)
                qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_TWO_SOURCE, addr->fallback);
        }
    }
}
Example #3
0
void qdr_core_remove_address(qdr_core_t *core, qdr_address_t *addr)
{
    // Remove the address from the list, hash index, and parse tree
    DEQ_REMOVE(core->addrs, addr);
    if (addr->hash_handle) {
        const char *a_str = (const char *)qd_hash_key_by_handle(addr->hash_handle);
        if (QDR_IS_LINK_ROUTE(a_str[0])) {
            qd_iterator_t *iter = qd_iterator_string(a_str, ITER_VIEW_ALL);
            qdr_link_route_unmap_pattern_CT(core, iter);
            qd_iterator_free(iter);
        }
        qd_hash_remove_by_handle(core->addr_hash, addr->hash_handle);
        qd_hash_handle_free(addr->hash_handle);
    }

    // Free resources associated with this address
    qd_bitmask_free(addr->rnodes);
    if (addr->treatment == QD_TREATMENT_ANYCAST_CLOSEST) {
        qd_bitmask_free(addr->closest_remotes);
    }
    else if (addr->treatment == QD_TREATMENT_ANYCAST_BALANCED) {
        free(addr->outstanding_deliveries);
    }
    free_qdr_address_t(addr);
}
Example #4
0
static void qdr_auto_link_activate_CT(qdr_core_t *core, qdr_auto_link_t *al, qdr_connection_t *conn)
{
    const char *key;

    qdr_route_log_CT(core, "Auto Link Activated", al->name, al->identity, conn);

    if (al->addr) {
        qdr_terminus_t *source = 0;
        qdr_terminus_t *target = 0;
        qdr_terminus_t *term   = qdr_terminus(0);

        if (al->dir == QD_INCOMING)
            source = term;
        else
            target = term;

        key = (const char*) qd_hash_key_by_handle(al->addr->hash_handle);
        if (key || al->external_addr) {
            if (al->external_addr)
                qdr_terminus_set_address(term, al->external_addr);
            else
                qdr_terminus_set_address(term, &key[2]); // truncate the "Mp" annotation (where p = phase)
            al->link = qdr_create_link_CT(core, conn, QD_LINK_ENDPOINT, al->dir, source, target);
            al->link->auto_link = al;
            al->state = QDR_AUTO_LINK_STATE_ATTACHING;
        }
    }
}
Example #5
0
void qdr_core_unbind_address_link_CT(qdr_core_t *core, qdr_address_t *addr, qdr_link_t *link)
{
    link->owning_addr = 0;

    if (link->link_direction == QD_OUTGOING) {
        qdr_del_link_ref(&addr->rlinks, link, QDR_LINK_LIST_CLASS_ADDRESS);
        if (DEQ_SIZE(addr->rlinks) == 0) {
            const char *key = (const char*) qd_hash_key_by_handle(addr->hash_handle);
            if (key && (*key == QD_ITER_HASH_PREFIX_MOBILE || *key == QD_ITER_HASH_PREFIX_EDGE_SUMMARY))
                qdr_post_mobile_removed_CT(core, key);
            qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_NO_LONGER_LOCAL_DEST, addr);
        } else if (DEQ_SIZE(addr->rlinks) == 1 && qd_bitmask_cardinality(addr->rnodes) == 0)
            qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_ONE_LOCAL_DEST, addr);
    } else {
        bool removed = qdr_del_link_ref(&addr->inlinks, link, QDR_LINK_LIST_CLASS_ADDRESS);
        if (removed) {
            if (DEQ_SIZE(addr->inlinks) == 0) {
                qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_NO_LONGER_SOURCE, addr);
                if (!!addr->fallback && !link->fallback)
                    qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_NO_LONGER_SOURCE, addr->fallback);
            } else if (DEQ_SIZE(addr->inlinks) == 1) {
                qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_ONE_SOURCE, addr);
                if (!!addr->fallback && !link->fallback)
                    qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_ONE_SOURCE, addr->fallback);
            }
        }
    }
}
Example #6
0
void qdr_core_unbind_address_conn_CT(qdr_core_t *core, qdr_address_t *addr, qdr_connection_t *conn)
{
    qdr_del_connection_ref(&addr->conns, conn);
    if (DEQ_IS_EMPTY(addr->conns)) {
        const char *key = (const char*) qd_hash_key_by_handle(addr->hash_handle);
        qdr_post_mobile_removed_CT(core, key);
        qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_NO_LONGER_LOCAL_DEST, addr);
    }
}
Example #7
0
void qdr_core_bind_address_conn_CT(qdr_core_t *core, qdr_address_t *addr, qdr_connection_t *conn)
{
    qdr_add_connection_ref(&addr->conns, conn);
    if (DEQ_SIZE(addr->conns) == 1) {
        const char *key = (const char*) qd_hash_key_by_handle(addr->hash_handle);
        qdr_post_mobile_added_CT(core, key, addr->treatment);
        qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_BECAME_LOCAL_DEST, addr);
    }
}
Example #8
0
static void qdr_manage_advance_address_CT(qdr_query_t *query, qdr_address_t *addr)
{
    query->next_offset++;
    addr = DEQ_NEXT(addr);
    if (addr) {
        query->more     = true;
        query->next_key = qdr_field((const char*) qd_hash_key_by_handle(addr->hash_handle));
    } else
        query->more = false;
}
Example #9
0
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) {
        const char *a_str = (const char *)qd_hash_key_by_handle(addr->hash_handle);
        if (QDR_IS_LINK_ROUTE(a_str[0])) {
            qd_iterator_t *iter = qd_iterator_string(a_str, ITER_VIEW_ALL);
            qdr_link_route_unmap_pattern_CT(core, iter);
            qd_iterator_free(iter);
        }
        qd_hash_remove_by_handle(core->addr_hash, addr->hash_handle);
        qd_hash_handle_free(addr->hash_handle);
    }

    // Free resources associated with this address

    DEQ_APPEND(addr->rlinks, addr->inlinks);
    qdr_link_ref_t *lref = DEQ_HEAD(addr->rlinks);
    while (lref) {
        qdr_link_t *link = lref->link;
        assert(link->owning_addr == addr);
        link->owning_addr = 0;
        qdr_del_link_ref(&addr->rlinks, link, QDR_LINK_LIST_CLASS_ADDRESS);
        lref = DEQ_HEAD(addr->rlinks);
    }

    qd_bitmask_free(addr->rnodes);
    if (addr->treatment == QD_TREATMENT_ANYCAST_CLOSEST) {
        qd_bitmask_free(addr->closest_remotes);
    }
    else if (addr->treatment == QD_TREATMENT_ANYCAST_BALANCED) {
        free(addr->outstanding_deliveries);
    }

    qdr_connection_ref_t *cr = DEQ_HEAD(addr->conns);
    while (cr) {
        qdr_del_connection_ref(&addr->conns, cr->conn);
        cr = DEQ_HEAD(addr->conns);
    }

    if (!!addr->fallback) {
        addr->fallback->fallback_for = 0;
        qdr_check_addr_CT(core, addr->fallback);
    }

    free(addr->add_prefix);
    free(addr->del_prefix);
    free_qdr_address_t(addr);
}
Example #10
0
bool qdr_address_is_mobile_CT(qdr_address_t *addr)
{
    if (!addr)
        return false;

    const char *addr_str = (const char *)qd_hash_key_by_handle(addr->hash_handle);

    if (addr_str && addr_str[0] == QD_ITER_HASH_PREFIX_MOBILE)
        return true;

    return false;
}
Example #11
0
static void qdr_link_route_deactivate_CT(qdr_core_t *core, qdr_link_route_t *lr, qdr_connection_t *conn)
{
    const char *key;

    qdr_route_log_CT(core, "Link Route Deactivated", lr->name, lr->identity, conn);

    //
    // Deactivate the address(es) for link-routed destinations.
    //
    if (lr->addr) {
        qdr_del_connection_ref(&lr->addr->conns, conn);
        if (DEQ_IS_EMPTY(lr->addr->conns)) {
            key = (const char*) qd_hash_key_by_handle(lr->addr->hash_handle);
            if (key)
                qdr_post_mobile_removed_CT(core, key);
        }
    }
}
Example #12
0
/**
 * Search for, and possibly create, the fallback address based on the
 * fallback flag in the address's configuration.  This will be used in
 * the forwarding paths to handle undeliverable messages with fallback destinations.
 */
void qdr_setup_fallback_address_CT(qdr_core_t *core, qdr_address_t *addr)
{
#define QDR_SETUP_FALLBACK_BUFFER_SIZE 256
    char  buffer[QDR_SETUP_FALLBACK_BUFFER_SIZE];
    char *alt_text       = buffer;
    bool  buffer_on_heap = false;

    char   *address_text = (char*) qd_hash_key_by_handle(addr->hash_handle);
    size_t  alt_length   = strlen(address_text) + 1;

    //
    // If this is a fallback address for a primary address that hasn't been seen
    // yet, simply exit without doing anything.
    //
    if (address_text[1] == QD_ITER_HASH_PHASE_FALLBACK)
        return;

    if (alt_length > QDR_SETUP_FALLBACK_BUFFER_SIZE) {
        alt_text       = (char*) malloc(alt_length);
        buffer_on_heap = true;
    }

    strcpy(alt_text, address_text);
    alt_text[1] = QD_ITER_HASH_PHASE_FALLBACK;

    qd_iterator_t *alt_iter = qd_iterator_string(alt_text, ITER_VIEW_ALL);
    qdr_address_t *alt_addr = 0;

    qd_hash_retrieve(core->addr_hash, alt_iter, (void**) &alt_addr);
    if (!alt_addr) {
        alt_addr = qdr_address_CT(core, QD_TREATMENT_ANYCAST_BALANCED, 0);
        qd_hash_insert(core->addr_hash, alt_iter, alt_addr, &alt_addr->hash_handle);
        DEQ_INSERT_TAIL(core->addrs, alt_addr);
    }

    assert(alt_addr != addr);
    assert(alt_addr->fallback_for == 0);
    addr->fallback         = alt_addr;
    alt_addr->fallback_for = addr;

    qd_iterator_free(alt_iter);
    if (buffer_on_heap)
        free(alt_text);
}
Example #13
0
static void qdr_link_route_activate_CT(qdr_core_t *core, qdr_link_route_t *lr, qdr_connection_t *conn)
{
    const char *key;

    qdr_route_log_CT(core, "Link Route Activated", lr->name, lr->identity, conn);

    //
    // Activate the address for link-routed destinations.  If this is the first
    // activation for this address, notify the router module of the added address.
    //
    if (lr->addr) {
        qdr_add_connection_ref(&lr->addr->conns, conn);
        if (DEQ_SIZE(lr->addr->conns) == 1) {
            key = (const char*) qd_hash_key_by_handle(lr->addr->hash_handle);
            if (key)
                qdr_post_mobile_added_CT(core, key);
        }
    }
}
Example #14
0
static const char *address_key(qdr_address_t *addr)
{
    return addr && addr->hash_handle ? (const char*) qd_hash_key_by_handle(addr->hash_handle) : NULL;
}
static void qdr_config_auto_link_insert_column_CT(qdr_auto_link_t *al, int col, qd_composed_field_t *body, bool as_map)
{
    const char *text = 0;
    const char *key;
    char id_str[100];

    if (as_map)
        qd_compose_insert_string(body, qdr_config_auto_link_columns[col]);

    switch(col) {
    case QDR_CONFIG_AUTO_LINK_NAME:
        if (al->name)
            qd_compose_insert_string(body, al->name);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_AUTO_LINK_IDENTITY:
        snprintf(id_str, 100, "%"PRId64, al->identity);
        qd_compose_insert_string(body, id_str);
        break;

    case QDR_CONFIG_AUTO_LINK_TYPE:
        qd_compose_insert_string(body, CONFIG_AUTOLINK_TYPE);
        break;

    case QDR_CONFIG_AUTO_LINK_ADDR:
        key = (const char*) qd_hash_key_by_handle(al->addr->hash_handle);
        if (key && key[0] == 'M')
            qd_compose_insert_string(body, &key[2]);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_AUTO_LINK_DIR:
        text = al->dir == QD_INCOMING ? "in" : "out";
        qd_compose_insert_string(body, text);
        break;

    case QDR_CONFIG_AUTO_LINK_PHASE:
        qd_compose_insert_int(body, al->phase);
        break;

    case QDR_CONFIG_AUTO_LINK_CONNECTION:
    case QDR_CONFIG_AUTO_LINK_CONTAINER_ID:
        if (al->conn_id) {
            key = (const char*) qd_hash_key_by_handle(al->conn_id->hash_handle);
            if (key && key[0] == 'L' && col == QDR_CONFIG_AUTO_LINK_CONNECTION) {
                qd_compose_insert_string(body, &key[1]);
                break;
            }
            if (key && key[0] == 'C' && col == QDR_CONFIG_AUTO_LINK_CONTAINER_ID) {
                qd_compose_insert_string(body, &key[1]);
                break;
            }
        }
        qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_AUTO_LINK_LINK_REF:
        if (al->link) {
            snprintf(id_str, 100, "%"PRId64, al->link->identity);
            qd_compose_insert_string(body, id_str);
        } else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_AUTO_LINK_OPER_STATUS:
        switch (al->state) {
        case QDR_AUTO_LINK_STATE_INACTIVE:  text = "inactive";  break;
        case QDR_AUTO_LINK_STATE_ATTACHING: text = "attaching"; break;
        case QDR_AUTO_LINK_STATE_FAILED:    text = "failed";    break;
        case QDR_AUTO_LINK_STATE_ACTIVE:    text = "active";    break;
        case QDR_AUTO_LINK_STATE_QUIESCING: text = "quiescing"; break;
        case QDR_AUTO_LINK_STATE_IDLE:      text = "idle";      break;
        }

        if (text)
            qd_compose_insert_string(body, text);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_AUTO_LINK_LAST_ERROR:
        if (al->last_error)
            qd_compose_insert_string(body, al->last_error);
        else
            qd_compose_insert_null(body);
        break;
    }
}
static void qdr_config_link_route_insert_column_CT(qdr_link_route_t *lr, int col, qd_composed_field_t *body, bool as_map)
{
    const char *text = 0;
    const char *key;

    if (as_map)
        qd_compose_insert_string(body, qdr_config_link_route_columns[col]);

    switch(col) {
    case QDR_CONFIG_LINK_ROUTE_NAME:
        if (lr->name)
            qd_compose_insert_string(body, lr->name);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_LINK_ROUTE_IDENTITY: {
        char id_str[100];
        snprintf(id_str, 100, "%"PRId64, lr->identity);
        qd_compose_insert_string(body, id_str);
        break;
    }

    case QDR_CONFIG_LINK_ROUTE_TYPE:
        qd_compose_insert_string(body, "org.apache.qpid.dispatch.router.config.linkRoute");
        break;

    case QDR_CONFIG_LINK_ROUTE_PREFIX:
        key = (const char*) qd_hash_key_by_handle(lr->addr->hash_handle);
        if (key && (key[0] == 'C' || key[0] == 'D'))
            qd_compose_insert_string(body, &key[1]);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_LINK_ROUTE_DISTRIBUTION:
        switch (lr->treatment) {
        case QD_TREATMENT_LINK_BALANCED: text = "linkBalanced"; break;
        default:
            text = 0;
        }

        if (text)
            qd_compose_insert_string(body, text);
        else
            qd_compose_insert_null(body);

        break;

    case QDR_CONFIG_LINK_ROUTE_CONNECTION:
    case QDR_CONFIG_LINK_ROUTE_CONTAINER_ID:
        if (lr->conn_id) {
            key = (const char*) qd_hash_key_by_handle(lr->conn_id->hash_handle);
            if (key && key[0] == 'L' && col == QDR_CONFIG_LINK_ROUTE_CONNECTION) {
                qd_compose_insert_string(body, &key[1]);
                break;
            }
            if (key && key[0] == 'C' && col == QDR_CONFIG_LINK_ROUTE_CONTAINER_ID) {
                qd_compose_insert_string(body, &key[1]);
                break;
            }
        }
        qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_LINK_ROUTE_DIR:
        text = lr->dir == QD_INCOMING ? "in" : "out";
        qd_compose_insert_string(body, text);
        break;

    case QDR_CONFIG_LINK_ROUTE_OPER_STATUS:
        text = lr->active ? "active" : "inactive";
        qd_compose_insert_string(body, text);
        break;
    }
}
Example #17
0
static void qdr_insert_address_columns_CT(qdr_core_t          *core,
                                          qdr_address_t       *addr,
                                          qd_composed_field_t *body,
                                          int                  column_index)
{
    switch(column_index) {
    case QDR_ADDRESS_NAME:
    case QDR_ADDRESS_IDENTITY:
    case QDR_ADDRESS_KEY:
        if (addr->hash_handle)
            qd_compose_insert_string(body, (const char*) qd_hash_key_by_handle(addr->hash_handle));
        else
            qd_compose_insert_null(body);
        break;

    case QDR_ADDRESS_TYPE:
        qd_compose_insert_string(body, "org.apache.qpid.dispatch.router.address");
        break;

    case QDR_ADDRESS_DISTRIBUTION: {
        switch (addr->treatment) {
        case QD_TREATMENT_MULTICAST_FLOOD:  qd_compose_insert_string(body, "flood");        break;
        case QD_TREATMENT_MULTICAST_ONCE:   qd_compose_insert_string(body, "multicast");    break;
        case QD_TREATMENT_ANYCAST_CLOSEST:  qd_compose_insert_string(body, "closest");      break;
        case QD_TREATMENT_ANYCAST_BALANCED: qd_compose_insert_string(body, "balanced");     break;
        case QD_TREATMENT_LINK_BALANCED:    qd_compose_insert_string(body, "linkBalanced"); break;
        }
        break;
    }

    case QDR_ADDRESS_IN_PROCESS:
        qd_compose_insert_uint(body, DEQ_SIZE(addr->subscriptions));
        break;

    case QDR_ADDRESS_SUBSCRIBER_COUNT:
        qd_compose_insert_uint(body, DEQ_SIZE(addr->rlinks));
        break;

    case QDR_ADDRESS_REMOTE_COUNT:
        qd_compose_insert_uint(body, qd_bitmask_cardinality(addr->rnodes));
        break;

    case QDR_ADDRESS_CONTAINER_COUNT:
        qd_compose_insert_uint(body, DEQ_SIZE(addr->conns));
        break;

    case QDR_ADDRESS_REMOTE_HOST_ROUTERS: {
        qd_compose_start_list(body);
        int c;
        int bit;
        for (QD_BITMASK_EACH(addr->rnodes, bit, c)) {
            qdr_node_t *rnode = core->routers_by_mask_bit[bit];
            if (rnode && rnode->owning_addr) {
                const char *ar = (char*) qd_hash_key_by_handle(rnode->owning_addr->hash_handle);
                qd_compose_insert_string(body, ar + 1); // Remove the 'R' prefix from the router address
            }
        }
        qd_compose_end_list(body);
        break;
    }

    case QDR_ADDRESS_DELIVERIES_INGRESS:
        qd_compose_insert_ulong(body, addr->deliveries_ingress);
        break;

    case QDR_ADDRESS_DELIVERIES_EGRESS:
        qd_compose_insert_ulong(body, addr->deliveries_egress);
        break;

    case QDR_ADDRESS_DELIVERIES_TRANSIT:
        qd_compose_insert_ulong(body, addr->deliveries_transit);
        break;

    case QDR_ADDRESS_DELIVERIES_TO_CONTAINER:
        qd_compose_insert_ulong(body, addr->deliveries_to_container);
        break;

    case QDR_ADDRESS_DELIVERIES_FROM_CONTAINER:
        qd_compose_insert_ulong(body, addr->deliveries_from_container);
        break;

    case QDR_ADDRESS_TRANSIT_OUTSTANDING:
        if (addr->outstanding_deliveries) {
            qd_compose_start_list(body);
            for (int i = 0; i < qd_bitmask_width(); i++)
                qd_compose_insert_long(body, addr->outstanding_deliveries[i]);
            qd_compose_end_list(body);
        } else
            qd_compose_insert_null(body);
        break;

    case QDR_ADDRESS_TRACKED_DELIVERIES:
        qd_compose_insert_long(body, addr->tracked_deliveries);
        break;

    default:
        qd_compose_insert_null(body);
        break;
    }

}