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 #include <string.h>
00035 #include <unistd.h>
00036 #include <stdio.h>
00037
00038 #include "../../dprint.h"
00039 #include "../../mem/mem.h"
00040 #include "../../mem/shm_mem.h"
00041
00042 #include "xjab_worker.h"
00043 #include "mdefines.h"
00044
00045 #define XJ_DEF_JDELIM '*'
00046
00054 xj_wlist xj_wlist_init(int **pipes, int size, int max, int cache_time,
00055 int sleep_time, int delay_time)
00056 {
00057 int i;
00058 xj_wlist jwl = NULL;
00059
00060 if(pipes == NULL || size <= 0 || max <= 0)
00061 return NULL;
00062 #ifdef XJ_EXTRA_DEBUG
00063 LM_DBG("-----START-----\n");
00064 #endif
00065 jwl = (xj_wlist)_M_SHM_MALLOC(sizeof(t_xj_wlist));
00066 if(jwl == NULL)
00067 return NULL;
00068 jwl->len = size;
00069 jwl->maxj = max;
00070
00071 jwl->cachet = cache_time;
00072 jwl->delayt = delay_time;
00073 jwl->sleept = sleep_time;
00074
00075 jwl->aliases = NULL;
00076 jwl->sems = NULL;
00077 i = 0;
00078
00079 if((jwl->sems = lock_set_alloc(size)) == NULL){
00080 LM_CRIT("failed to alloc lock set\n");
00081 goto clean;
00082 };
00083
00084 if (lock_set_init(jwl->sems)==0){
00085 LM_CRIT("failed to initialize the locks\n");
00086 goto clean;
00087 };
00088 jwl->workers = (xj_worker)_M_SHM_MALLOC(size*sizeof(t_xj_worker));
00089 if(jwl->workers == NULL){
00090 lock_set_destroy(jwl->sems);
00091 goto clean;
00092 }
00093
00094 for(i = 0; i < size; i++)
00095 {
00096 jwl->workers[i].nr = 0;
00097 jwl->workers[i].pid = 0;
00098 jwl->workers[i].wpipe = pipes[i][1];
00099 jwl->workers[i].rpipe = pipes[i][0];
00100 if((jwl->workers[i].sip_ids = newtree234(xj_jkey_cmp)) == NULL){
00101 lock_set_destroy(jwl->sems);
00102 goto clean;
00103 }
00104 }
00105
00106 return jwl;
00107
00108 clean:
00109 LM_DBG("error occurred -> cleaning\n");
00110 if(jwl->sems != NULL)
00111 lock_set_dealloc(jwl->sems);
00112 if(jwl->workers != NULL)
00113 {
00114 while(i>=0)
00115 {
00116 if(jwl->workers[i].sip_ids == NULL)
00117 free2tree234(jwl->workers[i].sip_ids, xj_jkey_free_p);
00118 i--;
00119 }
00120 _M_SHM_FREE(jwl->workers);
00121 }
00122 _M_SHM_FREE(jwl);
00123 return NULL;
00124
00125 }
00126
00134 int xj_wlist_set_pid(xj_wlist jwl, int pid, int idx)
00135 {
00136 if(jwl == NULL || pid <= 0 || idx < 0 || idx >= jwl->len)
00137 return -1;
00138 lock_set_get(jwl->sems, idx);
00139 jwl->workers[idx].pid = pid;
00140 lock_set_release(jwl->sems, idx);
00141 return 0;
00142 }
00143
00148 void xj_wlist_free(xj_wlist jwl)
00149 {
00150 int i;
00151 #ifdef XJ_EXTRA_DEBUG
00152 LM_DBG("freeing 'xj_wlist' memory ...\n");
00153 #endif
00154 if(jwl == NULL)
00155 return;
00156
00157 if(jwl->workers != NULL)
00158 {
00159 for(i=0; i<jwl->len; i++)
00160 free2tree234(jwl->workers[i].sip_ids, xj_jkey_free_p);
00161 _M_SHM_FREE(jwl->workers);
00162 }
00163
00164 if(jwl->aliases != NULL)
00165 {
00166 if(jwl->aliases->d)
00167 _M_SHM_FREE(jwl->aliases->d);
00168
00169 if(jwl->aliases->jdm != NULL)
00170 {
00171 _M_SHM_FREE(jwl->aliases->jdm->s);
00172 _M_SHM_FREE(jwl->aliases->jdm);
00173 }
00174 if(jwl->aliases->proxy != NULL)
00175 {
00176 _M_SHM_FREE(jwl->aliases->proxy->s);
00177 _M_SHM_FREE(jwl->aliases->proxy);
00178 }
00179 if(jwl->aliases->size > 0)
00180 {
00181 for(i=0; i<jwl->aliases->size; i++)
00182 _M_SHM_FREE(jwl->aliases->a[i].s);
00183 _M_SHM_FREE(jwl->aliases->a);
00184 }
00185 _M_SHM_FREE(jwl->aliases);
00186 jwl->aliases = NULL;
00187 }
00188
00189 if(jwl->sems != NULL){
00190 lock_set_destroy(jwl->sems);
00191 lock_set_dealloc(jwl->sems);
00192 }
00193
00194 _M_SHM_FREE(jwl);
00195 }
00196
00205 int xj_wlist_check(xj_wlist jwl, xj_jkey jkey, xj_jkey *p)
00206 {
00207 int i;
00208 if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
00209 return -1;
00210
00211 i = 0;
00212 *p = NULL;
00213 while(i < jwl->len)
00214 {
00215 lock_set_get(jwl->sems, i);
00216 if(jwl->workers[i].pid <= 0)
00217 {
00218 lock_set_release(jwl->sems, i);
00219 i++;
00220 continue;
00221 }
00222 if((*p = find234(jwl->workers[i].sip_ids, (void*)jkey, NULL)) != NULL)
00223 {
00224 lock_set_release(jwl->sems, i);
00225 #ifdef XJ_EXTRA_DEBUG
00226 LM_DBG("entry exists for <%.*s> in the"
00227 " pool of <%d> [%d]\n",jkey->id->len, jkey->id->s,
00228 jwl->workers[i].pid,i);
00229 #endif
00230 return jwl->workers[i].wpipe;
00231 }
00232 lock_set_release(jwl->sems, i);
00233 i++;
00234 }
00235 #ifdef XJ_EXTRA_DEBUG
00236 LM_DBG("entry does not exist for <%.*s>\n",
00237 jkey->id->len, jkey->id->s);
00238 #endif
00239 return -1;
00240 }
00241
00250 int xj_wlist_get(xj_wlist jwl, xj_jkey jkey, xj_jkey *p)
00251 {
00252 int i = 0, pos = -1, min = 100000;
00253 xj_jkey msid = NULL;
00254
00255 if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
00256 return -1;
00257
00258 *p = NULL;
00259 while(i < jwl->len)
00260 {
00261 lock_set_get(jwl->sems, i);
00262 if(jwl->workers[i].pid <= 0)
00263 {
00264 lock_set_release(jwl->sems, i);
00265 i++;
00266 continue;
00267 }
00268 if((*p = find234(jwl->workers[i].sip_ids, (void*)jkey, NULL))!=NULL)
00269 {
00270 if(pos >= 0)
00271 lock_set_release(jwl->sems, pos);
00272 lock_set_release(jwl->sems, i);
00273 #ifdef XJ_EXTRA_DEBUG
00274 LM_DBG("entry already exists for <%.*s> in the"
00275 " pool of <%d> [%d]\n",jkey->id->len, jkey->id->s,
00276 jwl->workers[i].pid,i);
00277 #endif
00278 return jwl->workers[i].wpipe;
00279 }
00280 if(min > jwl->workers[i].nr)
00281 {
00282 if(pos >= 0)
00283 lock_set_release(jwl->sems, pos);
00284 pos = i;
00285 min = jwl->workers[i].nr;
00286 }
00287 else
00288 lock_set_release(jwl->sems, i);
00289 i++;
00290 }
00291 if(pos >= 0 && jwl->workers[pos].nr < jwl->maxj)
00292 {
00293 jwl->workers[pos].nr++;
00294
00295 msid = (xj_jkey)_M_SHM_MALLOC(sizeof(t_xj_jkey));
00296 if(msid == NULL)
00297 goto error;
00298 msid->id = (str*)_M_SHM_MALLOC(sizeof(str));
00299 if(msid->id == NULL)
00300 {
00301 _M_SHM_FREE(msid);
00302 goto error;
00303 }
00304
00305 msid->id->s = (char*)_M_SHM_MALLOC(jkey->id->len);
00306 if(msid->id == NULL)
00307 {
00308 _M_SHM_FREE(msid->id);
00309 _M_SHM_FREE(msid);
00310 goto error;
00311 }
00312
00313 if((*p = add234(jwl->workers[pos].sip_ids, msid)) != NULL)
00314 {
00315 msid->id->len = jkey->id->len;
00316 memcpy(msid->id->s, jkey->id->s, jkey->id->len);
00317 msid->hash = jkey->hash;
00318 msid->flag = XJ_FLAG_OPEN;
00319 lock_set_release(jwl->sems, pos);
00320 #ifdef XJ_EXTRA_DEBUG
00321 LM_DBG("new entry for <%.*s> in the pool of"
00322 " <%d> - [%d]\n", jkey->id->len, jkey->id->s,
00323 jwl->workers[pos].pid, pos);
00324 #endif
00325 return jwl->workers[pos].wpipe;
00326 }
00327 _M_SHM_FREE(msid->id->s);
00328 _M_SHM_FREE(msid->id);
00329 _M_SHM_FREE(msid);
00330 }
00331
00332 error:
00333 if(pos >= 0)
00334 lock_set_release(jwl->sems, pos);
00335 LM_DBG("cannot create a new entry for <%.*s>\n",
00336 jkey->id->len, jkey->id->s);
00337 return -1;
00338 }
00339
00344 int xj_wlist_set_flag(xj_wlist jwl, xj_jkey jkey, int fl)
00345 {
00346 int i;
00347 xj_jkey p = NULL;
00348 if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
00349 return -1;
00350
00351 #ifdef XJ_EXTRA_DEBUG
00352 LM_DBG("looking for <%.*s>"
00353 " having id=%d\n", jkey->id->len, jkey->id->s, jkey->hash);
00354 #endif
00355
00356 i = 0;
00357 while(i < jwl->len)
00358 {
00359 lock_set_get(jwl->sems, i);
00360 if(jwl->workers[i].pid <= 0)
00361 {
00362 lock_set_release(jwl->sems, i);
00363 i++;
00364 continue;
00365 }
00366 if((p=find234(jwl->workers[i].sip_ids, (void*)jkey, NULL)) != NULL)
00367 {
00368 p->flag = fl;
00369 lock_set_release(jwl->sems, i);
00370 #ifdef XJ_EXTRA_DEBUG
00371 LM_DBG("the connection for <%.*s>"
00372 " marked with flag=%d", jkey->id->len, jkey->id->s, fl);
00373 #endif
00374 return jwl->workers[i].wpipe;
00375 }
00376 lock_set_release(jwl->sems, i);
00377 i++;
00378 }
00379 #ifdef XJ_EXTRA_DEBUG
00380 LM_DBG("entry does not exist for <%.*s>\n",
00381 jkey->id->len, jkey->id->s);
00382 #endif
00383 return -1;
00384 }
00385
00386
00392 int xj_wlist_set_aliases(xj_wlist jwl, char *als, char *jd, char *pa)
00393 {
00394 char *p, *p0, *p1;
00395 int i, n;
00396
00397 if(jwl == NULL)
00398 return -1;
00399 if(!jd)
00400 return 0;
00401
00402 if((jwl->aliases = (xj_jalias)_M_SHM_MALLOC(sizeof(t_xj_jalias)))==NULL)
00403 {
00404 LM_DBG("not enough SHMemory.\n");
00405 return -1;
00406 }
00407
00408 jwl->aliases->jdm = NULL;
00409 jwl->aliases->proxy = NULL;
00410 jwl->aliases->dlm = XJ_DEF_JDELIM;
00411 jwl->aliases->size = 0;
00412 jwl->aliases->a = NULL;
00413 jwl->aliases->d = NULL;
00414
00415
00416 if(jd != NULL && (n=strlen(jd))>2)
00417 {
00418 p = jd;
00419 while(p < jd+n && *p!='=')
00420 p++;
00421 if(p<jd+n-1)
00422 {
00423 jwl->aliases->dlm = *(p+1);
00424 n = p - jd;
00425 }
00426 if((jwl->aliases->jdm = (str*)_M_SHM_MALLOC(sizeof(str)))== NULL)
00427 {
00428 LM_DBG("not enough SHMemory!?\n");
00429 _M_SHM_FREE(jwl->aliases);
00430 jwl->aliases = NULL;
00431 return -1;
00432 }
00433 jwl->aliases->jdm->len = n;
00434 if((jwl->aliases->jdm->s=(char*)_M_SHM_MALLOC(jwl->aliases->jdm->len))
00435 == NULL)
00436 {
00437 LM_DBG("not enough SHMemory!?!\n");
00438 _M_SHM_FREE(jwl->aliases->jdm);
00439 _M_SHM_FREE(jwl->aliases);
00440 jwl->aliases = NULL;
00441 }
00442 strncpy(jwl->aliases->jdm->s, jd, jwl->aliases->jdm->len);
00443 #ifdef XJ_EXTRA_DEBUG
00444 LM_DBG("jdomain=%.*s delim=%c\n",
00445 jwl->aliases->jdm->len, jwl->aliases->jdm->s, jwl->aliases->dlm);
00446 #endif
00447 }
00448
00449
00450 if(pa && strlen(pa)>0)
00451 {
00452 if((jwl->aliases->proxy = (str*)_M_SHM_MALLOC(sizeof(str)))==NULL)
00453 {
00454 LM_DBG(" not enough SHMemory!!\n");
00455 goto clean3;
00456 }
00457 i = jwl->aliases->proxy->len = strlen(pa);
00458
00459 if(i < 4 || pa[0]!='s' || pa[1]!='i' || pa[2]!='p' || pa[3]!=':')
00460 jwl->aliases->proxy->len += 4;
00461 if((jwl->aliases->proxy->s=
00462 (char*)_M_SHM_MALLOC(jwl->aliases->proxy->len))
00463 == NULL)
00464 {
00465 LM_DBG("not enough SHMemory!!!\n");
00466 _M_SHM_FREE(jwl->aliases->proxy);
00467 goto clean3;
00468 }
00469 p0 = jwl->aliases->proxy->s;
00470 if(jwl->aliases->proxy->len != i)
00471 {
00472 strncpy(p0, "sip:", 4);
00473 p0 += 4;
00474 }
00475 strncpy(p0, pa, i);
00476 #ifdef XJ_EXTRA_DEBUG
00477 LM_DBG("outbound proxy=[%.*s]\n",
00478 jwl->aliases->proxy->len, jwl->aliases->proxy->s);
00479 #endif
00480 }
00481
00482
00483 if(!als || strlen(als)<2)
00484 return 0;
00485
00486 if((p = strchr(als, ';')) == NULL)
00487 {
00488 LM_DBG("bad parameter value\n");
00489 return -1;
00490 }
00491
00492 if((jwl->aliases->size = atoi(als)) <= 0)
00493 {
00494 LM_DBG("wrong number of aliases\n");
00495 return 0;
00496 }
00497
00498 jwl->aliases->d = (char*)_M_SHM_MALLOC(jwl->aliases->size*sizeof(char));
00499 if(jwl->aliases->d == NULL)
00500 {
00501 LM_DBG("not enough SHMemory..\n");
00502 goto clean2;
00503 }
00504 memset(jwl->aliases->d, 0, jwl->aliases->size);
00505
00506 jwl->aliases->a = (str*)_M_SHM_MALLOC(jwl->aliases->size*sizeof(str));
00507 if(jwl->aliases->a == NULL)
00508 {
00509 LM_DBG("not enough SHMemory..\n");
00510 goto clean1;
00511 }
00512
00513 p++;
00514 for(i=0; i<jwl->aliases->size; i++)
00515 {
00516 if((p0 = strchr(p, ';'))==NULL)
00517 {
00518 LM_DBG("bad parameter value format\n");
00519 goto clean;
00520 }
00521 n = p0 - p;
00522 p1 = strchr(p, '=');
00523 if(p1 && p1<p0-1)
00524 {
00525 jwl->aliases->d[i] = *(p1+1);
00526 n = p1 - p;
00527 }
00528 jwl->aliases->a[i].len = n;
00529 if((jwl->aliases->a[i].s = (char*)_M_SHM_MALLOC(jwl->aliases->a[i].len))
00530 == NULL)
00531 {
00532 LM_DBG("not enough SHMemory!\n");
00533 goto clean;
00534 }
00535
00536 strncpy(jwl->aliases->a[i].s, p, jwl->aliases->a[i].len);
00537 #ifdef XJ_EXTRA_DEBUG
00538 LM_DBG("alias[%d/%d]=%.*s delim=%c\n",
00539 i+1, jwl->aliases->size, jwl->aliases->a[i].len,
00540 jwl->aliases->a[i].s, jwl->aliases->d[i]?jwl->aliases->d[i]:'X');
00541 #endif
00542 p = p0 + 1;
00543 }
00544 return 0;
00545
00546 clean:
00547 while(i>0)
00548 {
00549 _M_SHM_FREE(jwl->aliases->a[i-1].s);
00550 i--;
00551 }
00552 _M_SHM_FREE(jwl->aliases->a);
00553
00554 clean1:
00555 if(jwl->aliases->d)
00556 _M_SHM_FREE(jwl->aliases->d);
00557
00558 clean2:
00559 if(jwl->aliases->proxy)
00560 {
00561 _M_SHM_FREE(jwl->aliases->proxy->s);
00562 _M_SHM_FREE(jwl->aliases->proxy);
00563 }
00564 clean3:
00565 if(jwl->aliases->jdm)
00566 {
00567 _M_SHM_FREE(jwl->aliases->jdm->s);
00568 _M_SHM_FREE(jwl->aliases->jdm);
00569 }
00570 _M_SHM_FREE(jwl->aliases);
00571 jwl->aliases = NULL;
00572 return -1;
00573 }
00574
00575
00582 int xj_wlist_check_aliases(xj_wlist jwl, str *addr)
00583 {
00584 char *p, *p0;
00585 int ll, i;
00586 if(!jwl || !jwl->aliases || !addr || !addr->s || addr->len<=0)
00587 return -1;
00588
00589
00590 p = addr->s;
00591 while(p < addr->s + addr->len && *p != '@')
00592 p++;
00593 if(p >= addr->s + addr->len)
00594 return -1;
00595
00596 p++;
00597 ll = addr->s + addr->len - p;
00598
00599
00600 p0 = p;
00601 while(p0 < p + ll && *p0 != ';')
00602 p0++;
00603 if(p0 < p + ll)
00604 ll = p0 - p;
00605
00606 ll = addr->s + addr->len - p;
00607 if(jwl->aliases->jdm && jwl->aliases->jdm->len == ll &&
00608 !strncasecmp(jwl->aliases->jdm->s, p, ll))
00609 return 0;
00610
00611 if(jwl->aliases->size <= 0)
00612 return 1;
00613
00614 for(i = 0; i < jwl->aliases->size; i++)
00615 if(jwl->aliases->a[i].len == ll &&
00616 !strncasecmp(p, jwl->aliases->a[i].s, ll))
00617 return 0;
00618 return 1;
00619 }
00620
00628 void xj_wlist_del(xj_wlist jwl, xj_jkey jkey, int _pid)
00629 {
00630 int i;
00631 void *p;
00632 if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
00633 return;
00634 for(i=0; i < jwl->len; i++)
00635 if(jwl->workers[i].pid == _pid)
00636 break;
00637 if(i >= jwl->len)
00638 {
00639 LM_DBG("%d: key <%.*s> not found in [%d]...\n",
00640 _pid, jkey->id->len, jkey->id->s, i);
00641 return;
00642 }
00643 #ifdef XJ_EXTRA_DEBUG
00644 LM_DBG("%d: trying to delete entry for <%.*s>...\n",
00645 _pid, jkey->id->len, jkey->id->s);
00646 #endif
00647 lock_set_get(jwl->sems, i);
00648 p = del234(jwl->workers[i].sip_ids, (void*)jkey);
00649
00650 if(p != NULL)
00651 {
00652 jwl->workers[i].nr--;
00653 #ifdef XJ_EXTRA_DEBUG
00654 LM_DBG("%d: sip id <%.*s> deleted\n", _pid,
00655 jkey->id->len, jkey->id->s);
00656 #endif
00657 xj_jkey_free_p(p);
00658 }
00659
00660 lock_set_release(jwl->sems, i);
00661 }
00662