00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00038 #include "udomain.h"
00039 #include <string.h>
00040 #include "../../parser/parse_methods.h"
00041 #include "../../mem/shm_mem.h"
00042 #include "../../dprint.h"
00043 #include "../../lib/srdb1/db.h"
00044 #include "../../socket_info.h"
00045 #include "../../ut.h"
00046 #include "../../hashes.h"
00047 #include "ul_mod.h"
00048 #include "usrloc.h"
00049 #include "utime.h"
00050 #include "usrloc.h"
00051
00052 #ifdef STATISTICS
00053 static char *build_stat_name( str* domain, char *var_name)
00054 {
00055 int n;
00056 char *s;
00057 char *p;
00058
00059 n = domain->len + 1 + strlen(var_name) + 1;
00060 s = (char*)shm_malloc( n );
00061 if (s==0) {
00062 LM_ERR("no more shm mem\n");
00063 return 0;
00064 }
00065 memcpy( s, domain->s, domain->len);
00066 p = s + domain->len;
00067 *(p++) = '-';
00068 memcpy( p , var_name, strlen(var_name));
00069 p += strlen(var_name);
00070 *(p++) = 0;
00071 return s;
00072 }
00073 #endif
00074
00075
00084 int new_udomain(str* _n, int _s, udomain_t** _d)
00085 {
00086 int i;
00087 #ifdef STATISTICS
00088 char *name;
00089 #endif
00090
00091
00092
00093
00094
00095 *_d = (udomain_t*)shm_malloc(sizeof(udomain_t));
00096 if (!(*_d)) {
00097 LM_ERR("new_udomain(): No memory left\n");
00098 goto error0;
00099 }
00100 memset(*_d, 0, sizeof(udomain_t));
00101
00102 (*_d)->table = (hslot_t*)shm_malloc(sizeof(hslot_t) * _s);
00103 if (!(*_d)->table) {
00104 LM_ERR("no memory left 2\n");
00105 goto error1;
00106 }
00107
00108 (*_d)->name = _n;
00109
00110 for(i = 0; i < _s; i++) {
00111 init_slot(*_d, &((*_d)->table[i]), i);
00112 }
00113
00114 (*_d)->size = _s;
00115
00116 #ifdef STATISTICS
00117
00118 if ( (name=build_stat_name(_n,"users"))==0 || register_stat("usrloc",
00119 name, &(*_d)->users, STAT_NO_RESET|STAT_SHM_NAME)!=0 ) {
00120 LM_ERR("failed to add stat variable\n");
00121 goto error2;
00122 }
00123 if ( (name=build_stat_name(_n,"contacts"))==0 || register_stat("usrloc",
00124 name, &(*_d)->contacts, STAT_NO_RESET|STAT_SHM_NAME)!=0 ) {
00125 LM_ERR("failed to add stat variable\n");
00126 goto error2;
00127 }
00128 if ( (name=build_stat_name(_n,"expires"))==0 || register_stat("usrloc",
00129 name, &(*_d)->expires, STAT_SHM_NAME)!=0 ) {
00130 LM_ERR("failed to add stat variable\n");
00131 goto error2;
00132 }
00133 #endif
00134
00135 return 0;
00136 #ifdef STATISTICS
00137 error2:
00138 shm_free((*_d)->table);
00139 #endif
00140 error1:
00141 shm_free(*_d);
00142 error0:
00143 return -1;
00144 }
00145
00146
00151 void free_udomain(udomain_t* _d)
00152 {
00153 int i;
00154
00155 if (_d->table) {
00156 for(i = 0; i < _d->size; i++) {
00157 lock_ulslot(_d, i);
00158 deinit_slot(_d->table + i);
00159 unlock_ulslot(_d, i);
00160 }
00161 shm_free(_d->table);
00162 }
00163 shm_free(_d);
00164 }
00165
00166
00173 static inline void get_static_urecord(udomain_t* _d, str* _aor,
00174 struct urecord** _r)
00175 {
00176 static struct urecord r;
00177
00178 memset( &r, 0, sizeof(struct urecord) );
00179 r.aor = *_aor;
00180 r.aorhash = ul_get_aorhash(_aor);
00181 r.domain = _d->name;
00182 *_r = &r;
00183 }
00184
00185
00189 void print_udomain(FILE* _f, udomain_t* _d)
00190 {
00191 int i;
00192 int max=0, slot=0, n=0;
00193 struct urecord* r;
00194 fprintf(_f, "---Domain---\n");
00195 fprintf(_f, "name : '%.*s'\n", _d->name->len, ZSW(_d->name->s));
00196 fprintf(_f, "size : %d\n", _d->size);
00197 fprintf(_f, "table: %p\n", _d->table);
00198
00199 fprintf(_f, "\n");
00200 for(i=0; i<_d->size; i++)
00201 {
00202 r = _d->table[i].first;
00203 n += _d->table[i].n;
00204 if(max<_d->table[i].n){
00205 max= _d->table[i].n;
00206 slot = i;
00207 }
00208 while(r) {
00209 print_urecord(_f, r);
00210 r = r->next;
00211 }
00212 }
00213 fprintf(_f, "\nMax slot: %d (%d/%d)\n", max, slot, n);
00214 fprintf(_f, "\n---/Domain---\n");
00215 }
00216
00217
00228 static inline ucontact_info_t* dbrow2info( db_val_t *vals, str *contact)
00229 {
00230 static ucontact_info_t ci;
00231 static str callid, ua, received, host, path;
00232 int port, proto;
00233 char *p;
00234
00235 memset( &ci, 0, sizeof(ucontact_info_t));
00236
00237 contact->s = (char*)VAL_STRING(vals);
00238 if (VAL_NULL(vals) || contact->s==0 || contact->s[0]==0) {
00239 LM_CRIT("bad contact\n");
00240 return 0;
00241 }
00242 contact->len = strlen(contact->s);
00243
00244 if (VAL_NULL(vals+1)) {
00245 LM_CRIT("empty expire\n");
00246 return 0;
00247 }
00248 ci.expires = VAL_TIME(vals+1);
00249
00250 if (VAL_NULL(vals+2)) {
00251 LM_CRIT("empty q\n");
00252 return 0;
00253 }
00254 ci.q = double2q(VAL_DOUBLE(vals+2));
00255
00256 if (VAL_NULL(vals+4)) {
00257 LM_CRIT("empty cseq_nr\n");
00258 return 0;
00259 }
00260 ci.cseq = VAL_INT(vals+4);
00261
00262 callid.s = (char*)VAL_STRING(vals+3);
00263 if (VAL_NULL(vals+3) || !callid.s || !callid.s[0]) {
00264 LM_CRIT("bad callid\n");
00265 return 0;
00266 }
00267 callid.len = strlen(callid.s);
00268 ci.callid = &callid;
00269
00270 if (VAL_NULL(vals+5)) {
00271 LM_CRIT("empty flag\n");
00272 return 0;
00273 }
00274 ci.flags = VAL_BITMAP(vals+5);
00275
00276 if (VAL_NULL(vals+6)) {
00277 LM_CRIT("empty cflag\n");
00278 return 0;
00279 }
00280 ci.cflags = VAL_BITMAP(vals+6);
00281
00282 ua.s = (char*)VAL_STRING(vals+7);
00283 if (VAL_NULL(vals+7) || !ua.s || !ua.s[0]) {
00284 ua.s = 0;
00285 ua.len = 0;
00286 } else {
00287 ua.len = strlen(ua.s);
00288 }
00289 ci.user_agent = &ua;
00290
00291 received.s = (char*)VAL_STRING(vals+8);
00292 if (VAL_NULL(vals+8) || !received.s || !received.s[0]) {
00293 received.len = 0;
00294 received.s = 0;
00295 } else {
00296 received.len = strlen(received.s);
00297 }
00298 ci.received = received;
00299
00300 path.s = (char*)VAL_STRING(vals+9);
00301 if (VAL_NULL(vals+9) || !path.s || !path.s[0]) {
00302 path.len = 0;
00303 path.s = 0;
00304 } else {
00305 path.len = strlen(path.s);
00306 }
00307 ci.path= &path;
00308
00309
00310 p = (char*)VAL_STRING(vals+10);
00311 if (VAL_NULL(vals+10) || p==0 || p[0]==0){
00312 ci.sock = 0;
00313 } else {
00314 if (parse_phostport( p, &host.s, &host.len,
00315 &port, &proto)!=0) {
00316 LM_ERR("bad socket <%s>\n", p);
00317 return 0;
00318 }
00319 ci.sock = grep_sock_info( &host, (unsigned short)port, proto);
00320 if (ci.sock==0) {
00321 LM_WARN("non-local socket <%s>...ignoring\n", p);
00322 }
00323 }
00324
00325
00326 if (VAL_NULL(vals+11)) {
00327 ci.methods = ALL_METHODS;
00328 } else {
00329 ci.methods = VAL_BITMAP(vals+11);
00330 }
00331
00332
00333 if (!VAL_NULL(vals+12)) {
00334 ci.last_modified = VAL_TIME(vals+12);
00335 }
00336
00337
00338 if (!VAL_NULL(vals+13)) {
00339 ci.ruid.s = (char*)VAL_STRING(vals+13);
00340 ci.ruid.len = strlen(ci.ruid.s);
00341 }
00342
00343
00344 if (!VAL_NULL(vals+14)) {
00345 ci.instance.s = (char*)VAL_STRING(vals+14);
00346 ci.instance.len = strlen(ci.instance.s);
00347 }
00348
00349
00350 if (!VAL_NULL(vals+15)) {
00351 ci.reg_id = VAL_UINT(vals+15);
00352 }
00353
00354 return &ci;
00355 }
00356
00357
00367 int preload_udomain(db1_con_t* _c, udomain_t* _d)
00368 {
00369 char uri[MAX_URI_SIZE];
00370 ucontact_info_t *ci;
00371 db_row_t *row;
00372 db_key_t columns[18];
00373 db1_res_t* res = NULL;
00374 str user, contact;
00375 char* domain;
00376 int i;
00377 int n;
00378
00379 urecord_t* r;
00380 ucontact_t* c;
00381
00382 columns[0] = &user_col;
00383 columns[1] = &contact_col;
00384 columns[2] = &expires_col;
00385 columns[3] = &q_col;
00386 columns[4] = &callid_col;
00387 columns[5] = &cseq_col;
00388 columns[6] = &flags_col;
00389 columns[7] = &cflags_col;
00390 columns[8] = &user_agent_col;
00391 columns[9] = &received_col;
00392 columns[10] = &path_col;
00393 columns[11] = &sock_col;
00394 columns[12] = &methods_col;
00395 columns[13] = &last_mod_col;
00396 columns[14] = &ruid_col;
00397 columns[15] = &instance_col;
00398 columns[16] = ®_id_col;
00399 columns[17] = &domain_col;
00400
00401 if (ul_dbf.use_table(_c, _d->name) < 0) {
00402 LM_ERR("sql use_table failed\n");
00403 return -1;
00404 }
00405
00406 #ifdef EXTRA_DEBUG
00407 LM_NOTICE("load start time [%d]\n", (int)time(NULL));
00408 #endif
00409
00410 if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
00411 if (ul_dbf.query(_c, 0, 0, 0, columns, 0, (use_domain)?(18):(17), 0,
00412 0) < 0) {
00413 LM_ERR("db_query (1) failed\n");
00414 return -1;
00415 }
00416 if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) {
00417 LM_ERR("fetching rows failed\n");
00418 return -1;
00419 }
00420 } else {
00421 if (ul_dbf.query(_c, 0, 0, 0, columns, 0, (use_domain)?(18):(17), 0,
00422 &res) < 0) {
00423 LM_ERR("db_query failed\n");
00424 return -1;
00425 }
00426 }
00427
00428 if (RES_ROW_N(res) == 0) {
00429 LM_DBG("table is empty\n");
00430 ul_dbf.free_result(_c, res);
00431 return 0;
00432 }
00433
00434
00435 n = 0;
00436 do {
00437 LM_DBG("loading records - cycle [%d]\n", ++n);
00438 for(i = 0; i < RES_ROW_N(res); i++) {
00439 row = RES_ROWS(res) + i;
00440
00441 user.s = (char*)VAL_STRING(ROW_VALUES(row));
00442 if (VAL_NULL(ROW_VALUES(row)) || user.s==0 || user.s[0]==0) {
00443 LM_CRIT("empty username record in table %s...skipping\n",
00444 _d->name->s);
00445 continue;
00446 }
00447 user.len = strlen(user.s);
00448
00449 ci = dbrow2info( ROW_VALUES(row)+1, &contact);
00450 if (ci==0) {
00451 LM_ERR("sipping record for %.*s in table %s\n",
00452 user.len, user.s, _d->name->s);
00453 continue;
00454 }
00455
00456 if (use_domain) {
00457 domain = (char*)VAL_STRING(ROW_VALUES(row) + 17);
00458 if (VAL_NULL(ROW_VALUES(row)+17) || domain==0 || domain[0]==0){
00459 LM_CRIT("empty domain record for user %.*s...skipping\n",
00460 user.len, user.s);
00461 continue;
00462 }
00463
00464 user.len = snprintf(uri, MAX_URI_SIZE, "%.*s@%s",
00465 user.len, user.s, domain);
00466 user.s = uri;
00467 if (user.s[user.len]!=0) {
00468 LM_CRIT("URI '%.*s@%s' longer than %d\n", user.len, user.s,
00469 domain, MAX_URI_SIZE);
00470 continue;
00471 }
00472 }
00473
00474
00475 lock_udomain(_d, &user);
00476 if (get_urecord(_d, &user, &r) > 0) {
00477 if (mem_insert_urecord(_d, &user, &r) < 0) {
00478 LM_ERR("failed to create a record\n");
00479 unlock_udomain(_d, &user);
00480 goto error;
00481 }
00482 }
00483
00484 if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) {
00485 LM_ERR("inserting contact failed\n");
00486 unlock_udomain(_d, &user);
00487 goto error1;
00488 }
00489
00490
00491
00492 c->state = CS_SYNC;
00493 unlock_udomain(_d, &user);
00494 }
00495
00496 if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
00497 if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) {
00498 LM_ERR("fetching rows (1) failed\n");
00499 ul_dbf.free_result(_c, res);
00500 return -1;
00501 }
00502 } else {
00503 break;
00504 }
00505 } while(RES_ROW_N(res)>0);
00506
00507 ul_dbf.free_result(_c, res);
00508
00509 #ifdef EXTRA_DEBUG
00510 LM_NOTICE("load end time [%d]\n", (int)time(NULL));
00511 #endif
00512
00513 return 0;
00514 error1:
00515 free_ucontact(c);
00516 error:
00517 ul_dbf.free_result(_c, res);
00518 return -1;
00519 }
00520
00521
00529 urecord_t* db_load_urecord(db1_con_t* _c, udomain_t* _d, str *_aor)
00530 {
00531 ucontact_info_t *ci;
00532 db_key_t columns[16];
00533 db_key_t keys[2];
00534 db_key_t order;
00535 db_val_t vals[2];
00536 db1_res_t* res = NULL;
00537 str contact;
00538 char *domain;
00539 int i;
00540
00541 urecord_t* r;
00542 ucontact_t* c;
00543
00544 keys[0] = &user_col;
00545 vals[0].type = DB1_STR;
00546 vals[0].nul = 0;
00547 if (use_domain) {
00548 keys[1] = &domain_col;
00549 vals[1].type = DB1_STR;
00550 vals[1].nul = 0;
00551 domain = memchr(_aor->s, '@', _aor->len);
00552 vals[0].val.str_val.s = _aor->s;
00553 if (domain==0) {
00554 vals[0].val.str_val.len = 0;
00555 vals[1].val.str_val = *_aor;
00556 } else {
00557 vals[0].val.str_val.len = domain - _aor->s;
00558 vals[1].val.str_val.s = domain+1;
00559 vals[1].val.str_val.len = _aor->s + _aor->len - domain - 1;
00560 }
00561 } else {
00562 vals[0].val.str_val = *_aor;
00563 }
00564
00565 columns[0] = &contact_col;
00566 columns[1] = &expires_col;
00567 columns[2] = &q_col;
00568 columns[3] = &callid_col;
00569 columns[4] = &cseq_col;
00570 columns[5] = &flags_col;
00571 columns[6] = &cflags_col;
00572 columns[7] = &user_agent_col;
00573 columns[8] = &received_col;
00574 columns[9] = &path_col;
00575 columns[10] = &sock_col;
00576 columns[11] = &methods_col;
00577 columns[12] = &last_mod_col;
00578 columns[13] = &ruid_col;
00579 columns[14] = &instance_col;
00580 columns[15] = ®_id_col;
00581
00582 if (desc_time_order)
00583 order = &last_mod_col;
00584 else
00585 order = &q_col;
00586
00587 if (ul_dbf.use_table(_c, _d->name) < 0) {
00588 LM_ERR("failed to use table %.*s\n", _d->name->len, _d->name->s);
00589 return 0;
00590 }
00591
00592 if (ul_dbf.query(_c, keys, 0, vals, columns, (use_domain)?2:1, 16, order,
00593 &res) < 0) {
00594 LM_ERR("db_query failed\n");
00595 return 0;
00596 }
00597
00598 if (RES_ROW_N(res) == 0) {
00599 LM_DBG("aor %.*s not found in table %.*s\n",_aor->len, _aor->s, _d->name->len, _d->name->s);
00600 ul_dbf.free_result(_c, res);
00601 return 0;
00602 }
00603
00604 r = 0;
00605
00606 for(i = 0; i < RES_ROW_N(res); i++) {
00607 ci = dbrow2info( ROW_VALUES(RES_ROWS(res) + i), &contact);
00608 if (ci==0) {
00609 LM_ERR("skipping record for %.*s in table %s\n",
00610 _aor->len, _aor->s, _d->name->s);
00611 continue;
00612 }
00613
00614 if ( r==0 )
00615 get_static_urecord( _d, _aor, &r);
00616
00617 if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) {
00618 LM_ERR("mem_insert failed\n");
00619 free_urecord(r);
00620 ul_dbf.free_result(_c, res);
00621 return 0;
00622 }
00623
00624
00625
00626 c->state = CS_SYNC;
00627 }
00628
00629 ul_dbf.free_result(_c, res);
00630 return r;
00631 }
00632
00640 urecord_t* db_load_urecord_by_ruid(db1_con_t* _c, udomain_t* _d, str *_ruid)
00641 {
00642 ucontact_info_t *ci;
00643 db_key_t columns[18];
00644 db_key_t keys[1];
00645 db_key_t order;
00646 db_val_t vals[1];
00647 db1_res_t* res = NULL;
00648 db_row_t *row;
00649 str contact;
00650 str aor;
00651 char aorbuf[512];
00652 str domain;
00653
00654 urecord_t* r;
00655 ucontact_t* c;
00656
00657 keys[0] = &ruid_col;
00658 vals[0].type = DB1_STR;
00659 vals[0].nul = 0;
00660 vals[0].val.str_val = *_ruid;
00661
00662 columns[0] = &contact_col;
00663 columns[1] = &expires_col;
00664 columns[2] = &q_col;
00665 columns[3] = &callid_col;
00666 columns[4] = &cseq_col;
00667 columns[5] = &flags_col;
00668 columns[6] = &cflags_col;
00669 columns[7] = &user_agent_col;
00670 columns[8] = &received_col;
00671 columns[9] = &path_col;
00672 columns[10] = &sock_col;
00673 columns[11] = &methods_col;
00674 columns[12] = &last_mod_col;
00675 columns[13] = &ruid_col;
00676 columns[14] = &instance_col;
00677 columns[15] = ®_id_col;
00678 columns[16] = &user_col;
00679 columns[17] = &domain_col;
00680
00681 if (desc_time_order)
00682 order = &last_mod_col;
00683 else
00684 order = &q_col;
00685
00686 if (ul_dbf.use_table(_c, _d->name) < 0) {
00687 LM_ERR("failed to use table %.*s\n", _d->name->len, _d->name->s);
00688 return 0;
00689 }
00690
00691 if (ul_dbf.query(_c, keys, 0, vals, columns, 1, 18, order,
00692 &res) < 0) {
00693 LM_ERR("db_query failed\n");
00694 return 0;
00695 }
00696
00697 if (RES_ROW_N(res) == 0) {
00698 LM_DBG("aor %.*s not found in table %.*s\n",_ruid->len, _ruid->s,
00699 _d->name->len, _d->name->s);
00700 ul_dbf.free_result(_c, res);
00701 return 0;
00702 }
00703
00704 r = 0;
00705
00706
00707 row = RES_ROWS(res);
00708
00709 ci = dbrow2info(ROW_VALUES(RES_ROWS(res)), &contact);
00710 if (ci==0) {
00711 LM_ERR("skipping record for %.*s in table %s\n",
00712 _ruid->len, _ruid->s, _d->name->s);
00713 goto done;
00714 }
00715
00716 aor.s = (char*)VAL_STRING(ROW_VALUES(row) + 16);
00717 aor.len = strlen(aor.s);
00718
00719 if (use_domain) {
00720 domain.s = (char*)VAL_STRING(ROW_VALUES(row) + 17);
00721 if (VAL_NULL(ROW_VALUES(row)+17) || domain.s==0 || domain.s[0]==0){
00722 LM_CRIT("empty domain record for user %.*s...skipping\n",
00723 aor.len, aor.s);
00724 goto done;
00725 }
00726 domain.len = strlen(domain.s);
00727 if(aor.len + domain.len + 2 >= 512) {
00728 LM_ERR("AoR is too big\n");
00729 goto done;
00730 }
00731 memcpy(aorbuf, aor.s, aor.len);
00732 aorbuf[aor.len] = '@';
00733 memcpy(aorbuf + aor.len + 1, domain.s, domain.len);
00734 aor.len += 1 + domain.len;
00735 aor.s = aorbuf;
00736 aor.s[aor.len] = '\0';
00737 }
00738 get_static_urecord( _d, &aor, &r);
00739
00740 if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) {
00741 LM_ERR("mem_insert failed\n");
00742 free_urecord(r);
00743 ul_dbf.free_result(_c, res);
00744 return 0;
00745 }
00746
00747
00748
00749 c->state = CS_SYNC;
00750
00751 done:
00752 ul_dbf.free_result(_c, res);
00753 return r;
00754 }
00755
00756
00762 int db_timer_udomain(udomain_t* _d)
00763 {
00764 db_key_t keys[2];
00765 db_op_t ops[2];
00766 db_val_t vals[2];
00767
00768 keys[0] = &expires_col;
00769 ops[0] = "<";
00770 vals[0].type = DB1_DATETIME;
00771 vals[0].nul = 0;
00772 vals[0].val.time_val = act_time + 1;
00773
00774 keys[1] = &expires_col;
00775 ops[1] = "!=";
00776 vals[1].type = DB1_DATETIME;
00777 vals[1].nul = 0;
00778 vals[1].val.time_val = 0;
00779
00780 if (ul_dbf.use_table(ul_dbh, _d->name) < 0) {
00781 LM_ERR("use_table failed\n");
00782 return -1;
00783 }
00784
00785 if (ul_dbf.delete(ul_dbh, keys, ops, vals, 2) < 0) {
00786 LM_ERR("failed to delete from table %s\n",_d->name->s);
00787 return -1;
00788 }
00789
00790 return 0;
00791 }
00792
00793
00799 int testdb_udomain(db1_con_t* con, udomain_t* d)
00800 {
00801 db_key_t key[1], col[1];
00802 db_val_t val[1];
00803 db1_res_t* res = NULL;
00804
00805 if (ul_dbf.use_table(con, d->name) < 0) {
00806 LM_ERR("failed to change table\n");
00807 return -1;
00808 }
00809
00810 key[0] = &user_col;
00811
00812 col[0] = &user_col;
00813 VAL_TYPE(val) = DB1_STRING;
00814 VAL_NULL(val) = 0;
00815 VAL_STRING(val) = "dummy_user";
00816
00817 if (ul_dbf.query( con, key, 0, val, col, 1, 1, 0, &res) < 0) {
00818 LM_ERR("failure in db_query\n");
00819 return -1;
00820 }
00821
00822 ul_dbf.free_result( con, res);
00823 return 0;
00824 }
00825
00826
00834 int mem_insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r)
00835 {
00836 int sl;
00837
00838 if (new_urecord(_d->name, _aor, _r) < 0) {
00839 LM_ERR("creating urecord failed\n");
00840 return -1;
00841 }
00842
00843 sl = ((*_r)->aorhash)&(_d->size-1);
00844 slot_add(&_d->table[sl], *_r);
00845 update_stat( _d->users, 1);
00846 return 0;
00847 }
00848
00849
00855 void mem_delete_urecord(udomain_t* _d, struct urecord* _r)
00856 {
00857 slot_rem(_r->slot, _r);
00858 free_urecord(_r);
00859 update_stat( _d->users, -1);
00860 }
00861
00862
00867 void mem_timer_udomain(udomain_t* _d, int istart, int istep)
00868 {
00869 struct urecord* ptr, *t;
00870 int i;
00871
00872 for(i=istart; i<_d->size; i+=istep)
00873 {
00874 lock_ulslot(_d, i);
00875
00876 ptr = _d->table[i].first;
00877
00878 while(ptr) {
00879 timer_urecord(ptr);
00880
00881 if (ptr->contacts == 0) {
00882 t = ptr;
00883 ptr = ptr->next;
00884 mem_delete_urecord(_d, t);
00885 } else {
00886 ptr = ptr->next;
00887 }
00888 }
00889 unlock_ulslot(_d, i);
00890 }
00891 }
00892
00893
00899 void lock_udomain(udomain_t* _d, str* _aor)
00900 {
00901 unsigned int sl;
00902 if (db_mode!=DB_ONLY)
00903 {
00904 sl = ul_get_aorhash(_aor) & (_d->size - 1);
00905
00906 #ifdef GEN_LOCK_T_PREFERED
00907 lock_get(_d->table[sl].lock);
00908 #else
00909 ul_lock_idx(_d->table[sl].lockidx);
00910 #endif
00911 }
00912 }
00913
00914
00920 void unlock_udomain(udomain_t* _d, str* _aor)
00921 {
00922 unsigned int sl;
00923 if (db_mode!=DB_ONLY)
00924 {
00925 sl = ul_get_aorhash(_aor) & (_d->size - 1);
00926 #ifdef GEN_LOCK_T_PREFERED
00927 lock_release(_d->table[sl].lock);
00928 #else
00929 ul_release_idx(_d->table[sl].lockidx);
00930 #endif
00931 }
00932 }
00933
00939 void lock_ulslot(udomain_t* _d, int i)
00940 {
00941 if (db_mode!=DB_ONLY)
00942 #ifdef GEN_LOCK_T_PREFERED
00943 lock_get(_d->table[i].lock);
00944 #else
00945 ul_lock_idx(_d->table[i].lockidx);
00946 #endif
00947 }
00948
00949
00955 void unlock_ulslot(udomain_t* _d, int i)
00956 {
00957 if (db_mode!=DB_ONLY)
00958 #ifdef GEN_LOCK_T_PREFERED
00959 lock_release(_d->table[i].lock);
00960 #else
00961 ul_release_idx(_d->table[i].lockidx);
00962 #endif
00963 }
00964
00965
00966
00974 int insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r)
00975 {
00976 if (db_mode!=DB_ONLY) {
00977 if (mem_insert_urecord(_d, _aor, _r) < 0) {
00978 LM_ERR("inserting record failed\n");
00979 return -1;
00980 }
00981 } else {
00982 get_static_urecord( _d, _aor, _r);
00983 }
00984 return 0;
00985 }
00986
00987
00995 int get_urecord(udomain_t* _d, str* _aor, struct urecord** _r)
00996 {
00997 unsigned int sl, i, aorhash;
00998 urecord_t* r;
00999
01000 if (db_mode!=DB_ONLY) {
01001
01002 aorhash = ul_get_aorhash(_aor);
01003 sl = aorhash&(_d->size-1);
01004 r = _d->table[sl].first;
01005
01006 for(i = 0; i < _d->table[sl].n; i++) {
01007 if((r->aorhash==aorhash) && (r->aor.len==_aor->len)
01008 && !memcmp(r->aor.s,_aor->s,_aor->len)){
01009 *_r = r;
01010 return 0;
01011 }
01012
01013 r = r->next;
01014 }
01015 } else {
01016
01017 r = db_load_urecord( ul_dbh, _d, _aor);
01018 if (r) {
01019 *_r = r;
01020 return 0;
01021 }
01022 }
01023
01024 return 1;
01025 }
01026
01036 int get_urecord_by_ruid(udomain_t* _d, unsigned int _aorhash,
01037 str *_ruid, struct urecord** _r, struct ucontact** _c)
01038 {
01039 unsigned int sl, i;
01040 urecord_t* r;
01041 ucontact_t* c;
01042
01043 sl = _aorhash&(_d->size-1);
01044 lock_ulslot(_d, sl);
01045
01046 if (db_mode!=DB_ONLY) {
01047
01048 r = _d->table[sl].first;
01049
01050 for(i = 0; i < _d->table[sl].n; i++) {
01051 if(r->aorhash==_aorhash) {
01052 c = r->contacts;
01053 while(c) {
01054 if(c->ruid.len==_ruid->len
01055 && !memcmp(c->ruid.s, _ruid->s, _ruid->len)) {
01056 *_r = r;
01057 *_c = c;
01058 return 0;
01059 }
01060 }
01061 }
01062 r = r->next;
01063 }
01064 } else {
01065
01066 r = db_load_urecord_by_ruid(ul_dbh, _d, _ruid);
01067 if (r) {
01068 if(r->aorhash==_aorhash) {
01069 c = r->contacts;
01070 while(c) {
01071 if(c->ruid.len==_ruid->len
01072 && !memcmp(c->ruid.s, _ruid->s, _ruid->len)) {
01073 *_r = r;
01074 *_c = c;
01075 return 0;
01076 }
01077 }
01078 }
01079 }
01080 }
01081
01082 unlock_ulslot(_d, (_aorhash & (_d->size - 1)));
01083 return -1;
01084 }
01085
01093 int delete_urecord(udomain_t* _d, str* _aor, struct urecord* _r)
01094 {
01095 struct ucontact* c, *t;
01096
01097 if (db_mode==DB_ONLY) {
01098 if (_r==0)
01099 get_static_urecord( _d, _aor, &_r);
01100 if (db_delete_urecord(_r)<0) {
01101 LM_ERR("DB delete failed\n");
01102 return -1;
01103 }
01104 free_urecord(_r);
01105 return 0;
01106 }
01107
01108 if (_r==0) {
01109 if (get_urecord(_d, _aor, &_r) > 0) {
01110 return 0;
01111 }
01112 }
01113
01114 c = _r->contacts;
01115 while(c) {
01116 t = c;
01117 c = c->next;
01118 if (delete_ucontact(_r, t) < 0) {
01119 LM_ERR("deleting contact failed\n");
01120 return -1;
01121 }
01122 }
01123 release_urecord(_r);
01124 return 0;
01125 }