Пример #1
0
static char* test_view_address_with_space(void *context)
{
    struct {const char *addr; const char *view;} cases[] = {
    {"amqp:/link-target",                    "M0test.vhost.link-target"},
    {"amqp:/domain/link-target",             "M0test.vhost.domain/link-target"},
    {"domain/link-target",                   "M0test.vhost.domain/link-target"},
    {"bbc79fb3-e1fd-4a08-92b2-9a2de232b558", "M0test.vhost.bbc79fb3-e1fd-4a08-92b2-9a2de232b558"},
    {0, 0}
    };
    int idx;

    for (idx = 0; cases[idx].addr; idx++) {
        qd_iterator_t *iter = qd_iterator_string(cases[idx].addr, ITER_VIEW_ADDRESS_HASH);
        qd_iterator_annotate_space(iter, "test.vhost.", 11);
        if (!qd_iterator_equal(iter, (unsigned char*) cases[idx].view)) {
            char *got = (char*) qd_iterator_copy(iter);
            snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed.  Expected '%s', got '%s'",
                     cases[idx].addr, cases[idx].view, got);
            return fail_text;
        }
        if (qd_iterator_length(iter) != strlen(cases[idx].view)) {
            snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed.  Length %d, iter_length returned %d",
                     cases[idx].addr, (int) strlen(cases[idx].view), (int) qd_iterator_length(iter));
            return fail_text;
        }
        qd_iterator_free(iter);
    }

    return 0;
}
Пример #2
0
qdr_address_t *qdr_add_mobile_address_CT(qdr_core_t *core, const char *prefix, const char *address, qd_address_treatment_t treatment, bool edge)
{
    char           addr_string_stack[1000];
    char          *addr_string = addr_string_stack;
    bool           allocated   = false;
    qdr_address_t *addr = 0;
    qd_iterator_t *iter = 0;

    size_t len = strlen(prefix) + strlen(address) + 3;
    if (len > sizeof(addr_string_stack)) {
        allocated = true;
        addr_string = (char*) malloc(len);
    }

    snprintf(addr_string, len, "%s%s%s", edge ? "H" : "M0", prefix, address);
    iter = qd_iterator_string(addr_string, ITER_VIEW_ALL);

    qd_hash_retrieve(core->addr_hash, iter, (void**) &addr);
    if (!addr) {
        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);
        }
    }

    qd_iterator_free(iter);
    if (allocated)
        free(addr_string);
    return addr;
}
Пример #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);
}
Пример #4
0
static char* test_view_address_hash_override(void *context)
{
    struct {const char *addr; const char *view;} cases[] = {
    {"amqp:/link-target",                    "Clink-target"},
    {"amqp:/domain/link-target",             "Cdomain/link-target"},
    {"domain/link-target",                   "Cdomain/link-target"},
    {"bbc79fb3-e1fd-4a08-92b2-9a2de232b558", "Cbbc79fb3-e1fd-4a08-92b2-9a2de232b558"},
    {0, 0}
    };
    int idx;

    for (idx = 0; cases[idx].addr; idx++) {
        qd_iterator_t *iter = qd_iterator_string(cases[idx].addr, ITER_VIEW_ADDRESS_HASH);
        qd_iterator_annotate_prefix(iter, 'C');
        if (!qd_iterator_equal(iter, (unsigned char*) cases[idx].view)) {
            char *got = (char*) qd_iterator_copy(iter);
            snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed.  Expected '%s', got '%s'",
                     cases[idx].addr, cases[idx].view, got);
            return fail_text;
        }
        qd_iterator_free(iter);
    }

    return 0;
}
Пример #5
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);
}
Пример #6
0
void qdr_core_remove_address_config(qdr_core_t *core, qdr_address_config_t *addr)
{
    qd_iterator_t *pattern = qd_iterator_string(addr->pattern, ITER_VIEW_ALL);

    // 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--;

    if (addr->ref_count == 0)
        free_address_config(addr);
    qd_iterator_free(pattern);
}
Пример #7
0
void qdr_core_remove_address_config(qdr_core_t *core, qdr_address_config_t *addr)
{
    qd_iterator_t *pattern = qd_iterator_string(addr->pattern, ITER_VIEW_ALL);

    // 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);

    // Free resources associated with this address.
    if (addr->name) {
        free(addr->name);
    }
    qd_iterator_free(pattern);
    free(addr->pattern);
    free_qdr_address_config_t(addr);
}
Пример #8
0
static char *test_trim(void *context)
{
    qd_iterator_t *iter = qd_iterator_string("testing.trim", ITER_VIEW_ALL);

    qd_iterator_trim_view(iter, 7);
    if (!qd_iterator_equal(iter, (unsigned char*) "testing"))
        return "Trim on ITER_VIEW_ALL failed (1)";

    qd_iterator_reset_view(iter, ITER_VIEW_ALL);
    if (!qd_iterator_equal(iter, (unsigned char*) "testing.trim"))
        return "Trim on ITER_VIEW_ALL failed (2)";

    qd_iterator_advance(iter, 4);
    qd_iterator_trim_view(iter, 5);
    if (!qd_iterator_equal(iter, (unsigned char*) "ing.t"))
        return "Trim on ITER_VIEW_ALL failed (3)";

    qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
    qd_iterator_trim_view(iter, 9);
    if (!qd_iterator_equal(iter, (unsigned char*) "M0testing"))
        return "Trim on ITER_VIEW_ADDRESS_HASH failed";

    qd_iterator_reset(iter);
    qd_iterator_annotate_space(iter, "my_space.", 9);
    qd_iterator_trim_view(iter, 18);
    if (!qd_iterator_equal(iter, (unsigned char*) "M0my_space.testing"))
        return "Trim on ITER_VIEW_ADDRESS_HASH (with space 1) failed";

    qd_iterator_reset(iter);
    qd_iterator_trim_view(iter, 10);
    if (!qd_iterator_equal(iter, (unsigned char*) "M0my_space"))
        return "Trim on ITER_VIEW_ADDRESS_HASH (in space 1) failed";

    qd_iterator_reset(iter);
    qd_iterator_trim_view(iter, 2);
    if (!qd_iterator_equal(iter, (unsigned char*) "M0"))
        return "Trim on ITER_VIEW_ADDRESS_HASH (in annotation 1) failed";

    qd_iterator_reset(iter);
    qd_iterator_trim_view(iter, 1);
    if (!qd_iterator_equal(iter, (unsigned char*) "M"))
        return "Trim on ITER_VIEW_ADDRESS_HASH (in annotation 2) failed";

    qd_iterator_free(iter);
    return 0;
}
Пример #9
0
static char* test_view_global_no_host(void *context)
{
    qd_iterator_t *iter = qd_iterator_string("global/sub", ITER_VIEW_ALL);
    if (!qd_iterator_equal(iter, (unsigned char*) "global/sub"))
        return "ITER_VIEW_ALL failed";

    qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_NO_HOST);
    if (!qd_iterator_equal(iter, (unsigned char*) "global/sub"))
        return "ITER_VIEW_ADDRESS_NO_HOST failed";

    qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
    if (!qd_iterator_equal(iter, (unsigned char*) "M0global/sub"))
        return "ITER_VIEW_ADDRESS_HASH failed";

    qd_iterator_free(iter);

    return 0;
}
Пример #10
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);
}
Пример #11
0
qdr_address_t *qdr_add_local_address_CT(qdr_core_t *core, char aclass, const char *address, qd_address_treatment_t treatment)
{
    char           addr_string[1000];
    qdr_address_t *addr = 0;
    qd_iterator_t *iter = 0;

    snprintf(addr_string, sizeof(addr_string), "%c%s", aclass, address);
    iter = qd_iterator_string(addr_string, ITER_VIEW_ALL);

    qd_hash_retrieve(core->addr_hash, iter, (void**) &addr);
    if (!addr) {
        addr = qdr_address_CT(core, treatment);
        qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle);
        DEQ_INSERT_TAIL(core->addrs, addr);
        addr->block_deletion = true;
        addr->local = (aclass == 'L');
    }
    qd_iterator_free(iter);
    return addr;
}
Пример #12
0
static char *test_sub_iterator(void *context)
{
    qd_iterator_t *iter = qd_iterator_string("test_sub_iterator", ITER_VIEW_ALL);
    qd_iterator_t *sub1 = qd_iterator_sub(iter, qd_iterator_remaining(iter));
    qd_iterator_advance(iter, 5);
    qd_iterator_t *sub2 = qd_iterator_sub(iter, qd_iterator_remaining(iter));
    qd_iterator_t *sub3 = qd_iterator_sub(iter, 3);

    if (!qd_iterator_equal(sub1, (unsigned char*) "test_sub_iterator"))
        return "Sub Iterator failed - 1";
    if (!qd_iterator_equal(sub2, (unsigned char*) "sub_iterator"))
        return "Sub Iterator failed - 2";
    if (!qd_iterator_equal(sub3, (unsigned char*) "sub"))
        return "Sub Iterator failed - 3";

    qd_iterator_free(iter);
    qd_iterator_free(sub1);
    qd_iterator_free(sub2);
    qd_iterator_free(sub3);

    return 0;
}
Пример #13
0
static char* test_view_node_hash(void *context)
{
    struct {const char *addr; const char *view;} cases[] = {
    {"area/router",       "Aarea"},
    {"my-area/router",    "Rrouter"},
    {"my-area/my-router", "Rmy-router"},
    {0, 0}
    };
    int idx;

    for (idx = 0; cases[idx].addr; idx++) {
        qd_iterator_t *iter = qd_iterator_string(cases[idx].addr, ITER_VIEW_NODE_HASH);
        if (!qd_iterator_equal(iter, (unsigned char*) cases[idx].view)) {
            char *got = (char*) qd_iterator_copy(iter);
            snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed.  Expected '%s', got '%s'",
                     cases[idx].addr, cases[idx].view, got);
            return fail_text;
            qd_iterator_free(iter);
        }
        qd_iterator_free(iter);
    }

    return 0;
}
Пример #14
0
static char* test_view_address_hash(void *context)
{
    struct {const char *addr; const char *view;} cases[] = {
    {"amqp:/_local/my-addr/sub",                "Lmy-addr/sub"},
    {"amqp:/_local/my-addr",                    "Lmy-addr"},
    {"amqp:/_topo/area/router/local/sub",       "Aarea"},
    {"amqp:/_topo/my-area/router/local/sub",    "Rrouter"},
    {"amqp:/_topo/my-area/my-router/local/sub", "Llocal/sub"},
    {"amqp:/_topo/area/all/local/sub",          "Aarea"},
    {"amqp:/_topo/my-area/all/local/sub",       "Tlocal/sub"},
    {"amqp:/_topo/all/all/local/sub",           "Tlocal/sub"},
    {"amqp://host:port/_local/my-addr",         "Lmy-addr"},
    {"_topo/area/router/my-addr",               "Aarea"},
    {"_topo/my-area/router/my-addr",            "Rrouter"},
    {"_topo/my-area/my-router/my-addr",         "Lmy-addr"},
    {"_topo/my-area/router",                    "Rrouter"},
    {"amqp:/mobile",                            "M1mobile"},
    {"mobile",                                  "M1mobile"},
    {"/mobile",                                 "M1mobile"},

    // Re-run the above tests to make sure trailing dots are ignored.
    {"amqp:/_local/my-addr/sub.",                "Lmy-addr/sub"},
    {"amqp:/_local/my-addr.",                    "Lmy-addr"},
    {"amqp:/_topo/area/router/local/sub.",       "Aarea"},
    {"amqp:/_topo/my-area/router/local/sub.",    "Rrouter"},
    {"amqp:/_topo/my-area/my-router/local/sub.", "Llocal/sub"},
    {"amqp:/_topo/area/all/local/sub.",          "Aarea"},
    {"amqp:/_topo/my-area/all/local/sub.",       "Tlocal/sub"},
    {"amqp:/_topo/all/all/local/sub.",           "Tlocal/sub"},
    {"amqp://host:port/_local/my-addr.",         "Lmy-addr"},
    {"_topo/area/router/my-addr.",               "Aarea"},
    {"_topo/my-area/router/my-addr.",            "Rrouter"},
    {"_topo/my-area/my-router/my-addr.",         "Lmy-addr"},
    {"_topo/my-area/router.",                    "Rrouter"},
    {"_topo/my-area/router:",                    "Rrouter:"},

    {0, 0}
    };
    int idx;

    for (idx = 0; cases[idx].addr; idx++) {
        qd_iterator_t *iter = qd_iterator_string(cases[idx].addr, ITER_VIEW_ADDRESS_HASH);
        char *ret = view_address_hash(context, iter, cases[idx].addr, cases[idx].view);
        qd_iterator_free(iter);
        if (ret) return ret;
    }

    for (idx = 0; cases[idx].addr; idx++) {
        qd_buffer_list_t chain;
        DEQ_INIT(chain);
        build_buffer_chain(&chain, cases[idx].addr, 3);
        qd_iterator_t *iter = qd_iterator_buffer(DEQ_HEAD(chain), 0,
                                                 strlen(cases[idx].addr),
                                                 ITER_VIEW_ADDRESS_HASH);
        char *ret = view_address_hash(context, iter, cases[idx].addr, cases[idx].view);
        release_buffer_chain(&chain);
        if (ret) return ret;
    }

    return 0;
}