void rpc_mtree_match(rpc_t* rpc, void* ctx) { str tname = STR_NULL; str tomatch = STR_NULL; int mode = -1; m_tree_t *tr; if(!mt_defined_trees()) { rpc->fault(ctx, 500, "Empty tree list."); return; } if (rpc->scan(ctx, ".SSd", &tname, &tomatch, &mode) < 3) { rpc->fault(ctx, 500, "Invalid Parameters"); return; } if (mode !=0 && mode != 2) { rpc->fault(ctx, 500, "Invalid parameter 'mode'"); return; } again: lock_get( mt_lock ); if (mt_reload_flag) { lock_release( mt_lock ); sleep_us(5); goto again; } mt_tree_refcnt++; lock_release( mt_lock ); tr = mt_get_tree(&tname); if(tr==NULL) { /* no tree with such name*/ rpc->fault(ctx, 404, "Not found tree"); goto error; } if(mt_rpc_match_prefix(rpc, ctx, tr, &tomatch, mode)<0) { LM_DBG("no prefix found in [%.*s] for [%.*s]\n", tname.len, tname.s, tomatch.len, tomatch.s); rpc->fault(ctx, 404, "Not found"); } error: lock_get( mt_lock ); mt_tree_refcnt--; lock_release( mt_lock ); }
/* use tree tn, match var, by mode, output in avp params */ static int mt_match(sip_msg_t *msg, str *tname, str *tomatch, int mval) { m_tree_t *tr = NULL; if(msg==NULL) { LM_ERR("received null msg\n"); return -1; } again: lock_get( mt_lock ); if (mt_reload_flag) { lock_release( mt_lock ); sleep_us(5); goto again; } mt_tree_refcnt++; lock_release( mt_lock ); tr = mt_get_tree(tname); if(tr==NULL) { /* no tree with such name*/ goto error; } if(mt_match_prefix(msg, tr, tomatch, mval)<0) { LM_DBG("no prefix found in [%.*s] for [%.*s]\n", tname->len, tname->s, tomatch->len, tomatch->s); goto error; } lock_get( mt_lock ); mt_tree_refcnt--; lock_release( mt_lock ); return 1; error: lock_get( mt_lock ); mt_tree_refcnt--; lock_release( mt_lock ); return -1; }
static int mt_load_db(m_tree_t *pt) { db_key_t db_cols[MT_MAX_COLS] = {&tprefix_column, &tvalue_column}; db_key_t key_cols[1]; db_op_t op[1] = {OP_EQ}; db_val_t vals[1]; str tprefix, tvalue; db1_res_t* db_res = NULL; int i, ret, c; m_tree_t new_tree; m_tree_t *old_tree = NULL; mt_node_t *bk_head = NULL; if(pt->ncols>0) { for(c=0; c<pt->ncols; c++) { db_cols[c] = &pt->scols[c]; } } else { db_cols[0] = &tprefix_column; db_cols[1] = &tvalue_column; c = 2; } key_cols[0] = &tname_column; VAL_TYPE(vals) = DB1_STRING; VAL_NULL(vals) = 0; VAL_STRING(vals) = pt->tname.s; if(db_con==NULL) { LM_ERR("no db connection\n"); return -1; } old_tree = mt_get_tree(&(pt->tname)); if(old_tree==NULL) { LM_ERR("tree definition not found [%.*s]\n", pt->tname.len, pt->tname.s); return -1; } memcpy(&new_tree, old_tree, sizeof(m_tree_t)); new_tree.head = 0; new_tree.next = 0; new_tree.nrnodes = 0; new_tree.nritems = 0; new_tree.memsize = 0; new_tree.reload_count++; new_tree.reload_time = (unsigned int)time(NULL); if (mt_dbf.use_table(db_con, &old_tree->dbtable) < 0) { LM_ERR("failed to use_table\n"); return -1; } if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) { if(mt_dbf.query(db_con, key_cols, op, vals, db_cols, pt->multi, c, 0, 0) < 0) { LM_ERR("Error while querying db\n"); return -1; } if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) { LM_ERR("Error while fetching result\n"); goto error; } else { if(RES_ROW_N(db_res)==0) { goto dbreloaded; } } } else { if((ret=mt_dbf.query(db_con, key_cols, op, vals, db_cols, pt->multi, 2, 0, &db_res))!=0 || RES_ROW_N(db_res)<=0 ) { if(ret==0) { goto dbreloaded; } else { goto error; } } } if(RES_ROW_N(db_res)>0) { if(RES_ROWS(db_res)[0].values[0].type != DB1_STRING || RES_ROWS(db_res)[0].values[1].type != DB1_STRING) { LM_ERR("wrond column types in db table (%d / %d)\n", RES_ROWS(db_res)[0].values[0].type, RES_ROWS(db_res)[0].values[1].type); goto error; } } do { for(i=0; i<RES_ROW_N(db_res); i++) { /* check for NULL values ?!?! */ tprefix.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val); tprefix.len = strlen(ZSW(tprefix.s)); if(c>2) { if(mt_pack_values(&new_tree, db_res, i, c, &tvalue)<0) { LM_ERR("Error packing values\n"); goto error; } } else { tvalue.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val); tvalue.len = strlen(ZSW(tvalue.s)); } if(tprefix.s==NULL || tvalue.s==NULL || tprefix.len<=0 || tvalue.len<=0) { LM_ERR("Error - bad record in db" " (prefix: %p/%d - value: %p/%d)\n", tprefix.s, tprefix.len, tvalue.s, tvalue.len); continue; } if(mt_add_to_tree(&new_tree, &tprefix, &tvalue)<0) { LM_ERR("Error adding info to tree\n"); goto error; } } if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) { if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) { LM_ERR("Error while fetching!\n"); if (db_res) mt_dbf.free_result(db_con, db_res); goto error; } } else { break; } } while(RES_ROW_N(db_res)>0); dbreloaded: mt_dbf.free_result(db_con, db_res); /* block all readers */ lock_get( mt_lock ); mt_reload_flag = 1; lock_release( mt_lock ); while (mt_tree_refcnt) { sleep_us(10); } bk_head = old_tree->head; old_tree->head = new_tree.head; old_tree->nrnodes = new_tree.nrnodes; old_tree->nritems = new_tree.nritems; old_tree->memsize = new_tree.memsize; old_tree->reload_count = new_tree.reload_count; old_tree->reload_time = new_tree.reload_time; mt_reload_flag = 0; /* free old data */ if (bk_head!=NULL) mt_free_node(bk_head, new_tree.type); return 0; error: mt_dbf.free_result(db_con, db_res); if (new_tree.head!=NULL) mt_free_node(new_tree.head, new_tree.type); return -1; }
/* use tree tn, match var, by mode, output in avp params */ static int mt_match(struct sip_msg *msg, gparam_t *tn, gparam_t *var, gparam_t *mode) { str tname; str tomatch; int mval; m_tree_t *tr = NULL; if(msg==NULL) { LM_ERR("received null msg\n"); return -1; } if(fixup_get_svalue(msg, tn, &tname)<0) { LM_ERR("cannot get the tree name\n"); return -1; } if(fixup_get_svalue(msg, var, &tomatch)<0) { LM_ERR("cannot get the match var\n"); return -1; } if(fixup_get_ivalue(msg, mode, &mval)<0) { LM_ERR("cannot get the mode\n"); return -1; } again: lock_get( mt_lock ); if (mt_reload_flag) { lock_release( mt_lock ); sleep_us(5); goto again; } mt_tree_refcnt++; lock_release( mt_lock ); tr = mt_get_tree(&tname); if(tr==NULL) { /* no tree with such name*/ goto error; } if(mt_match_prefix(msg, tr, &tomatch, mval)<0) { LM_DBG("no prefix found in [%.*s] for [%.*s]\n", tname.len, tname.s, tomatch.len, tomatch.s); goto error; } lock_get( mt_lock ); mt_tree_refcnt--; lock_release( mt_lock ); return 1; error: lock_get( mt_lock ); mt_tree_refcnt--; lock_release( mt_lock ); return -1; }
static int mt_load_db(str *tname) { db_key_t db_cols[3] = {&tprefix_column, &tvalue_column}; str tprefix, tvalue; db1_res_t* db_res = NULL; int i, ret; m_tree_t new_tree; m_tree_t *old_tree = NULL; mt_node_t *bk_head = NULL; if(db_con==NULL) { LM_ERR("no db connection\n"); return -1; } LM_ERR("attempting to load [%.*s]\n", tname->len, tname->s); old_tree = mt_get_tree(tname); if(old_tree==NULL) { LM_ERR("tree definition not found [%.*s]\n", tname->len, tname->s); return -1; } memcpy(&new_tree, old_tree, sizeof(m_tree_t)); new_tree.head = 0; new_tree.next = 0; if (mt_dbf.use_table(db_con, &old_tree->dbtable) < 0) { LM_ERR("failed to use_table\n"); return -1; } if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) { if(mt_dbf.query(db_con, 0, 0, 0, db_cols, 0, 2, 0, 0) < 0) { LM_ERR("Error while querying db\n"); return -1; } if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) { LM_ERR("Error while fetching result\n"); if (db_res) mt_dbf.free_result(db_con, db_res); goto error; } else { if(RES_ROW_N(db_res)==0) { return 0; } } } else { if((ret=mt_dbf.query(db_con, NULL, NULL, NULL, db_cols, 0, 2, 0, &db_res))!=0 || RES_ROW_N(db_res)<=0 ) { mt_dbf.free_result(db_con, db_res); if( ret==0) { return 0; } else { goto error; } } } do { for(i=0; i<RES_ROW_N(db_res); i++) { /* check for NULL values ?!?! */ tprefix.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val); tprefix.len = strlen(tprefix.s); tvalue.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val); tvalue.len = strlen(tvalue.s); if(tprefix.s==NULL || tvalue.s==NULL || tprefix.len<=0 || tvalue.len<=0) { LM_ERR("Error - bad values in db\n"); continue; } if(mt_add_to_tree(&new_tree, &tprefix, &tvalue)<0) { LM_ERR("Error adding info to tree\n"); goto error; } } if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) { if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) { LM_ERR("Error while fetching!\n"); if (db_res) mt_dbf.free_result(db_con, db_res); goto error; } } else { break; } } while(RES_ROW_N(db_res)>0); mt_dbf.free_result(db_con, db_res); /* block all readers */ lock_get( mt_lock ); mt_reload_flag = 1; lock_release( mt_lock ); while (mt_tree_refcnt) { sleep_us(10); } bk_head = old_tree->head; old_tree->head = new_tree.head; mt_reload_flag = 0; /* free old data */ if (bk_head!=NULL) mt_free_node(bk_head, new_tree.type); return 0; error: mt_dbf.free_result(db_con, db_res); if (new_tree.head!=NULL) mt_free_node(new_tree.head, new_tree.type); return -1; }