// Test pattern matching a field.
TEST(TestIronBee, test_data_pcre)
{
    ib_engine_t *ib;
    ib_data_config_t *dataconfig;
    ib_data_t *data;
    ib_field_t *list_field;
    ib_field_t *out_field;
    ib_list_t *list;
    ib_list_t *out_list;
    ib_field_t *field1;
    ib_field_t *field2;
    ib_field_t *field3;
    ib_num_t num1 = 1;
    ib_num_t num2 = 2;
    ib_num_t num3 = 3;

    ibtest_engine_create(&ib);

    ASSERT_EQ(IB_OK, ib_data_config_create(ib_engine_pool_main_get(ib), & dataconfig));
    ASSERT_EQ(IB_OK, ib_data_create(dataconfig, ib_engine_pool_main_get(ib), &data));
    ASSERT_TRUE(data);

    ASSERT_IB_OK(
        ib_field_create(&field1, ib_data_pool(data), "field1", 6, IB_FTYPE_NUM, &num1));
    ASSERT_IB_OK(
        ib_field_create(&field2, ib_data_pool(data), "field2", 6, IB_FTYPE_NUM, &num2));
    ASSERT_IB_OK(
        ib_field_create(&field3, ib_data_pool(data), "field3", 6, IB_FTYPE_NUM, &num3));
    ASSERT_IB_OK(ib_data_add_list(data, "ARGV", &list_field));
    ASSERT_IB_OK(ib_data_get(data, "ARGV", &out_field));

    ASSERT_IB_OK(ib_field_value(list_field, &list));
    ASSERT_IB_OK(ib_list_push(list, field1));
    ASSERT_IB_OK(ib_list_push(list, field2));
    ASSERT_IB_OK(ib_list_push(list, field3));

    ASSERT_IB_OK(ib_data_get(data, "ARGV:/.*(1|3)/", &out_field));

    ASSERT_IB_OK(ib_field_value(out_field, &out_list));
    ASSERT_NE(list, out_list); /* Make sure it's a different list. */

    ASSERT_EQ(2U, IB_LIST_ELEMENTS(out_list));

    out_field = (ib_field_t *) IB_LIST_FIRST(out_list)->data;
    ASSERT_FALSE(memcmp(out_field->name, field1->name, field1->nlen));

    out_field = (ib_field_t *) IB_LIST_LAST(out_list)->data;
    ASSERT_FALSE(memcmp(out_field->name, field3->name, field3->nlen));

    ibtest_engine_destroy(ib);
}
Exemple #2
0
/// @test Test util list library - IB_LIST_LOOP()
TEST_F(TestIBUtilList, test_list_loop)
{
    ib_list_t *list;
    ib_list_node_t *node;
    ib_status_t rc;
    int init[] = { 0, 1, 2, 3, 4 };
    int *val;
    int i;

    rc = ib_list_create(&list, MemPool());
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(list);
    ASSERT_EQ(0UL, ib_list_elements(list));

    for (i = 0; i < 5; i++) {
        rc = ib_list_push(list, &init[i]);
        ASSERT_EQ(IB_OK, rc);
    }
    ASSERT_EQ(5UL, ib_list_elements(list));

    i = 0;
    IB_LIST_LOOP(list, node) {
        val = (int *)ib_list_node_data(node);
        ASSERT_EQ(init[i], *val);
        i++;
    }
Exemple #3
0
static ib_status_t dyn_get(
    const ib_field_t *f,
    void *out_value,
    const void *arg,
    size_t alen,
    void *data
)
{
    ib_mpool_t *mp = (ib_mpool_t *)data;
    ib_num_t numval = 5;
    ib_field_t *newf;
    ib_status_t rc;
    ib_list_t *l;

    const char* carg = (const char *)arg;

    rc = ib_list_create(&l, mp);
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_field_create(&newf, mp, carg, alen, IB_FTYPE_NUM,
        ib_ftype_num_in(&numval));
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_list_push(l, newf);

    *(void**)out_value = l;

    return IB_OK;
}
Exemple #4
0
    void RunTest(size_t bufsize,
                 ib_status_t expected_rc,
                 ib_flags_t expected_result,
                 const char *expected,
                 bool quote,
                 const char *join,
                 size_t num, ...)
    {
        va_list va;
        const char *s;
        ib_status_t rc;
        ib_list_t *slist;
        size_t n;

        rc = ib_list_create(&slist, m_pool);
        if (rc != IB_OK) {
            throw std::runtime_error("Error creating string list");
        }

        va_start(va, num);
        for (n = 0;  n < num;  ++n) {
            s = va_arg(va, char *);
            rc = ib_list_push(slist, (void *)s);
            if (rc != IB_OK) {
                throw std::runtime_error("Error creating string list");
            }
        }
        va_end(va);

        RunTest(slist, quote, join, bufsize,
                expected_rc, expected_result, expected);

    }
Exemple #5
0
ib_status_t ib_cfgparser_create(ib_cfgparser_t **pcp,
                                ib_engine_t *ib)
{
    IB_FTRACE_INIT(ib_cfgparser_create);
    ib_mpool_t *pool;
    ib_status_t rc;

    /* Create parser memory pool */
    rc = ib_mpool_create(&pool, ib->mp);
    if (rc != IB_OK) {
        rc = IB_EALLOC;
        goto failed;
    }

    /* Create the main structure in the memory pool */
    *pcp = (ib_cfgparser_t *)ib_mpool_calloc(pool, 1, sizeof(**pcp));
    if (*pcp == NULL) {
        rc = IB_EALLOC;
        goto failed;
    }
    (*pcp)->ib = ib;
    (*pcp)->mp = pool;

    /* Create the stack */
    rc = ib_list_create(&((*pcp)->stack), pool);
    if (rc != IB_OK) {
        goto failed;
    }
    (*pcp)->cur_ctx = ib_context_main(ib);
    ib_list_push((*pcp)->stack, (*pcp)->cur_ctx);

    /* Create the block tracking list */
    rc = ib_list_create(&((*pcp)->block), pool);
    if (rc != IB_OK) {
        goto failed;
    }

    /* Other fields are NULLed via calloc */

    ib_log_debug(ib, 9, "Stack: ctx=%p site=%p(%s) loc=%p(%s)",
                 (*pcp)->cur_ctx,
                 (*pcp)->cur_site, (*pcp)->cur_site?(*pcp)->cur_site->name:"NONE",
                 (*pcp)->cur_loc, (*pcp)->cur_loc?(*pcp)->cur_loc->path:"/");

    IB_FTRACE_RET_STATUS(rc);

failed:
    /* Make sure everything is cleaned up on failure */
    if (pool != NULL) {
        ib_mpool_destroy(pool);
    }
    *pcp = NULL;

    IB_FTRACE_RET_STATUS(rc);
}
Exemple #6
0
ib_status_t ib_flags_oplist_parse(
    const ib_strval_t *map,
    ib_mpool_t        *mp,
    const char        *str,
    const char        *sep,
    ib_list_t         *oplist)
{
    if ( (map == NULL) || (str == NULL) || (sep == NULL) || (oplist == NULL) ) {
        return IB_EINVAL;
    }

    char       *copy;
    const char *tmp;

    /* Make a copy of the string that we can use for strtok */
    copy = ib_mpool_strdup(mp, str);
    if (copy == NULL) {
        return IB_EALLOC;
    }

    /* Clear the list */
    ib_list_clear(oplist);

    /* Walk through the separated list, parser each operator, build the list */
    tmp = strtok(copy, sep);
    do {
        ib_status_t           rc;
        ib_flags_op_t         op;
        ib_flags_t            flags;
        ib_flags_operation_t *operation;

        rc = parse_single(map, tmp, &op, &flags);
        if (rc != IB_OK) {
            return rc;
        }
        operation = ib_mpool_alloc(mp, sizeof(*operation));
        if (operation == NULL) {
            return IB_EALLOC;
        }
        operation->op = op;
        operation->flags = flags;
        rc = ib_list_push(oplist, operation);
        if (rc != IB_OK) {
            return rc;
        }
    } while ( (tmp = strtok(NULL, sep)) != NULL);

    return IB_OK;
}
Exemple #7
0
ib_status_t DLL_PUBLIC ib_cfgparser_block_push(ib_cfgparser_t *cp,
                                               const char *name)
{
    IB_FTRACE_INIT(ib_cfgparser_block_push);
    ib_engine_t *ib = cp->ib;
    ib_status_t rc;

    rc = ib_list_push(cp->block, (void *)name);
    if (rc != IB_OK) {
        ib_log_error(ib, 4, "Failed to push block %p: %d", name, rc);
        IB_FTRACE_RET_STATUS(rc);
    }
    cp->cur_blkname = name;

    IB_FTRACE_RET_STATUS(IB_OK);
}
Exemple #8
0
ib_status_t ib_site_hostname_add(ib_site_t *site,
                                 const char *host)
{
    IB_FTRACE_INIT(ib_site_hostname_add);
    ib_status_t rc;

    /* Create a list if this is the first item. */
    if (site->hosts == NULL) {
        rc = ib_list_create(&site->hosts, site->mp);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    /// @todo: use regex
    rc = ib_list_push(site->hosts, (void *)host);
    IB_FTRACE_RET_STATUS(rc);
}
Exemple #9
0
ib_status_t ib_field_list_add(
    ib_field_t *f,
    ib_field_t *fval
)
{
    ib_status_t rc;
    ib_list_t *l = NULL;

    rc = ib_field_mutable_value_type(
        f,
        ib_ftype_list_mutable_out(&l),
        IB_FTYPE_LIST
    );
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_list_push(l, (void *)fval);
    return rc;
}
Exemple #10
0
ib_status_t DLL_PUBLIC ib_logevent_field_add(ib_logevent_t *le,
                                             const char *name)
{
    IB_FTRACE_INIT();
    char *name_copy;
    ib_status_t rc;

    assert(le != NULL);

    if (le->fields == NULL) {
        rc = ib_list_create(&le->fields, le->mp);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    name_copy = ib_mpool_memdup(le->mp, name, strlen(name) + 1);
    rc = ib_list_push(le->fields, name_copy);

    IB_FTRACE_RET_STATUS(rc);
}
Exemple #11
0
ib_status_t DLL_PUBLIC ib_logevent_tag_add(ib_logevent_t *le,
                                           const char *tag)
{
    IB_FTRACE_INIT();
    char *tag_copy;
    ib_status_t rc;

    assert(le != NULL);

    if (le->tags == NULL) {
        rc = ib_list_create(&le->tags, le->mp);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    tag_copy = ib_mpool_memdup(le->mp, tag, strlen(tag) + 1);
    rc = ib_list_push(le->tags, tag_copy);

    IB_FTRACE_RET_STATUS(rc);
}
Exemple #12
0
ib_status_t ib_cfgparser_context_push(ib_cfgparser_t *cp,
                                      ib_context_t *ctx)
{
    IB_FTRACE_INIT(ib_cfgparser_context_push);
    ib_engine_t *ib = cp->ib;
    ib_status_t rc;

    rc = ib_list_push(cp->stack, ctx);
    if (rc != IB_OK) {
        ib_log_error(ib, 4, "Failed to push context %p: %d", ctx, rc);
        IB_FTRACE_RET_STATUS(rc);
    }
    cfgp_set_current(cp, ctx);

    ib_log_debug(ib, 9, "Stack: ctx=%p site=%p(%s) loc=%p(%s)",
                 cp->cur_ctx,
                 cp->cur_site, cp->cur_site?cp->cur_site->name:"NONE",
                 cp->cur_loc, cp->cur_loc?cp->cur_loc->path:"/");

    IB_FTRACE_RET_STATUS(IB_OK);
}
Exemple #13
0
ib_status_t ib_site_loc_create(ib_site_t *site,
                               ib_loc_t **ploc,
                               const char *path)
{
    IB_FTRACE_INIT(ib_site_loc_create);
    ib_loc_t *loc;
    ib_status_t rc;

    if (ploc != NULL) {
        *ploc = NULL;
    }

    /* Create a list if this is the first item. */
    if (site->locations == NULL) {
        rc = ib_list_create(&site->locations, site->mp);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    /* Create the location structure in the site memory pool */
    loc = (ib_loc_t *)ib_mpool_calloc(site->mp, 1, sizeof(*loc));
    if (loc == NULL) {
        rc = IB_EALLOC;
        IB_FTRACE_RET_STATUS(rc);
    }
    loc->site = site;
    loc->path = path;
    loc->path = (const char *)ib_mpool_memdup(site->mp, path, strlen(path)+1);

    if (ploc != NULL) {
        *ploc = loc;
    }

    rc = ib_list_push(site->locations, (void *)loc);
    IB_FTRACE_RET_STATUS(rc);
}
Exemple #14
0
/*********************************
 * Helper Functions
 *********************************/
static
ib_status_t sqli_create_pattern_set_from_file(
    sqli_pattern_set_t **out_ps,
    const char         *path,
    ib_mpool_t         *mp
)
{
    assert(out_ps != NULL);
    assert(path   != NULL);
    assert(mp     != NULL);

    ib_status_t  rc;
    FILE               *fp          = NULL;
    char               *buffer      = NULL;
    size_t              buffer_size = 0;
    ib_list_t          *items       = NULL;
    ib_list_node_t     *n           = NULL;
    ib_mpool_t         *tmp         = NULL;
    sqli_pattern_set_t *ps          = NULL;
    size_t              i           = 0;

    /* Temporary memory pool for this function only. */
    rc = ib_mpool_create(&tmp, "sqli tmp", NULL);
    assert(rc == IB_OK);
    assert(tmp != NULL);

    fp = fopen(path, "r");
    if (fp == NULL) {
        goto fail;
    }

    rc = ib_list_create(&items, tmp);
    assert(rc    == IB_OK);
    assert(items != NULL);

    for (;;) {
        char *buffer_copy;
        int   read = getline(&buffer, &buffer_size, fp);

        if (read == -1) {
            if (! feof(fp)) {
                fclose(fp);
                goto fail;
            }
            else {
                break;
            }
        }

        buffer_copy = ib_mpool_memdup(mp, buffer, read);
        assert(buffer_copy != NULL);
        while (buffer_copy[read-1] == '\n' || buffer_copy[read-1] == '\r') {
            buffer_copy[read-1] = '\0';
            --read;
        }

        rc = ib_list_push(items, (void *)buffer_copy);
        assert(rc == IB_OK);
    }

    fclose(fp);

    ps = ib_mpool_alloc(mp, sizeof(*ps));
    assert(ps != NULL);

    ps->num_patterns = ib_list_elements(items);
    ps->patterns =
        ib_mpool_alloc(mp, ps->num_patterns * sizeof(*ps->patterns));
    assert(ps->patterns != NULL);

    i = 0;
    IB_LIST_LOOP(items, n) {
        ps->patterns[i] = ib_list_node_data(n);
        ++i;
    }
Exemple #15
0
/**
 * @internal
 * Handle a PocSig directive.
 *
 * @param cp Config parser
 * @param name Directive name
 * @param args List of directive arguments
 * @param cbdata Callback data (from directive registration)
 *
 * @returns Status code
 */
static ib_status_t pocsig_dir_signature(ib_cfgparser_t *cp,
                                        const char *name,
                                        ib_list_t *args,
                                        void *cbdata)
{
    IB_FTRACE_INIT(pocsig_dir_signature);
    ib_engine_t *ib = cp->ib;
    ib_context_t *ctx = cp->cur_ctx ? cp->cur_ctx : ib_context_main(ib);
    ib_list_t *list;
    const char *target;
    const char *op;
    const char *action;
    pocsig_cfg_t *cfg;
    pocsig_phase_t phase;
    pocsig_sig_t *sig;
    const char *errptr;
    int erroff;
    ib_status_t rc;

    /* Get the pocsig configuration for this context. */
    rc = ib_context_module_config(ctx, IB_MODULE_STRUCT_PTR, (void *)&cfg);
    if (rc != IB_OK) {
        ib_log_error(ib, 1, "Failed to fetch %s config: %d",
                     MODULE_NAME_STR, rc);
    }

    /* Setup the PCRE matcher. */
    if (cfg->pcre == NULL) {
        rc = ib_matcher_create(ib, ib_engine_pool_config_get(ib),
                               "pcre", &cfg->pcre);
        if (rc != IB_OK) {
            ib_log_error(ib, 2, "Could not create a PCRE matcher: %d", rc);
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    /* Determine phase and initialize the phase list if required. */
    if (strcasecmp("PocSigPreTx", name) == 0) {
        phase = POCSIG_PRE;
        if (cfg->phase[phase] == NULL) {
            rc = ib_list_create(cfg->phase + POCSIG_PRE,
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else if (strcasecmp("PocSigReqHead", name) == 0) {
        phase = POCSIG_REQHEAD;
        if (cfg->phase[phase] == NULL) {
            ib_log_debug(ib, 4, "Creating list for phase=%d", phase);
            rc = ib_list_create(&list,
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
            ib_log_debug(ib, 4, "List for phase=%d list=%p", phase, list);
            cfg->phase[phase] = list;
        }
    }
    else if (strcasecmp("PocSigReq", name) == 0) {
        phase = POCSIG_REQ;
        if (cfg->phase[phase] == NULL) {
            rc = ib_list_create(&cfg->phase[phase],
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else if (strcasecmp("PocSigResHead", name) == 0) {
        phase = POCSIG_RESHEAD;
        if (cfg->phase[phase] == NULL) {
            rc = ib_list_create(&cfg->phase[phase],
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else if (strcasecmp("PocSigRes", name) == 0) {
        phase = POCSIG_RES;
        if (cfg->phase[POCSIG_RES] == NULL) {
            rc = ib_list_create(&cfg->phase[POCSIG_RES],
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else if (strcasecmp("PocSigPostTx", name) == 0) {
        phase = POCSIG_POST;
        if (cfg->phase[phase] == NULL) {
            rc = ib_list_create(&cfg->phase[phase],
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else {
        ib_log_error(ib, 2, "Invalid signature: %s", name);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* Target */
    rc = ib_list_shift(args, &target);
    if (rc != IB_OK) {
        ib_log_error(ib, 1, "No PocSig target");
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* Operator */
    rc = ib_list_shift(args, &op);
    if (rc != IB_OK) {
        ib_log_error(ib, 1, "No PocSig operator");
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* Action */
    rc = ib_list_shift(args, &action);
    if (rc != IB_OK) {
        ib_log_debug(ib, 4, "No PocSig action");
        action = "";
    }

    /* Signature */
    sig = (pocsig_sig_t *)ib_mpool_alloc(ib_engine_pool_config_get(ib),
                                         sizeof(*sig));
    if (sig == NULL) {
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    sig->target = ib_mpool_strdup(ib_engine_pool_config_get(ib), target);
    sig->patt = ib_mpool_strdup(ib_engine_pool_config_get(ib), op);
    sig->emsg = ib_mpool_strdup(ib_engine_pool_config_get(ib), action);

    /* Compile the PCRE patt. */
    if (cfg->pcre == NULL) {
        ib_log_error(ib, 2, "No PCRE matcher available (load the pcre module?)");
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }
    sig->cpatt = ib_matcher_compile(cfg->pcre, sig->patt, &errptr, &erroff);
    if (sig->cpatt == NULL) {
        ib_log_error(ib, 2, "Error at offset=%d of PCRE patt=\"%s\": %s",
                     erroff, sig->patt, errptr);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    ib_log_debug(ib, 4, "POCSIG: \"%s\" \"%s\" \"%s\" phase=%d ctx=%p",
                 target, op, action, phase, ctx);

    /* Add the signature to the phase list. */
    rc = ib_list_push(cfg->phase[phase], sig);
    if (rc != IB_OK) {
        ib_log_error(ib, 1, "Failed to add signature");
        IB_FTRACE_RET_STATUS(rc);
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
Exemple #16
0
/*********************************
 * Helper Functions
 *********************************/
static
ib_status_t sqli_create_fingerprint_set_from_file(
    sqli_fingerprint_set_t **out_ps,
    const char         *path,
    ib_mm_t             mm
)
{
    assert(out_ps != NULL);
    assert(path   != NULL);

    ib_status_t         rc;
    FILE               *fp          = NULL;
    char               *buffer      = NULL;
    size_t              buffer_size = 0;
    ib_list_t          *items       = NULL;
    ib_list_node_t     *n           = NULL;
    ib_mpool_lite_t    *tmp         = NULL;
    ib_mm_t             tmp_mm;
    sqli_fingerprint_set_t *ps          = NULL;
    size_t              i           = 0;

    /* Temporary memory pool for this function only. */
    rc = ib_mpool_lite_create(&tmp);
    assert(rc == IB_OK);
    assert(tmp != NULL);
    tmp_mm = ib_mm_mpool_lite(tmp);

    fp = fopen(path, "r");
    if (fp == NULL) {
        goto fail;
    }

    rc = ib_list_create(&items, tmp_mm);
    assert(rc    == IB_OK);
    assert(items != NULL);

    for (;;) {
        char *buffer_copy;
        int   read = getline(&buffer, &buffer_size, fp);
        char *space = NULL;
        ib_num_t confidence = 0;
        sqli_fingerprint_entry_t *entry = ib_mm_alloc(tmp_mm, sizeof(*entry));

        if (read == -1) {
            if (! feof(fp)) {
                fclose(fp);
                goto fail;
            }
            else {
                break;
            }
        }
        while (buffer[read-1] == '\n' || buffer[read-1] == '\r') {
            buffer[read-1] = '\0';
            --read;
        }

        space = strstr(buffer, " ");
        if (space != NULL) {
            rc = ib_type_atoi(space + 1, 10, &confidence);
            if (rc != IB_OK || confidence > 100) {
                return IB_EINVAL;
            }
            *space = '\0';
        }

        buffer_copy = ib_mm_strdup(mm, buffer);
        assert(buffer_copy != NULL);

        entry->confidence = confidence;
        entry->fingerprint = buffer_copy;

        rc = ib_list_push(items, (void *)entry);
        assert(rc == IB_OK);
    }

    fclose(fp);

    ps = ib_mm_alloc(mm, sizeof(*ps));
    assert(ps != NULL);

    ps->num_fingerprints = ib_list_elements(items);
    ps->fingerprints =
        ib_mm_alloc(mm, ps->num_fingerprints * sizeof(*ps->fingerprints));
    assert(ps->fingerprints != NULL);

    i = 0;
    IB_LIST_LOOP(items, n) {
        const sqli_fingerprint_entry_t *entry =
            (const sqli_fingerprint_entry_t *)ib_list_node_data(n);
        ps->fingerprints[i] = *entry;
        ++i;
    }
    assert(i == ps->num_fingerprints);

    ib_mpool_lite_destroy(tmp);

    qsort(
        ps->fingerprints, ps->num_fingerprints,
        sizeof(*ps->fingerprints),
        &sqli_cmp
    );

    *out_ps = ps;

    return IB_OK;

fail:
    ib_mpool_lite_destroy(tmp);
    return IB_EINVAL;
}
Exemple #17
0
ib_status_t ib_tfn_execute(
    ib_mpool_t        *mp,
    const ib_tfn_t    *tfn,
    const ib_field_t  *fin,
    const ib_field_t **fout
)
{
    assert(mp   != NULL);
    assert(tfn  != NULL);
    assert(fin  != NULL);
    assert(fout != NULL);

    ib_status_t       rc;
    const ib_field_t *out = NULL;

    if (fin->type == IB_FTYPE_LIST && ! ib_tfn_handle_list(tfn)) {
        /* Unroll list */
        const ib_list_t *value_list;
        const ib_list_node_t *node;
        ib_list_t *out_list;
        ib_field_t *fnew;

        rc = ib_field_value(fin, ib_ftype_list_out(&value_list));
        if (rc != IB_OK) {
            return rc;
        }

        rc = ib_list_create(&out_list, mp);
        if (rc != IB_OK) {
            return rc;
        }

        IB_LIST_LOOP_CONST(value_list, node) {
            const ib_field_t *in;
            const ib_field_t *tfn_out;

            in = (const ib_field_t *)ib_list_node_data_const(node);
            assert(in != NULL);

            rc = ib_tfn_execute(mp, tfn, in, &tfn_out);
            if (rc != IB_OK) {
                return rc;
            }
            if (tfn_out == NULL) {
                return IB_EINVAL;
            }

            rc = ib_list_push(out_list, (void *)tfn_out);
            if (rc != IB_OK) {
                return rc;
            }
        }

        /* Finally, create the output field (list) and return it */
        rc = ib_field_create(&fnew, mp,
                             fin->name, fin->nlen,
                             IB_FTYPE_LIST, ib_ftype_list_in(out_list));
        if (rc != IB_OK) {
            return rc;
        }
        out = fnew;
    }
    else {
Exemple #18
0
/*
 * Recursive function that return a list of all the datas found under this cidr
 *
 * @param node the node to check
 * @param prefix the prefix we are searching
 * @param offset, the number of bits already compared +1 (cur possition)
 * @param rlist reference to a pointer where the list will be allocated
 * @param mp pool where we should allocate the list
 *
 * @returns Status code
 */
static ib_status_t ib_radix_match_all(ib_radix_node_t *node,
                                                ib_radix_prefix_t *prefix,
                                                int offset,
                                                ib_list_t **rlist,
                                                ib_mpool_t *mp)
{
    IB_FTRACE_INIT(ib_radix_match_all);
    ib_status_t ret = IB_OK;
    uint8_t inserted = 0;

    if (node == NULL) {
        IB_FTRACE_RET_STATUS(IB_ENOENT);
    }

    if (offset >= prefix->prefixlen && node->data != NULL) {
        if (*rlist == NULL) {
            ret = ib_list_create(rlist, mp);
            if (ret != IB_OK) {
                IB_FTRACE_RET_STATUS(ret);
            }
        }

        ret = ib_list_push(*rlist, node->data);
        if (ret != IB_OK) {
            IB_FTRACE_RET_STATUS(ret);
        }

        inserted = 1;
    }
    else {
        int i = 0;

        for (; i < node->prefix->prefixlen && offset < prefix->prefixlen;
              i++, offset++)
        {
            if (IB_READ_BIT(node->prefix->rawbits[i / 8], i % 8) !=
                IB_READ_BIT(prefix->rawbits[offset / 8], offset % 8))
            {
                IB_FTRACE_RET_STATUS(IB_ENOENT);
            }
    
            if (offset >= prefix->prefixlen && node->data != NULL) {
                if (*rlist == NULL) {
                    ret = ib_list_create(rlist, mp);
                    if (ret != IB_OK) {
                        IB_FTRACE_RET_STATUS(ret);
                    }
                }

                ret = ib_list_push(*rlist, node->data);
                if (ret != IB_OK) {
                    IB_FTRACE_RET_STATUS(ret);
                }

                inserted = 1;
                break;
            }
        }
    }

    if (inserted == 0 && offset >= prefix->prefixlen && node->data != NULL) {
        if (*rlist == NULL) {
            ret = ib_list_create(rlist, mp);
            if (ret != IB_OK) {
                IB_FTRACE_RET_STATUS(ret);
            }
        }
        ret = ib_list_push(*rlist, node->data);
        if (ret != IB_OK) {
            IB_FTRACE_RET_STATUS(ret);
        }
    }

    if (offset >= prefix->prefixlen) {
        ret = ib_radix_match_all(node->zero, prefix, offset, rlist, mp);
        if (ret != IB_OK && ret != IB_ENOENT) {
            IB_FTRACE_RET_STATUS(ret);
        }
            
        ret = ib_radix_match_all(node->one, prefix, offset, rlist, mp);
        if (ret != IB_OK && ret != IB_ENOENT) {
            IB_FTRACE_RET_STATUS(ret);
        }
    }
    else {
        if (IB_READ_BIT(prefix->rawbits[offset / 8], offset % 8) == 0) {
            ret = ib_radix_match_all(node->zero, prefix, offset, rlist, mp);
        }
        else {
            ret = ib_radix_match_all(node->one, prefix, offset, rlist, mp);
        }
    }

    IB_FTRACE_RET_STATUS(ret);
}
Exemple #19
0
/*
 * Function that return a list of all the datas with a prefix that start like
 * the provided prefix arg
 *
 * Example: insert data in 192.168.1.27, as well as 192.168.1.28,
 * as well as 192.168.10.0/24 and 10.0.0.0/8 and then search 192.168.0.0/16
 * it should return a list containing all the datas except the associated to
 * 10.0.0.0/8
 *
 * @param node the node to check
 * @param prefix the prefix we are searching
 * @param offset, the number of bits already compared +1 (cur possition)
 * @param rlist reference to the pointer that will be linked to the list, if any
 * @param mp pool where we should allocate the list
 *
 * @returns Status code
 */
ib_status_t ib_radix_match_all_data(ib_radix_t *radix,
                                     ib_radix_prefix_t *prefix,
                                     ib_list_t **rlist,
                                     ib_mpool_t *mp)
{
    IB_FTRACE_INIT(ib_radix_match_all_data);
    ib_status_t ret;

    if (rlist == NULL) {
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    if (radix->start == NULL) {
        IB_FTRACE_RET_STATUS(IB_ENOENT);
    }

    if (radix->start->data != NULL  &&
        prefix->prefixlen == 0)
    {
        if (*rlist == NULL) {
            ret = ib_list_create(rlist, mp);
            if (ret != IB_OK) {
                IB_FTRACE_RET_STATUS(ret);
            }
        }
        ret = ib_list_push(*rlist, radix->start->data);
        if (ret != IB_OK) {
            IB_FTRACE_RET_STATUS(ret);
        }
    }

    if (prefix->prefixlen == 0) {
            // Append data of both branches
            ret = ib_radix_match_all(radix->start->zero, prefix, 0,
                                        rlist, mp);
            if (ret != IB_OK && ret != IB_ENOENT) {
                IB_FTRACE_RET_STATUS(ret);
            }
            ret = ib_radix_match_all(radix->start->one, prefix, 0,
                                        rlist, mp);
            if (ret != IB_OK && ret != IB_ENOENT) {
                IB_FTRACE_RET_STATUS(ret);
            }
    }
    else {
        // Follow it's path until we reach the correct offset
        if (IB_GET_DIR(prefix->rawbits[0]) == 0) {
            ret = ib_radix_match_all(radix->start->zero, prefix, 0,
                                        rlist, mp);
        }
        else {
            ret = ib_radix_match_all(radix->start->one, prefix, 0,
                                        rlist, mp);
        }
    }

    if (ret == IB_ENOENT && *rlist != NULL &&
        ib_list_elements(*rlist) > 0) {
        IB_FTRACE_RET_STATUS(IB_OK);
    }

    IB_FTRACE_RET_STATUS(ret);
}
Exemple #20
0
/// @test Test util list library - ib_list_push() and ib_list_pop()
TEST_F(TestIBUtilList, test_list_push_and_pop)
{
    ib_list_t *list;
    ib_status_t rc;
    int v0 = 0;
    int v1 = 1;
    int v2 = 2;
    int v3 = 3;
    int v4 = 4;
    int *val;

    rc = ib_list_create(&list, MemPool());
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(list);
    ASSERT_EQ(0UL, ib_list_elements(list));

    /* Pop invalid. */
    rc = ib_list_pop(list,(void *)&val);
    ASSERT_EQ(IB_ENOENT, rc);
    ASSERT_FALSE(val);
    ASSERT_EQ(0UL, ib_list_elements(list));

    /* Simple pushes followed by pops. */
    rc = ib_list_push(list, &v0);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(1UL, ib_list_elements(list));
    rc = ib_list_push(list, &v1);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(2UL, ib_list_elements(list));
    rc = ib_list_push(list, &v2);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(3UL, ib_list_elements(list));
    rc = ib_list_push(list, &v3);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(4UL, ib_list_elements(list));
    rc = ib_list_push(list, &v4);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_EQ(5UL, ib_list_elements(list));
    ASSERT_EQ(v0, *(int *)(ib_list_node_data(ib_list_first(list))));
    ASSERT_EQ(v4, *(int *)(ib_list_node_data(ib_list_last(list))));
    rc = ib_list_pop(list, (void *)&val);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(val);
    ASSERT_EQ(v4, *val);
    ASSERT_EQ(4UL, ib_list_elements(list));
    rc = ib_list_pop(list, (void *)&val);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(val);
    ASSERT_EQ(v3, *val);
    ASSERT_EQ(3UL, ib_list_elements(list));
    rc = ib_list_pop(list, (void *)&val);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(val);
    ASSERT_EQ(v2, *val);
    ASSERT_EQ(2UL, ib_list_elements(list));
    rc = ib_list_pop(list, (void *)&val);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(val);
    ASSERT_EQ(v1, *val);
    ASSERT_EQ(1UL, ib_list_elements(list));
    rc = ib_list_pop(list, (void *)&val);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(val);
    ASSERT_EQ(v0, *val);
    ASSERT_EQ(0UL, ib_list_elements(list));
}
Exemple #21
0
/**
 * Create an alias list collection.
 *
 * @param ib Engine.
 * @param tx Transaction.
 * @param name Collection name
 * @param header Header list to alias
 *
 * @returns Status code
 */
static ib_status_t create_header_alias_list(
    ib_engine_t *ib,
    ib_tx_t *tx,
    const char *name,
    ib_parsed_header_wrapper_t *header)
{
    ib_field_t *f;
    ib_list_t *header_list;
    ib_status_t rc;
    ib_parsed_name_value_pair_list_t *nvpair;

    assert(ib != NULL);
    assert(tx != NULL);
    assert(name != NULL);
    assert(header != NULL);

    /* Create the list */
    rc = ib_data_get(tx->data, name, &f);
    if (rc == IB_ENOENT) {
        rc = ib_data_add_list(tx->data, name, &f);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else if (rc != IB_OK) {
        return rc;
    }
    rc = ib_field_mutable_value(f, ib_ftype_list_mutable_out(&header_list));
    if (rc != IB_OK) {
        return rc;
    }

    /* Loop through the list & alias everything */
    for(nvpair = header->head;  nvpair != NULL;  nvpair = nvpair->next) {
        assert(nvpair);
        assert(nvpair->value);
        ib_bytestr_t *bs = NULL;
        if (ib_bytestr_ptr(nvpair->value) != NULL) {
            rc = ib_bytestr_alias_mem(
                &bs,
                tx->mp,
                ib_bytestr_ptr(nvpair->value),
                ib_bytestr_length(nvpair->value)
            );
        }
        else {
            rc = ib_bytestr_dup_mem(&bs, tx->mp, (const uint8_t *)"", 0);
        }
        if (rc != IB_OK) {
            ib_log_error_tx(
                tx,
                "Error creating bytestring of '%.*s' for %s: %s",
                (int)ib_bytestr_length(nvpair->name),
                (const char *)ib_bytestr_ptr(nvpair->name),
                name,
                ib_status_to_string(rc)
            );
            return rc;
        }

        /* Create a byte string field */
        rc = ib_field_create(
            &f,
            tx->mp,
            (const char *)ib_bytestr_const_ptr(nvpair->name),
            ib_bytestr_length(nvpair->name),
            IB_FTYPE_BYTESTR,
            ib_ftype_bytestr_in(bs)
        );
        if (rc != IB_OK) {
            ib_log_error_tx(tx,
                            "Error creating field of '%.*s' for %s: %s",
                            (int)ib_bytestr_length(nvpair->name),
                            (const char *)ib_bytestr_ptr(nvpair->name),
                            name,
                            ib_status_to_string(rc));
            return rc;
        }

        /* Add the field to the list */
        rc = ib_list_push(header_list, f);
        if (rc != IB_OK) {
            ib_log_error_tx(tx, "Error adding alias of '%.*s' to %s list: %s",
                            (int)ib_bytestr_length(nvpair->name),
                            (const char *)ib_bytestr_ptr(nvpair->name),
                            name,
                            ib_status_to_string(rc));
            return rc;
        }
    }

    return IB_OK;
}
Exemple #22
0
 /**
  * Push @a value to back of list.
  *
  * @param[in] value Value to push to back of list.
  **/
 void push_back(T value) const
 {
     Internal::throw_if_error(
         ib_list_push(m_ib, Internal::value_as_void(value))
     );
 }
/**
 * Handle managed collection registration for vars "name=value" parameters
 *
 * @param[in] ib Engine
 * @param[in] module Collection manager's module object (unused)
 * @param[in] manager The collection manager object to register with (unused)
 * @param[in] mp Memory pool to use for allocations
 * @param[in] collection_name Name of the collection
 * @param[in] uri Full collection URI (unused)
 * @param[in] uri_scheme URI scheme (unused)
 * @param[in] uri_data Hierarchical/data part of the URI
 * @param[in] params List of parameter strings
 * @param[in] register_data Register callback data (unused)
 * @param[out] pmanager_inst_data Pointer to manager specific collection data
 *
 * @returns Status code:
 *   - IB_OK All OK
 *   - IB_Exxx Other error
 */
static ib_status_t core_managed_collection_vars_register_fn(
    const ib_engine_t             *ib,
    const ib_module_t             *module,
    const ib_collection_manager_t *manager,
    ib_mpool_t                    *mp,
    const char                    *collection_name,
    const char                    *uri,
    const char                    *uri_scheme,
    const char                    *uri_data,
    const ib_list_t               *params,
    void                          *register_data,
    void                         **pmanager_inst_data)
{
    assert(ib != NULL);
    assert(module != NULL);
    assert(mp != NULL);
    assert(collection_name != NULL);
    assert(params != NULL);
    assert(pmanager_inst_data != NULL);

    const ib_list_node_t *node;
    ib_list_t *vars_list;
    ib_list_t *field_list;
    ib_mpool_t *tmp = ib_engine_pool_temp_get(ib);
    ib_status_t rc;

    if (strlen(uri_data) != 0) {
        return IB_DECLINED;
    }
    if (ib_list_elements(params) < 1) {
        return IB_EINVAL;
    }

    /* Create a temporary list */
    rc = ib_list_create(&vars_list, tmp);
    if (rc != IB_OK) {
        return rc;
    }

    /* First pass; walk through all params, look for "a=b" type syntax */
    IB_LIST_LOOP_CONST(params, node) {
        static const int ovecsize = 9;
        int ovector[ovecsize];
        const char *param = (const char *)node->data;
        core_vars_t *vars;
        int pcre_rc;

        pcre_rc = pcre_exec(core_vars_manager.pattern, NULL,
                            param, strlen(param),
                            0, 0, ovector, ovecsize);
        if (pcre_rc < 0) {
            return IB_DECLINED;
        }

        vars = ib_mpool_alloc(tmp, sizeof(*vars));
        if (vars == NULL) {
            return IB_EALLOC;
        }
        vars->name  = ib_mpool_memdup_to_str(tmp,
                                             param + ovector[2],
                                             ovector[3] - ovector[2]);
        vars->value = ib_mpool_memdup_to_str(tmp,
                                             param + ovector[4],
                                             ovector[5] - ovector[4]);
        if ( (vars->name == NULL) || (vars->value == NULL) ) {
            return IB_EALLOC;
        }
        rc = ib_list_push(vars_list, vars);
        if (rc != IB_OK) {
            return rc;
        }
    }

    /* Build the list of fields */
    rc = ib_list_create(&field_list, mp);
    if (rc != IB_OK) {
        return rc;
    }

    /* Now walk though the list, creating a field for each one */
    IB_LIST_LOOP_CONST(vars_list, node) {
        const core_vars_t *vars = (const core_vars_t *)node->data;
        ib_field_t *field;
        ib_field_val_union_t fval;

        rc = ib_field_from_string(mp,
                                  IB_FIELD_NAME(vars->name), vars->value,
                                  &field, &fval);
        if (rc != IB_OK) {
            ib_log_error(ib, "Error creating field (\"%s\", \"%s\"): %s",
                         vars->name, vars->value,
                         ib_status_to_string(rc));
            return rc;
        }
        rc = ib_list_push(field_list, field);
        if (rc != IB_OK) {
            return rc;
        }

        if (field->type == IB_FTYPE_NUM) {
            ib_log_trace(ib, "Created numeric field \"%s\" %"PRId64" in \"%s\"",
                         vars->name, fval.num, collection_name);
        }

        else if (field->type == IB_FTYPE_FLOAT) {
            ib_log_trace(ib, "Created float field \"%s\" %f in \"%s\"",
                         vars->name, (double)fval.fnum, collection_name);
        }
        else {
            ib_log_trace(ib, "Created string field \"%s\" \"%s\" in \"%s\"",
                         vars->name, fval.nulstr, collection_name);
        }
    }

    /* Finally, store the list as the manager specific collection data */
    *pmanager_inst_data = field_list;

    return IB_OK;
}