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