// 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); }
/// @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++; }
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; }
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); }
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); }
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; }
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); }
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); }
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; }
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); }
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); }
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); }
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); }
/********************************* * 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; }
/** * @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); }
/********************************* * 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; }
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 {
/* * 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); }
/* * 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); }
/// @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)); }
/** * 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; }
/** * 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; }