udomain.c
来自「性能优秀的SIP Proxy」· C语言 代码 · 共 816 行 · 第 1/2 页
C
816 行
} if (ul_dbf.query(_c, 0, 0, 0, columns, 0, (use_domain) ? (14) : (13), 0, &res) < 0) { LOG(L_ERR, "preload_udomain(): Error while doing db_query\n"); return -1; } if (RES_ROW_N(res) == 0) { DBG("preload_udomain(): Table is empty\n"); ul_dbf.free_result(_c, res); return 0; } lock_udomain(_d); for(i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; user.s = (char*)VAL_STRING(ROW_VALUES(row)); if (VAL_NULL(ROW_VALUES(row)) || user.s==0 || user.s[0]==0) { LOG(L_CRIT, "ERROR:usrloc:preload_udomain: empty username " "record in table %s...skipping\n",_d->name->s); continue; } user.len = strlen(user.s); ci = dbrow2info( ROW_VALUES(row)+1, &contact); if (ci==0) { LOG(L_ERR, "ERROR:usrloc:preload_udomain: skipping record for " "%.*s in table %s\n", user.len, user.s, _d->name->s); continue; } if (use_domain) { domain = (char*)VAL_STRING(ROW_VALUES(row) + 13); if (VAL_NULL(ROW_VALUES(row)+12) || domain==0 || domain[0]==0) { LOG(L_CRIT, "ERROR:usrloc:preload_udomain: empty domain " "record for user %.*s...skipping\n", user.len, user.s); continue; } /* user.s cannot be NULL - checked previosly */ user.len = snprintf(uri, MAX_URI_SIZE, "%.*s@%s", user.len, user.s, domain); user.s = uri; if (user.s[user.len]!=0) { LOG(L_CRIT,"ERROR:usrloc:preload_udomain: URI '%.*s@%s' " "longer than %d\n", user.len, user.s, domain,MAX_URI_SIZE); continue; } } if (get_urecord(_d, &user, &r) > 0) { if (mem_insert_urecord(_d, &user, &r) < 0) { LOG(L_ERR, "preload_udomain(): Can't create a record\n"); goto error; } } if ( (c=mem_insert_ucontact(r, &contact, ci)) < 0) { LOG(L_ERR, "preload_udomain(): Error while inserting contact\n"); goto error1; } /* We have to do this, because insert_ucontact sets state to CS_NEW * and we have the contact in the database already */ c->state = CS_SYNC; } ul_dbf.free_result(_c, res); unlock_udomain(_d); return 0;error1: free_ucontact(c);error: ul_dbf.free_result(_c, res); unlock_udomain(_d); return -1;}/* * loads from DB all contacts for an AOR */urecord_t* db_load_urecord(db_con_t* _c, udomain_t* _d, str *_aor){ ucontact_info_t *ci; db_key_t columns[12]; db_key_t keys[2]; db_val_t vals[2]; db_res_t* res; str contact; char *domain; int i; urecord_t* r; ucontact_t* c; keys[0] = user_col.s; vals[0].type = DB_STR; vals[0].nul = 0; if (use_domain) { keys[1] = domain_col.s; vals[1].type = DB_STR; vals[1].nul = 0; domain = q_memchr(_aor->s, '@', _aor->len); if (domain==0) { LOG(L_CRIT,"BUG:usrloc:db_load_urecord: AOR has no @ while " "use_domain is enabled\n"); return 0; } vals[0].val.str_val.s = _aor->s; vals[0].val.str_val.len = domain - _aor->s; vals[1].val.str_val.s = domain+1; vals[1].val.str_val.len = _aor->s + _aor->len - domain - 1; } else { vals[0].val.str_val = *_aor; } columns[0] = contact_col.s; columns[1] = expires_col.s; columns[2] = q_col.s; columns[3] = callid_col.s; columns[4] = cseq_col.s; columns[5] = flags_col.s; columns[6] = user_agent_col.s; columns[7] = received_col.s; columns[8] = path_col.s; columns[9] = sock_col.s; columns[10] = methods_col.s; columns[11] = last_mod_col.s; if (ul_dbf.use_table(_c, _d->name->s) < 0) { LOG(L_ERR, "ERROR:usrloc:db_load_urecord: failed to use_table\n"); return 0; } if (ul_dbf.query(_c, keys, 0, vals, columns, (use_domain)?2:1, 12, 0, &res) < 0) { LOG(L_ERR, "ERROR:usrloc:db_load_urecord: db_query failed\n"); return 0; } if (RES_ROW_N(res) == 0) { DBG("DEBUG:usrloc:db_load_urecord: aor not found in DB\n"); ul_dbf.free_result(_c, res); return 0; } r = 0; for(i = 0; i < RES_ROW_N(res); i++) { ci = dbrow2info( ROW_VALUES(RES_ROWS(res) + i), &contact); if (ci==0) { LOG(L_ERR, "ERROR:usrloc:db_load_urecord: skipping record for " "%.*s in table %s\n", _aor->len, _aor->s, _d->name->s); continue; } if ( r==0 ) get_static_urecord( _d, _aor, &r); if ( (c=mem_insert_ucontact(r, &contact, ci)) < 0) { LOG(L_ERR, "ERROR:usrloc:db_load_urecord: mem_insert failed\n"); free_urecord(r); ul_dbf.free_result(_c, res); return 0; } /* We have to do this, because insert_ucontact sets state to CS_NEW * and we have the contact in the database already */ c->state = CS_SYNC; } ul_dbf.free_result(_c, res); return r;}int db_timer_udomain(udomain_t* _d){ db_key_t keys[1]; db_op_t ops[1]; db_val_t vals[1]; keys[0] = expires_col.s; ops[0] = "<"; vals[0].type = DB_DATETIME; vals[0].nul = 0; vals[0].val.time_val = act_time + 1; if (ul_dbf.use_table(ul_dbh, _d->name->s) < 0) { LOG(L_ERR, "ERROR:usrloc: db_timer_udomain: use_table failed\n"); return -1; } if (ul_dbf.delete(ul_dbh, keys, ops, vals, 1) < 0) { LOG(L_ERR, "ERROR:usrloc:db_timer_udomain: failed to delete from " "table %s\n",_d->name->s); return -1; } return 0;}/* performs a dummy query just to see if DB is ok */int testdb_udomain(db_con_t* con, udomain_t* d){ db_key_t key[1], col[1]; db_val_t val[1]; db_res_t* res; if (ul_dbf.use_table(con, d->name->s) < 0) { LOG(L_ERR, "ERROR:usrloc:testdb_udomain: failed to change table\n"); return -1; } key[0] = user_col.s; col[0] = user_col.s; VAL_TYPE(val) = DB_STRING; VAL_NULL(val) = 0; VAL_STRING(val) = "dummy_user"; if (ul_dbf.query( con, key, 0, val, col, 1, 1, 0, &res) < 0) { LOG(L_ERR, "ERROR:usrloc:testdb_udomain: failure in db_query\n"); return -1; } ul_dbf.free_result( con, res); return 0;}/* * Insert a new record into domain */int mem_insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r){ int sl; if (new_urecord(_d->name, _aor, _r) < 0) { LOG(L_ERR, "insert_urecord(): Error while creating urecord\n"); return -1; } sl = hash_func(_d, (unsigned char*)_aor->s, _aor->len); slot_add(&_d->table[sl], *_r); udomain_add(_d, *_r); update_stat( _d->users, 1); return 0;}/* * Remove a record from domain */void mem_delete_urecord(udomain_t* _d, struct urecord* _r){ if (_r->watchers == 0) { udomain_remove(_d, _r); slot_rem(_r->slot, _r); free_urecord(_r); update_stat( _d->users, -1); }}int mem_timer_udomain(udomain_t* _d){ struct urecord* ptr, *t; lock_udomain(_d); ptr = _d->d_ll.first; while(ptr) { if (timer_urecord(ptr) < 0) { LOG(L_ERR, "timer_udomain(): Error in timer_urecord\n"); unlock_udomain(_d); return -1; } /* Remove the entire record if it is empty */ if (ptr->contacts == 0) { t = ptr; ptr = ptr->d_ll.next; mem_delete_urecord(_d, t); } else { ptr = ptr->d_ll.next; } } unlock_udomain(_d); return 0;}/* * Get lock */void lock_udomain(udomain_t* _d){ if (db_mode!=DB_ONLY) lock_get(&_d->lock);}/* * Release lock */void unlock_udomain(udomain_t* _d){ if (db_mode!=DB_ONLY) lock_release(&_d->lock);}/* * Create and insert a new record */int insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r){ if (db_mode!=DB_ONLY) { if (mem_insert_urecord(_d, _aor, _r) < 0) { LOG(L_ERR, "insert_urecord(): Error while inserting record\n"); return -1; } } else { get_static_urecord( _d, _aor, _r); } return 0;}/* * Obtain a urecord pointer if the urecord exists in domain */int get_urecord(udomain_t* _d, str* _aor, struct urecord** _r){ int sl, i; urecord_t* r; if (db_mode!=DB_ONLY) { /* search in cache */ sl = hash_func(_d, (unsigned char*)_aor->s, _aor->len); r = _d->table[sl].first; for(i = 0; i < _d->table[sl].n; i++) { if((r->aor.len==_aor->len) && !memcmp(r->aor.s,_aor->s,_aor->len)){ *_r = r; return 0; } r = r->s_ll.next; } } else { /* search in DB */ r = db_load_urecord( ul_dbh, _d, _aor); if (r) { *_r = r; return 0; } } return 1; /* Nothing found */}/* * Delete a urecord from domain */int delete_urecord(udomain_t* _d, str* _aor, struct urecord* _r){ struct ucontact* c, *t; if (db_mode==DB_ONLY) { if (_r==0) get_static_urecord( _d, _aor, &_r); if (db_delete_urecord(_r)<0) { LOG(L_ERR, "ERROR:usrloc:delete_urecord: DB delete failed\n"); return -1; } free_urecord(_r); return 0; } if (_r==0) { if (get_urecord(_d, _aor, &_r) > 0) { return 0; } } c = _r->contacts; while(c) { t = c; c = c->next; if (delete_ucontact(_r, t) < 0) { LOG(L_ERR, "delete_urecord(): Error while deleting contact\n"); return -1; } } release_urecord(_r); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?