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
00031
00032
00033
00034
00035
00036
00037
00038 #include "dlist.h"
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <stdio.h>
00042 #include "../../ut.h"
00043 #include "../../db/db_ut.h"
00044 #include "../../mem/shm_mem.h"
00045 #include "../../dprint.h"
00046 #include "../../ip_addr.h"
00047 #include "../../socket_info.h"
00048 #include "udomain.h"
00049 #include "utime.h"
00050 #include "ul_mod.h"
00051
00052
00053
00054 dlist_t* root = 0;
00055
00056
00057
00058
00059
00060
00061
00062
00063 static inline int find_dlist(str* _n, dlist_t** _d)
00064 {
00065 dlist_t* ptr;
00066
00067 ptr = root;
00068 while(ptr) {
00069 if ((_n->len == ptr->name.len) &&
00070 !memcmp(_n->s, ptr->name.s, _n->len)) {
00071 *_d = ptr;
00072 return 0;
00073 }
00074
00075 ptr = ptr->next;
00076 }
00077
00078 return 1;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 static inline int get_all_db_ucontacts(void *buf, int len, unsigned int flags,
00093 unsigned int part_idx, unsigned int part_max)
00094 {
00095 static char query_buf[512];
00096 static str query_str;
00097
00098 struct socket_info *sock;
00099 unsigned int dbflags;
00100 db_res_t* res = NULL;
00101 db_row_t *row;
00102 dlist_t *dom;
00103 char *p, *p1;
00104 char now_s[25];
00105 int now_len;
00106 int port, proto, p_len, p1_len;
00107 str host;
00108 int i;
00109 void *cp;
00110 int shortage, needed;
00111
00112 cp = buf;
00113 shortage = 0;
00114
00115 len -= sizeof(p_len);
00116
00117
00118 now_len = 25;
00119 if (db_time2str( time(0), now_s, &now_len)!=0) {
00120 LM_ERR("failed to print now time\n");
00121 return -1;
00122 }
00123
00124 for (dom = root; dom!=NULL ; dom=dom->next) {
00125
00126 i = snprintf( query_buf, sizeof(query_buf), "select %.*s, %.*s, %.*s,"
00127 #ifdef ORACLE_USRLOC
00128 " %.*s, %.*s from %s where %.*s > %.*s and "
00129 "bitand(%.*s, %d) = %d and mod(id, %u) = %u",
00130 #else
00131 " %.*s, %.*s from %s where %.*s > %.*s and %.*s & %d = %d and "
00132 "id %% %u = %u",
00133 #endif
00134 received_col.len, received_col.s,
00135 contact_col.len, contact_col.s,
00136 sock_col.len, sock_col.s,
00137 cflags_col.len, cflags_col.s,
00138 path_col.len, path_col.s,
00139 dom->d->name->s,
00140 expires_col.len, expires_col.s,
00141 now_len, now_s,
00142 cflags_col.len, cflags_col.s,
00143 flags, flags, part_max, part_idx);
00144 if ( i>=sizeof(query_buf) ) {
00145 LM_ERR("DB query too long\n");
00146 return -1;
00147 }
00148 query_str.s = query_buf;
00149 query_str.len = i;
00150 if ( ul_dbf.raw_query( ul_dbh, &query_str, &res)<0 ) {
00151 LM_ERR("raw_query failed\n");
00152 return -1;
00153 }
00154 if( RES_ROW_N(res)==0 ) {
00155 ul_dbf.free_result(ul_dbh, res);
00156 continue;
00157 }
00158
00159 for(i = 0; i < RES_ROW_N(res); i++) {
00160 row = RES_ROWS(res) + i;
00161
00162
00163 p = (char*)VAL_STRING(ROW_VALUES(row));
00164 if ( VAL_NULL(ROW_VALUES(row)) || p==0 || p[0]==0 ) {
00165
00166 p = (char*)VAL_STRING(ROW_VALUES(row)+1);
00167 if (VAL_NULL(ROW_VALUES(row)+1) || p==0 || p[0]==0) {
00168 LM_ERR("empty contact -> skipping\n");
00169 continue;
00170 }
00171 }
00172 p_len = strlen(p);
00173
00174
00175 p1 = (char*)VAL_STRING(ROW_VALUES(row)+4);
00176 if (VAL_NULL(ROW_VALUES(row)+4) || p1==0 || p1[0]==0){
00177 p1 = NULL;
00178 p1_len = 0;
00179 } else {
00180 p1_len = strlen(p1);
00181 }
00182
00183 needed = (int)(sizeof(p_len)+p_len+sizeof(sock)+sizeof(dbflags)+
00184 sizeof(p1_len)+p1_len);
00185 if (len < needed) {
00186 shortage += needed ;
00187 continue;
00188 }
00189
00190
00191 memcpy(cp, &p_len, sizeof(p_len));
00192 cp = (char*)cp + sizeof(p_len);
00193 memcpy(cp, p, p_len);
00194 cp = (char*)cp + p_len;
00195
00196
00197 p = (char*)VAL_STRING(ROW_VALUES(row) + 2);
00198 if (VAL_NULL(ROW_VALUES(row)+2) || p==0 || p[0]==0){
00199 sock = 0;
00200 } else {
00201 if (parse_phostport( p, strlen(p), &host.s, &host.len,
00202 &port, &proto)!=0) {
00203 LM_ERR("bad socket <%s>...ignoring\n", p);
00204 sock = 0;
00205 } else {
00206 sock = grep_sock_info( &host, (unsigned short)port, proto);
00207 if (sock==0) {
00208 LM_WARN("non-local socket <%s>...ignoring\n", p);
00209 }
00210 }
00211 }
00212
00213
00214 dbflags = VAL_BITMAP(ROW_VALUES(row) + 3);
00215
00216
00217 memcpy(cp, &sock, sizeof(sock));
00218 cp = (char*)cp + sizeof(sock);
00219 memcpy(cp, &dbflags, sizeof(dbflags));
00220 cp = (char*)cp + sizeof(dbflags);
00221
00222
00223 memcpy(cp, &p1_len, sizeof(p1_len));
00224 cp = (char*)cp + sizeof(p1_len);
00225 memcpy(cp, p1, p1_len);
00226 cp = (char*)cp + p1_len;
00227
00228 len -= needed;
00229 }
00230
00231 ul_dbf.free_result(ul_dbh, res);
00232 }
00233
00234
00235 if (len >= 0)
00236 memset(cp, 0, sizeof(p_len));
00237
00238
00239 if (shortage > 0 && len > shortage) {
00240 abort();
00241 }
00242
00243 shortage -= len;
00244
00245 return shortage > 0 ? shortage : 0;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 static inline int get_all_mem_ucontacts(void *buf, int len, unsigned int flags,
00260 unsigned int part_idx, unsigned int part_max)
00261 {
00262 dlist_t *p;
00263 urecord_t *r;
00264 ucontact_t *c;
00265 void *cp;
00266 int shortage;
00267 int needed;
00268 int i = 0;
00269 cp = buf;
00270 shortage = 0;
00271
00272 len -= sizeof(c->c.len);
00273
00274 for (p = root; p != NULL; p = p->next) {
00275
00276 for(i=0; i<p->d->size; i++) {
00277
00278 if ( (i % part_max) != part_idx )
00279 continue;
00280
00281 lock_ulslot(p->d, i);
00282 if(p->d->table[i].n<=0)
00283 {
00284 unlock_ulslot(p->d, i);
00285 continue;
00286 }
00287 for (r = p->d->table[i].first; r != NULL; r = r->next) {
00288 for (c = r->contacts; c != NULL; c = c->next) {
00289 if (c->c.len <= 0)
00290 continue;
00291
00292
00293
00294
00295 if ((c->cflags & flags) != flags)
00296 continue;
00297 if (c->received.s) {
00298 needed = (int)(sizeof(c->received.len)
00299 + c->received.len + sizeof(c->sock)
00300 + sizeof(c->cflags) + sizeof(c->path.len)
00301 + c->path.len);
00302 if (len >= needed) {
00303 memcpy(cp,&c->received.len,sizeof(c->received.len));
00304 cp = (char*)cp + sizeof(c->received.len);
00305 memcpy(cp, c->received.s, c->received.len);
00306 cp = (char*)cp + c->received.len;
00307 memcpy(cp, &c->sock, sizeof(c->sock));
00308 cp = (char*)cp + sizeof(c->sock);
00309 memcpy(cp, &c->cflags, sizeof(c->cflags));
00310 cp = (char*)cp + sizeof(c->cflags);
00311 memcpy(cp, &c->path.len, sizeof(c->path.len));
00312 cp = (char*)cp + sizeof(c->path.len);
00313 memcpy(cp, c->path.s, c->path.len);
00314 cp = (char*)cp + c->path.len;
00315 len -= needed;
00316 } else {
00317 shortage += needed;
00318 }
00319 } else {
00320 needed = (int)(sizeof(c->c.len) + c->c.len +
00321 sizeof(c->sock) + sizeof(c->cflags) +
00322 sizeof(c->path.len) + c->path.len);
00323 if (len >= needed) {
00324 memcpy(cp, &c->c.len, sizeof(c->c.len));
00325 cp = (char*)cp + sizeof(c->c.len);
00326 memcpy(cp, c->c.s, c->c.len);
00327 cp = (char*)cp + c->c.len;
00328 memcpy(cp, &c->sock, sizeof(c->sock));
00329 cp = (char*)cp + sizeof(c->sock);
00330 memcpy(cp, &c->cflags, sizeof(c->cflags));
00331 cp = (char*)cp + sizeof(c->cflags);
00332 memcpy(cp, &c->path.len, sizeof(c->path.len));
00333 cp = (char*)cp + sizeof(c->path.len);
00334 memcpy(cp, c->path.s, c->path.len);
00335 cp = (char*)cp + c->path.len;
00336 len -= needed;
00337 } else {
00338 shortage += needed;
00339 }
00340 }
00341 }
00342 }
00343 unlock_ulslot(p->d, i);
00344 }
00345 }
00346
00347 if (len >= 0)
00348 memset(cp, 0, sizeof(c->c.len));
00349
00350
00351 if (shortage > 0 && len > shortage) {
00352 abort();
00353 }
00354
00355 shortage -= len;
00356
00357 return shortage > 0 ? shortage : 0;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 int get_all_ucontacts(void *buf, int len, unsigned int flags,
00395 unsigned int part_idx, unsigned int part_max)
00396 {
00397 if (db_mode==DB_ONLY)
00398 return get_all_db_ucontacts( buf, len, flags, part_idx, part_max);
00399 else
00400 return get_all_mem_ucontacts( buf, len, flags, part_idx, part_max);
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 static inline int new_dlist(str* _n, dlist_t** _d)
00414 {
00415 dlist_t* ptr;
00416
00417
00418
00419
00420 ptr = (dlist_t*)shm_malloc(sizeof(dlist_t));
00421 if (ptr == 0) {
00422 LM_ERR("no more share memory\n");
00423 return -1;
00424 }
00425 memset(ptr, 0, sizeof(dlist_t));
00426
00427
00428 ptr->name.s = (char*)shm_malloc(_n->len+1);
00429 if (ptr->name.s == 0) {
00430 LM_ERR("no more memory left\n");
00431 shm_free(ptr);
00432 return -2;
00433 }
00434
00435 memcpy(ptr->name.s, _n->s, _n->len);
00436 ptr->name.len = _n->len;
00437 ptr->name.s[ptr->name.len] = 0;
00438
00439 if (new_udomain(&(ptr->name), ul_hash_size, &(ptr->d)) < 0) {
00440 LM_ERR("creating domain structure failed\n");
00441 shm_free(ptr->name.s);
00442 shm_free(ptr);
00443 return -3;
00444 }
00445
00446 *_d = ptr;
00447 return 0;
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 int register_udomain(const char* _n, udomain_t** _d)
00462 {
00463 dlist_t* d;
00464 str s;
00465 db_con_t* con;
00466
00467 s.s = (char*)_n;
00468 s.len = strlen(_n);
00469
00470 if (find_dlist(&s, &d) == 0) {
00471 *_d = d->d;
00472 return 0;
00473 }
00474
00475 if (new_dlist(&s, &d) < 0) {
00476 LM_ERR("failed to create new domain\n");
00477 return -1;
00478 }
00479
00480
00481
00482
00483 if (db_mode != NO_DB) {
00484 con = ul_dbf.init(&db_url);
00485 if (!con) {
00486 LM_ERR("failed to open database connection\n");
00487 goto err;
00488 }
00489
00490 if(db_check_table_version(&ul_dbf, con, &s, UL_TABLE_VERSION) < 0) {
00491 LM_ERR("error during table version check.\n");
00492 goto err;
00493 }
00494
00495 if (testdb_udomain(con, d->d) < 0) {
00496 LM_ERR("testing domain '%.*s' failed\n", s.len, ZSW(s.s));
00497 goto err;
00498 }
00499
00500 ul_dbf.close(con);
00501 }
00502
00503 d->next = root;
00504 root = d;
00505
00506 *_d = d->d;
00507 return 0;
00508
00509 err:
00510 if (con) ul_dbf.close(con);
00511 free_udomain(d->d);
00512 shm_free(d->name.s);
00513 shm_free(d);
00514 return -1;
00515 }
00516
00517
00518
00519
00520
00521 void free_all_udomains(void)
00522 {
00523 dlist_t* ptr;
00524
00525 while(root) {
00526 ptr = root;
00527 root = root->next;
00528
00529 free_udomain(ptr->d);
00530 shm_free(ptr->name.s);
00531 shm_free(ptr);
00532 }
00533 }
00534
00535
00536
00537
00538
00539
00540 void print_all_udomains(FILE* _f)
00541 {
00542 dlist_t* ptr;
00543
00544 ptr = root;
00545
00546 fprintf(_f, "===Domain list===\n");
00547 while(ptr) {
00548 print_udomain(_f, ptr->d);
00549 ptr = ptr->next;
00550 }
00551 fprintf(_f, "===/Domain list===\n");
00552 }
00553
00554
00555
00556
00557
00558
00559 unsigned long get_number_of_users(void)
00560 {
00561 int numberOfUsers = 0;
00562
00563 dlist_t* current_dlist;
00564
00565 current_dlist = root;
00566
00567 while (current_dlist)
00568 {
00569 numberOfUsers += get_stat_val(current_dlist->d->users);
00570 current_dlist = current_dlist->next;
00571 }
00572
00573 return numberOfUsers;
00574 }
00575
00576
00577
00578
00579
00580
00581 int synchronize_all_udomains(void)
00582 {
00583 int res = 0;
00584 dlist_t* ptr;
00585
00586 get_act_time();
00587
00588 if (db_mode==DB_ONLY) {
00589 for( ptr=root ; ptr ; ptr=ptr->next)
00590 res |= db_timer_udomain(ptr->d);
00591 } else {
00592 for( ptr=root ; ptr ; ptr=ptr->next)
00593 mem_timer_udomain(ptr->d);
00594 }
00595
00596 return res;
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606 int find_domain(str* _d, udomain_t** _p)
00607 {
00608 dlist_t* d;
00609
00610 if (find_dlist(_d, &d) == 0) {
00611 *_p = d->d;
00612 return 0;
00613 }
00614
00615 return 1;
00616 }