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
00041
00042
00043
00044
00045
00046
00047
00048 #include <stdio.h>
00049 #include <string.h>
00050 #include <stdlib.h>
00051
00052 #include "../../ut.h"
00053 #include "../../trim.h"
00054 #include "../../dprint.h"
00055 #include "../../action.h"
00056 #include "../../route.h"
00057 #include "../../dset.h"
00058 #include "../../mem/shm_mem.h"
00059 #include "../../parser/parse_uri.h"
00060 #include "../../parser/parse_from.h"
00061 #include "../../usr_avp.h"
00062 #include "../../mi/mi.h"
00063 #include "../../parser/digest/digest.h"
00064 #include "../../resolve.h"
00065 #include "../tm/tm_load.h"
00066 #include "../../db/db.h"
00067 #include "../../db/db_res.h"
00068 #include "../../str.h"
00069
00070 #include "dispatch.h"
00071
00072 #define DS_TABLE_VERSION 1
00073 #define DS_TABLE_VERSION2 2
00074 #define DS_TABLE_VERSION3 3
00075
00076 static int _ds_table_version = DS_TABLE_VERSION;
00077
00078 typedef struct _ds_dest
00079 {
00080 str uri;
00081 int flags;
00082 int priority;
00083 struct ip_addr ip_address;
00084 unsigned short int port;
00085 int failure_count;
00086 struct _ds_dest *next;
00087 } ds_dest_t, *ds_dest_p;
00088
00089 typedef struct _ds_set
00090 {
00091 int id;
00092 int nr;
00093 int last;
00094 ds_dest_p dlist;
00095 struct _ds_set *next;
00096 } ds_set_t, *ds_set_p;
00097
00098 extern int ds_force_dst;
00099
00100 static db_func_t ds_dbf;
00101 static db_con_t* ds_db_handle=0;
00102 ds_set_p *ds_lists=NULL;
00103 int *ds_list_nr = NULL;
00104 int *crt_idx = NULL;
00105 int *next_idx = NULL;
00106
00107 #define _ds_list (ds_lists[*crt_idx])
00108 #define _ds_list_nr (*ds_list_nr)
00109
00110 void destroy_list(int);
00111
00112 static int ds_print_sets(void)
00113 {
00114 ds_set_p si = NULL;
00115 int i;
00116
00117 if(_ds_list==NULL)
00118 return -1;
00119
00120
00121 si = _ds_list;
00122 while(si)
00123 {
00124 for(i=0; i<si->nr; i++)
00125 {
00126 LM_DBG("dst>> %d %.*s %d %d\n", si->id,
00127 si->dlist[i].uri.len, si->dlist[i].uri.s,
00128 si->dlist[i].flags, si->dlist[i].priority);
00129 }
00130 si = si->next;
00131 }
00132
00133 return 0;
00134 }
00135
00136 int init_data(void)
00137 {
00138 int * p;
00139
00140 ds_lists = (ds_set_p*)shm_malloc(2*sizeof(ds_set_p));
00141 if(!ds_lists)
00142 {
00143 LM_ERR("Out of memory\n");
00144 return -1;
00145 }
00146 ds_lists[0] = ds_lists[1] = 0;
00147
00148
00149 p = (int*)shm_malloc(3*sizeof(int));
00150 if(!p)
00151 {
00152 LM_ERR("Out of memory\n");
00153 return -1;
00154 }
00155
00156 crt_idx = p;
00157 next_idx = p+1;
00158 ds_list_nr = p+2;
00159 *crt_idx= *next_idx = 0;
00160
00161 return 0;
00162 }
00163
00164 int add_dest2list(int id, str uri, int flags, int priority, int list_idx,
00165 int * setn)
00166 {
00167 ds_dest_p dp = NULL;
00168 ds_set_p sp = NULL;
00169 ds_dest_p dp0 = NULL;
00170 ds_dest_p dp1 = NULL;
00171
00172
00173 static char hn[256];
00174 struct hostent* he;
00175 struct sip_uri puri;
00176
00177
00178 if(parse_uri(uri.s, uri.len, &puri)!=0 || puri.host.len>254)
00179 {
00180 LM_ERR("bad uri [%.*s]\n", uri.len, uri.s);
00181 goto err;
00182 }
00183
00184
00185 sp = ds_lists[list_idx];
00186 while(sp)
00187 {
00188 if(sp->id == id)
00189 break;
00190 sp = sp->next;
00191 }
00192
00193 if(sp==NULL)
00194 {
00195 sp = (ds_set_p)shm_malloc(sizeof(ds_set_t));
00196 if(sp==NULL)
00197 {
00198 LM_ERR("no more memory.\n");
00199 goto err;
00200 }
00201
00202 memset(sp, 0, sizeof(ds_set_t));
00203 sp->next = ds_lists[list_idx];
00204 ds_lists[list_idx] = sp;
00205 *setn = *setn+1;
00206 }
00207 sp->id = id;
00208 sp->nr++;
00209
00210
00211 dp = (ds_dest_p)shm_malloc(sizeof(ds_dest_t));
00212 if(dp==NULL)
00213 {
00214 LM_ERR("no more memory!\n");
00215 goto err;
00216 }
00217 memset(dp, 0, sizeof(ds_dest_t));
00218
00219 dp->uri.s = (char*)shm_malloc((uri.len+1)*sizeof(char));
00220 if(dp->uri.s==NULL)
00221 {
00222 LM_ERR("no more memory!\n");
00223 goto err;
00224 }
00225 strncpy(dp->uri.s, uri.s, uri.len);
00226 dp->uri.s[uri.len]='\0';
00227 dp->uri.len = uri.len;
00228 dp->flags = flags;
00229 dp->priority = priority;
00230
00231
00232
00233 strncpy(hn, puri.host.s, puri.host.len);
00234 hn[puri.host.len]='\0';
00235
00236
00237 he=resolvehost(hn, 1);
00238 if (he==0)
00239 {
00240 LM_ERR("could not resolve %.*s\n", puri.host.len, puri.host.s);
00241 pkg_free(hn);
00242 goto err;
00243 }
00244
00245 hostent2ip_addr(&dp->ip_address, he, 0);
00246
00247
00248 dp->port = puri.port_no;
00249
00250 if(sp->dlist==NULL)
00251 {
00252 sp->dlist = dp;
00253 } else {
00254 dp1 = NULL;
00255 dp0 = sp->dlist;
00256
00257 while(dp0) {
00258 if(dp0->priority > dp->priority)
00259 break;
00260 dp1 = dp0;
00261 dp0=dp0->next;
00262 }
00263 if(dp1==NULL)
00264 {
00265 dp->next = sp->dlist;
00266 sp->dlist = dp;
00267 } else {
00268 dp->next = dp1->next;
00269 dp1->next = dp;
00270 }
00271 }
00272
00273 LM_DBG("dest [%d/%d] <%.*s>\n", sp->id, sp->nr, dp->uri.len, dp->uri.s);
00274
00275 return 0;
00276 err:
00277
00278 if(dp!=NULL)
00279 {
00280 if(dp->uri.s!=NULL)
00281 shm_free(dp->uri.s);
00282 shm_free(dp);
00283 }
00284 return -1;
00285 }
00286
00287
00288 int reindex_dests(int list_idx, int setn)
00289 {
00290 int j;
00291 ds_set_p sp = NULL;
00292 ds_dest_p dp = NULL, dp0= NULL;
00293
00294 for(sp = ds_lists[list_idx]; sp!= NULL; sp->dlist = dp0, sp = sp->next)
00295 {
00296 dp0 = (ds_dest_p)shm_malloc(sp->nr*sizeof(ds_dest_t));
00297 if(dp0==NULL)
00298 {
00299 LM_ERR("no more memory!\n");
00300 goto err1;
00301 }
00302 memset(dp0, 0, sp->nr*sizeof(ds_dest_t));
00303
00304
00305 for(j=sp->nr-1; j>=0 && sp->dlist!= NULL; j--)
00306 {
00307 memcpy(&dp0[j], sp->dlist, sizeof(ds_dest_t));
00308 if(j==sp->nr-1)
00309 dp0[j].next = NULL;
00310 else
00311 dp0[j].next = &dp0[j+1];
00312
00313 dp = sp->dlist;
00314 sp->dlist = dp->next;
00315
00316 shm_free(dp);
00317 dp=NULL;
00318 }
00319 }
00320
00321 LM_DBG("found [%d] dest sets\n", setn);
00322 return 0;
00323
00324 err1:
00325 return -1;
00326 }
00327
00328
00329 int ds_load_list(char *lfile)
00330 {
00331 char line[256], *p;
00332 FILE *f = NULL;
00333 int id, setn, flags, priority;
00334 str uri;
00335
00336 if( (*crt_idx) != (*next_idx)) {
00337 LM_WARN("load command already generated, aborting reload...\n");
00338 return 0;
00339 }
00340
00341 if(lfile==NULL || strlen(lfile)<=0)
00342 {
00343 LM_ERR("bad list file\n");
00344 return -1;
00345 }
00346
00347 f = fopen(lfile, "r");
00348 if(f==NULL)
00349 {
00350 LM_ERR("can't open list file [%s]\n", lfile);
00351 return -1;
00352
00353 }
00354
00355 id = setn = flags = priority = 0;
00356
00357 *next_idx = (*crt_idx + 1)%2;
00358 destroy_list(*next_idx);
00359
00360 p = fgets(line, 256, f);
00361 while(p)
00362 {
00363
00364 while(*p && (*p==' ' || *p=='\t' || *p=='\r' || *p=='\n'))
00365 p++;
00366 if(*p=='\0' || *p=='#')
00367 goto next_line;
00368
00369
00370 id = 0;
00371 while(*p>='0' && *p<='9')
00372 {
00373 id = id*10+ (*p-'0');
00374 p++;
00375 }
00376
00377
00378 while(*p && (*p==' ' || *p=='\t' || *p=='\r' || *p=='\n'))
00379 p++;
00380 if(*p=='\0' || *p=='#')
00381 {
00382 LM_ERR("bad line [%s]\n", line);
00383 goto error;
00384 }
00385
00386
00387 uri.s = p;
00388 while(*p && *p!=' ' && *p!='\t' && *p!='\r' && *p!='\n' && *p!='#')
00389 p++;
00390 uri.len = p-uri.s;
00391
00392
00393 while(*p && (*p==' ' || *p=='\t' || *p=='\r' || *p=='\n'))
00394 p++;
00395
00396
00397 flags = 0;
00398 priority = 0;
00399 if(*p=='\0' || *p=='#')
00400 goto add_destination;
00401
00402 while(*p>='0' && *p<='9')
00403 {
00404 flags = flags*10+ (*p-'0');
00405 p++;
00406 }
00407
00408
00409 while(*p && (*p==' ' || *p=='\t' || *p=='\r' || *p=='\n'))
00410 p++;
00411
00412
00413 priority = 0;
00414 if(*p=='\0' || *p=='#')
00415 goto add_destination;
00416
00417 while(*p>='0' && *p<='9')
00418 {
00419 priority = priority*10+ (*p-'0');
00420 p++;
00421 }
00422
00423 add_destination:
00424 if(add_dest2list(id, uri, flags, priority, *next_idx, &setn) != 0)
00425 goto error;
00426
00427
00428 next_line:
00429 p = fgets(line, 256, f);
00430 }
00431
00432 if(reindex_dests(*next_idx, setn)!=0){
00433 LM_ERR("error on reindex\n");
00434 goto error;
00435 }
00436
00437 fclose(f);
00438 f = NULL;
00439
00440 _ds_list_nr = setn;
00441 *crt_idx = *next_idx;
00442 ds_print_sets();
00443 return 0;
00444
00445 error:
00446 if(f!=NULL)
00447 fclose(f);
00448 destroy_list(*next_idx);
00449 *next_idx = *crt_idx;
00450 return -1;
00451 }
00452
00453 int ds_connect_db(void)
00454 {
00455 if(!ds_db_url.s)
00456 return -1;
00457
00458 if (ds_db_handle)
00459 {
00460 LM_CRIT("BUG - db connection found already open\n");
00461 return -1;
00462 }
00463
00464 if ((ds_db_handle = ds_dbf.init(&ds_db_url)) == 0){
00465
00466 return -1;
00467 }
00468 return 0;
00469 }
00470
00471 void ds_disconnect_db(void)
00472 {
00473 if(ds_db_handle)
00474 {
00475 ds_dbf.close(ds_db_handle);
00476 ds_db_handle = 0;
00477 }
00478 }
00479
00480
00481 int init_ds_db(void)
00482 {
00483 int ret;
00484
00485 if(ds_table_name.s == 0)
00486 {
00487 LM_ERR("invalid database name\n");
00488 return -1;
00489 }
00490
00491
00492 if (db_bind_mod(&ds_db_url, &ds_dbf) < 0)
00493 {
00494 LM_ERR("Unable to bind to a database driver\n");
00495 return -1;
00496 }
00497
00498 if(ds_connect_db()!=0){
00499
00500 LM_ERR("unable to connect to the database\n");
00501 return -1;
00502 }
00503
00504 _ds_table_version = db_table_version(&ds_dbf, ds_db_handle, &ds_table_name);
00505 if (_ds_table_version < 0)
00506 {
00507 LM_ERR("failed to query table version\n");
00508 return -1;
00509 } else if (_ds_table_version != DS_TABLE_VERSION
00510 && _ds_table_version != DS_TABLE_VERSION2
00511 && _ds_table_version != DS_TABLE_VERSION3) {
00512 LM_ERR("invalid table version (found %d , required %d, %d or %d)\n"
00513 "(use kamdbctl reinit)\n",
00514 _ds_table_version, DS_TABLE_VERSION, DS_TABLE_VERSION2,
00515 DS_TABLE_VERSION3);
00516 return -1;
00517 }
00518
00519 ret = ds_load_db();
00520
00521 ds_disconnect_db();
00522
00523 return ret;
00524 }
00525
00526
00527 int ds_load_db(void)
00528 {
00529 int i, id, nr_rows, setn;
00530 int flags;
00531 int priority;
00532 int nrcols;
00533 str uri;
00534 db_res_t * res;
00535 db_val_t * values;
00536 db_row_t * rows;
00537
00538 db_key_t query_cols[4] = {&ds_set_id_col, &ds_dest_uri_col,
00539 &ds_dest_flags_col, &ds_dest_priority_col};
00540
00541 nrcols = 2;
00542 if(_ds_table_version == DS_TABLE_VERSION2)
00543 nrcols = 3;
00544 else if(_ds_table_version == DS_TABLE_VERSION3)
00545 nrcols = 4;
00546
00547 if( (*crt_idx) != (*next_idx))
00548 {
00549 LM_WARN("load command already generated, aborting reload...\n");
00550 return 0;
00551 }
00552
00553 if(ds_db_handle == NULL){
00554 LM_ERR("invalid DB handler\n");
00555 return -1;
00556 }
00557
00558 if (ds_dbf.use_table(ds_db_handle, &ds_table_name) < 0)
00559 {
00560 LM_ERR("error in use_table\n");
00561 return -1;
00562 }
00563
00564
00565 if(ds_dbf.query(ds_db_handle,0,0,0,query_cols,0,nrcols,0,&res) < 0)
00566 {
00567 LM_ERR("error while querying database\n");
00568 return -1;
00569 }
00570
00571 nr_rows = RES_ROW_N(res);
00572 rows = RES_ROWS(res);
00573 if(nr_rows == 0)
00574 {
00575 LM_WARN("no dispatching data in the db -- empty destination set\n");
00576 ds_dbf.free_result(ds_db_handle, res);
00577 return 0;
00578 }
00579
00580 setn = 0;
00581 *next_idx = (*crt_idx + 1)%2;
00582 destroy_list(*next_idx);
00583
00584 for(i=0; i<nr_rows; i++)
00585 {
00586 values = ROW_VALUES(rows+i);
00587
00588 id = VAL_INT(values);
00589 uri.s = VAL_STR(values+1).s;
00590 uri.len = strlen(uri.s);
00591 flags = 0;
00592 if(nrcols>=3)
00593 flags = VAL_INT(values+2);
00594 priority=0;
00595 if(nrcols>=4)
00596 priority = VAL_INT(values+3);
00597
00598 if(add_dest2list(id, uri, flags, priority, *next_idx, &setn) != 0)
00599 goto err2;
00600
00601 }
00602 ds_dbf.free_result(ds_db_handle, res);
00603
00604 if(reindex_dests(*next_idx, setn)!=0)
00605 {
00606 LM_ERR("error on reindex\n");
00607 goto err2;
00608 }
00609
00610
00611 _ds_list_nr = setn;
00612 *crt_idx = *next_idx;
00613
00614 ds_print_sets();
00615
00616 return 0;
00617
00618 err2:
00619 destroy_list(*next_idx);
00620 ds_dbf.free_result(ds_db_handle, res);
00621 *next_idx = *crt_idx;
00622
00623 return -1;
00624 }
00625
00626
00627 int ds_destroy_list(void)
00628 {
00629 if (ds_lists) {
00630 destroy_list(0);
00631 destroy_list(1);
00632 shm_free(ds_lists);
00633 }
00634
00635 if (crt_idx)
00636 shm_free(crt_idx);
00637
00638 return 0;
00639 }
00640
00641 void destroy_list(int list_id)
00642 {
00643 ds_set_p sp = NULL;
00644 ds_dest_p dest = NULL;
00645
00646 sp = ds_lists[list_id];
00647
00648 while(sp)
00649 {
00650 for(dest = sp->dlist; dest!= NULL; dest=dest->next)
00651 {
00652 if(dest->uri.s!=NULL)
00653 {
00654 shm_free(dest->uri.s);
00655 dest->uri.s = NULL;
00656 }
00657 }
00658 shm_free(sp->dlist);
00659 sp = sp->next;
00660 }
00661
00662 ds_lists[list_id] = NULL;
00663 }
00664
00665
00666
00667
00668 unsigned int ds_get_hash(str *x, str *y)
00669 {
00670 char* p;
00671 register unsigned v;
00672 register unsigned h;
00673
00674 if(!x && !y)
00675 return 0;
00676 h=0;
00677 if(x)
00678 {
00679 p=x->s;
00680 if (x->len>=4)
00681 {
00682 for (; p<=(x->s+x->len-4); p+=4)
00683 {
00684 v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
00685 h+=v^(v>>3);
00686 }
00687 }
00688 v=0;
00689 for (;p<(x->s+x->len); p++)
00690 {
00691 v<<=8;
00692 v+=*p;
00693 }
00694 h+=v^(v>>3);
00695 }
00696 if(y)
00697 {
00698 p=y->s;
00699 if (y->len>=4)
00700 {
00701 for (; p<=(y->s+y->len-4); p+=4)
00702 {
00703 v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
00704 h+=v^(v>>3);
00705 }
00706 }
00707
00708 v=0;
00709 for (;p<(y->s+y->len); p++)
00710 {
00711 v<<=8;
00712 v+=*p;
00713 }
00714 h+=v^(v>>3);
00715 }
00716 h=((h)+(h>>11))+((h>>13)+(h>>23));
00717
00718 return (h)?h:1;
00719 }
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 static inline int get_uri_hash_keys(str* key1, str* key2,
00737 str* uri, struct sip_uri* parsed_uri, int flags)
00738 {
00739 struct sip_uri tmp_p_uri;
00740
00741 if (parsed_uri==0)
00742 {
00743 if (parse_uri(uri->s, uri->len, &tmp_p_uri)<0)
00744 {
00745 LM_ERR("invalid uri %.*s\n", uri->len, uri->len?uri->s:"");
00746 goto error;
00747 }
00748 parsed_uri=&tmp_p_uri;
00749 }
00750
00751 if (parsed_uri->host.s==0)
00752 {
00753 LM_ERR("invalid uri, no host present: %.*s\n",
00754 uri->len, uri->len?uri->s:"");
00755 goto error;
00756 }
00757
00758
00759
00760
00761 *key1=parsed_uri->user;
00762 key2->s=0;
00763 key2->len=0;
00764 if (!(flags & DS_HASH_USER_ONLY))
00765 {
00766 *key2=parsed_uri->host;
00767
00768 if (parsed_uri->port.s!=0)
00769 {
00770
00771 if (parsed_uri->port_no !=
00772 ((parsed_uri->type==SIPS_URI_T)?SIPS_PORT:SIP_PORT))
00773 key2->len+=parsed_uri->port.len+1 ;
00774 }
00775 }
00776 if (key1->s==0)
00777 {
00778 LM_WARN("empty username in: %.*s\n", uri->len, uri->len?uri->s:"");
00779 }
00780 return 0;
00781 error:
00782 return -1;
00783 }
00784
00785
00786
00787
00788
00789
00790 int ds_hash_fromuri(struct sip_msg *msg, unsigned int *hash)
00791 {
00792 str from;
00793 str key1;
00794 str key2;
00795
00796 if(msg==NULL || hash == NULL)
00797 {
00798 LM_ERR("bad parameters\n");
00799 return -1;
00800 }
00801
00802 if(parse_from_header(msg)<0)
00803 {
00804 LM_ERR("cannot parse From hdr\n");
00805 return -1;
00806 }
00807
00808 if(msg->from==NULL || get_from(msg)==NULL)
00809 {
00810 LM_ERR("cannot get From uri\n");
00811 return -1;
00812 }
00813
00814 from = get_from(msg)->uri;
00815 trim(&from);
00816 if (get_uri_hash_keys(&key1, &key2, &from, 0, ds_flags)<0)
00817 return -1;
00818 *hash = ds_get_hash(&key1, &key2);
00819
00820 return 0;
00821 }
00822
00823
00824
00825
00826
00827
00828 int ds_hash_touri(struct sip_msg *msg, unsigned int *hash)
00829 {
00830 str to;
00831 str key1;
00832 str key2;
00833
00834 if(msg==NULL || hash == NULL)
00835 {
00836 LM_ERR("bad parameters\n");
00837 return -1;
00838 }
00839 if ((msg->to==0) && ((parse_headers(msg, HDR_TO_F, 0)==-1) ||
00840 (msg->to==0)))
00841 {
00842 LM_ERR("cannot parse To hdr\n");
00843 return -1;
00844 }
00845
00846
00847 to = get_to(msg)->uri;
00848 trim(&to);
00849
00850 if (get_uri_hash_keys(&key1, &key2, &to, 0, ds_flags)<0)
00851 return -1;
00852 *hash = ds_get_hash(&key1, &key2);
00853
00854 return 0;
00855 }
00856
00857
00858
00859
00860
00861
00862 int ds_hash_callid(struct sip_msg *msg, unsigned int *hash)
00863 {
00864 str cid;
00865 if(msg==NULL || hash == NULL)
00866 {
00867 LM_ERR("bad parameters\n");
00868 return -1;
00869 }
00870
00871 if(msg->callid==NULL && ((parse_headers(msg, HDR_CALLID_F, 0)==-1) ||
00872 (msg->callid==NULL)) )
00873 {
00874 LM_ERR("cannot parse Call-Id\n");
00875 return -1;
00876 }
00877
00878 cid.s = msg->callid->body.s;
00879 cid.len = msg->callid->body.len;
00880 trim(&cid);
00881
00882 *hash = ds_get_hash(&cid, NULL);
00883
00884 return 0;
00885 }
00886
00887
00888
00889 int ds_hash_ruri(struct sip_msg *msg, unsigned int *hash)
00890 {
00891 str* uri;
00892 str key1;
00893 str key2;
00894
00895
00896 if(msg==NULL || hash == NULL)
00897 {
00898 LM_ERR("bad parameters\n");
00899 return -1;
00900 }
00901 if (parse_sip_msg_uri(msg)<0){
00902 LM_ERR("bad request uri\n");
00903 return -1;
00904 }
00905
00906 uri=GET_RURI(msg);
00907 if (get_uri_hash_keys(&key1, &key2, uri, &msg->parsed_uri, ds_flags)<0)
00908 return -1;
00909
00910 *hash = ds_get_hash(&key1, &key2);
00911 return 0;
00912 }
00913
00914 int ds_hash_authusername(struct sip_msg *msg, unsigned int *hash)
00915 {
00916
00917 struct hdr_field* h = 0;
00918
00919 str username = {0, 0};
00920
00921 auth_body_t* cred;
00922
00923 if(msg==NULL || hash == NULL)
00924 {
00925 LM_ERR("bad parameters\n");
00926 return -1;
00927 }
00928 if (parse_headers(msg, HDR_PROXYAUTH_F, 0) == -1)
00929 {
00930 LM_ERR("error parsing headers!\n");
00931 return -1;
00932 }
00933 if (msg->proxy_auth && !msg->proxy_auth->parsed)
00934 parse_credentials(msg->proxy_auth);
00935 if (msg->proxy_auth && msg->proxy_auth->parsed) {
00936 h = msg->proxy_auth;
00937 }
00938 if (!h)
00939 {
00940 if (parse_headers(msg, HDR_AUTHORIZATION_F, 0) == -1)
00941 {
00942 LM_ERR("error parsing headers!\n");
00943 return -1;
00944 }
00945 if (msg->authorization && !msg->authorization->parsed)
00946 parse_credentials(msg->authorization);
00947 if (msg->authorization && msg->authorization->parsed) {
00948 h = msg->authorization;
00949 }
00950 }
00951 if (!h)
00952 {
00953 LM_DBG("No Authorization-Header!\n");
00954 return 1;
00955 }
00956
00957 cred=(auth_body_t*)(h->parsed);
00958 if (!cred || !cred->digest.username.user.len)
00959 {
00960 LM_ERR("No Authorization-Username or Credentials!\n");
00961 return 1;
00962 }
00963
00964 username.s = cred->digest.username.user.s;
00965 username.len = cred->digest.username.user.len;
00966
00967 trim(&username);
00968
00969 *hash = ds_get_hash(&username, NULL);
00970
00971 return 0;
00972 }
00973
00974
00975 int ds_hash_pvar(struct sip_msg *msg, unsigned int *hash)
00976 {
00977
00978 str hash_str = {0, 0};
00979
00980 if(msg==NULL || hash == NULL || hash_param_model == NULL)
00981 {
00982 LM_ERR("bad parameters\n");
00983 return -1;
00984 }
00985 if (pv_printf_s(msg, hash_param_model, &hash_str)<0) {
00986 LM_ERR("error - cannot print the format\n");
00987 return -1;
00988 }
00989
00990
00991 trim(&hash_str);
00992 if (hash_str.len <= 0) {
00993 LM_ERR("String is empty!\n");
00994 return -1;
00995 }
00996 LM_DBG("Hashing %.*s!\n", hash_str.len, hash_str.s);
00997
00998 *hash = ds_get_hash(&hash_str, NULL);
00999
01000 return 0;
01001 }
01002
01003 static inline int ds_get_index(int group, ds_set_p *index)
01004 {
01005 ds_set_p si = NULL;
01006
01007 if(index==NULL || group<0 || _ds_list==NULL)
01008 return -1;
01009
01010
01011 si = _ds_list;
01012 while(si)
01013 {
01014 if(si->id == group)
01015 {
01016 *index = si;
01017 break;
01018 }
01019 si = si->next;
01020 }
01021
01022 if(si==NULL)
01023 {
01024 LM_ERR("destination set [%d] not found\n", group);
01025 return -1;
01026 }
01027
01028 return 0;
01029 }
01030
01031 static inline int ds_update_dst(struct sip_msg *msg, str *uri, int mode)
01032 {
01033 struct action act;
01034 str *duri = NULL;
01035 switch(mode)
01036 {
01037 case 1:
01038 act.type = SET_HOSTALL_T;
01039 act.elem[0].type = STRING_ST;
01040 if(uri->len>4
01041 && strncasecmp(uri->s,"sip:",4)==0)
01042 act.elem[0].u.string = uri->s+4;
01043 else
01044 act.elem[0].u.string = uri->s;
01045 act.next = 0;
01046
01047 if (do_action(&act, msg) < 0) {
01048 LM_ERR("error while setting host\n");
01049 return -1;
01050 }
01051 break;
01052 default:
01053 duri = uri;
01054 if (set_dst_uri(msg, uri) < 0) {
01055 LM_ERR("error while setting dst uri\n");
01056 return -1;
01057 }
01058 break;
01059 }
01060 if(ds_append_branch!=0 && route_type==FAILURE_ROUTE)
01061 {
01062 if (append_branch(msg, 0, duri, 0, Q_UNSPECIFIED, 0, 0)!=1 )
01063 {
01064 LM_ERR("append_branch action failed\n");
01065 return -1;
01066 }
01067 }
01068 return 0;
01069 }
01070
01071
01072
01073
01074 int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
01075 {
01076 int i, cnt;
01077 unsigned int hash;
01078 int_str avp_val;
01079 ds_set_p idx = NULL;
01080
01081 if(msg==NULL)
01082 {
01083 LM_ERR("bad parameters\n");
01084 return -1;
01085 }
01086
01087 if(_ds_list==NULL || _ds_list_nr<=0)
01088 {
01089 LM_ERR("no destination sets\n");
01090 return -1;
01091 }
01092
01093 if((mode==0) && (ds_force_dst==0)
01094 && (msg->dst_uri.s!=NULL || msg->dst_uri.len>0))
01095 {
01096 LM_ERR("destination already set [%.*s]\n", msg->dst_uri.len,
01097 msg->dst_uri.s);
01098 return -1;
01099 }
01100
01101
01102
01103 if(ds_get_index(set, &idx)!=0)
01104 {
01105 LM_ERR("destination set [%d] not found\n", set);
01106 return -1;
01107 }
01108
01109 LM_DBG("set [%d]\n", set);
01110
01111 hash = 0;
01112 switch(alg)
01113 {
01114 case 0:
01115 if(ds_hash_callid(msg, &hash)!=0)
01116 {
01117 LM_ERR("can't get callid hash\n");
01118 return -1;
01119 }
01120 break;
01121 case 1:
01122 if(ds_hash_fromuri(msg, &hash)!=0)
01123 {
01124 LM_ERR("can't get From uri hash\n");
01125 return -1;
01126 }
01127 break;
01128 case 2:
01129 if(ds_hash_touri(msg, &hash)!=0)
01130 {
01131 LM_ERR("can't get To uri hash\n");
01132 return -1;
01133 }
01134 break;
01135 case 3:
01136 if (ds_hash_ruri(msg, &hash)!=0)
01137 {
01138 LM_ERR("can't get ruri hash\n");
01139 return -1;
01140 }
01141 break;
01142 case 4:
01143 hash = idx->last;
01144 idx->last = (idx->last+1) % idx->nr;
01145 break;
01146 case 5:
01147 i = ds_hash_authusername(msg, &hash);
01148 switch (i)
01149 {
01150 case 0:
01151
01152 break;
01153 case 1:
01154
01155 hash = idx->last;
01156 idx->last = (idx->last+1) % idx->nr;
01157 break;
01158 default:
01159 LM_ERR("can't get authorization hash\n");
01160 return -1;
01161 break;
01162 }
01163 break;
01164 case 6:
01165 hash = rand() % idx->nr;
01166 break;
01167 case 7:
01168 if (ds_hash_pvar(msg, &hash)!=0)
01169 {
01170 LM_ERR("can't get PV hash\n");
01171 return -1;
01172 }
01173 break;
01174 case 8:
01175
01176 hash = 0;
01177 break;
01178 default:
01179 LM_WARN("algo %d not implemented - using first entry...\n", alg);
01180 hash = 0;
01181 }
01182
01183 LM_DBG("alg hash [%u]\n", hash);
01184 cnt = 0;
01185
01186 if(ds_use_default!=0 && idx->nr!=1)
01187 hash = hash%(idx->nr-1);
01188 else
01189 hash = hash%idx->nr;
01190 i=hash;
01191 while ((idx->dlist[i].flags & DS_INACTIVE_DST)
01192 || (idx->dlist[i].flags & DS_PROBING_DST))
01193 {
01194 if(ds_use_default!=0)
01195 i = (i+1)%(idx->nr-1);
01196 else
01197 i = (i+1)%idx->nr;
01198 if(i==hash)
01199 {
01200 if(ds_use_default!=0)
01201 {
01202 i = idx->nr-1;
01203 } else {
01204 return -1;
01205 }
01206 }
01207 }
01208
01209 hash = i;
01210
01211 if(ds_update_dst(msg, &idx->dlist[hash].uri, mode)!=0)
01212 {
01213 LM_ERR("cannot set dst addr\n");
01214 return -1;
01215 }
01216
01217 if(alg==4)
01218 idx->last = (hash+1) % idx->nr;
01219
01220 LM_DBG("selected [%d-%d/%d] <%.*s>\n", alg, set, hash,
01221 idx->dlist[hash].uri.len, idx->dlist[hash].uri.s);
01222
01223 if(!(ds_flags&DS_FAILOVER_ON))
01224 return 1;
01225
01226 if(dst_avp_name.n!=0)
01227 {
01228 if(ds_use_default!=0 && hash!=idx->nr-1)
01229 {
01230 avp_val.s = idx->dlist[idx->nr-1].uri;
01231 if(add_avp(AVP_VAL_STR|dst_avp_type, dst_avp_name, avp_val)!=0)
01232 return -1;
01233 cnt++;
01234 }
01235
01236
01237
01238 for(i=hash-1; i>=0; i--)
01239 {
01240 if((idx->dlist[i].flags & DS_INACTIVE_DST)
01241 || (ds_use_default!=0 && i==(idx->nr-1)))
01242 continue;
01243 LM_DBG("using entry [%d/%d]\n", set, i);
01244 avp_val.s = idx->dlist[i].uri;
01245 if(add_avp(AVP_VAL_STR|dst_avp_type, dst_avp_name, avp_val)!=0)
01246 return -1;
01247 cnt++;
01248 }
01249
01250 for(i=idx->nr-1; i>hash; i--)
01251 {
01252 if((idx->dlist[i].flags & DS_INACTIVE_DST)
01253 || (ds_use_default!=0 && i==(idx->nr-1)))
01254 continue;
01255 LM_DBG("using entry [%d/%d]\n", set, i);
01256 avp_val.s = idx->dlist[i].uri;
01257 if(add_avp(AVP_VAL_STR|dst_avp_type, dst_avp_name, avp_val)!=0)
01258 return -1;
01259 cnt++;
01260 }
01261
01262
01263 avp_val.s = idx->dlist[hash].uri;
01264 if(add_avp(AVP_VAL_STR|dst_avp_type, dst_avp_name, avp_val)!=0)
01265 return -1;
01266 cnt++;
01267 }
01268
01269 if(grp_avp_name.n!=0)
01270 {
01271
01272 avp_val.n = set;
01273 if(add_avp(grp_avp_type, grp_avp_name, avp_val)!=0)
01274 return -1;
01275 }
01276
01277 if(cnt_avp_name.n!=0)
01278 {
01279
01280 avp_val.n = cnt;
01281 if(add_avp(cnt_avp_type, cnt_avp_name, avp_val)!=0)
01282 return -1;
01283 }
01284
01285 return 1;
01286 }
01287
01288 int ds_next_dst(struct sip_msg *msg, int mode)
01289 {
01290 struct usr_avp *avp;
01291 struct usr_avp *prev_avp;
01292 int_str avp_value;
01293
01294 if(!(ds_flags&DS_FAILOVER_ON) || dst_avp_name.n==0)
01295 {
01296 LM_WARN("failover support disabled\n");
01297 return -1;
01298 }
01299
01300
01301 prev_avp = search_first_avp(dst_avp_type, dst_avp_name, &avp_value, 0);
01302 if(prev_avp==NULL)
01303 return -1;
01304
01305 avp = search_next_avp(prev_avp, &avp_value);
01306 destroy_avp(prev_avp);
01307 if(avp==NULL || !(avp->flags&AVP_VAL_STR))
01308 return -1;
01309
01310 if(ds_update_dst(msg, &avp_value.s, mode)!=0)
01311 {
01312 LM_ERR("cannot set dst addr\n");
01313 return -1;
01314 }
01315 LM_DBG("using [%.*s]\n", avp_value.s.len, avp_value.s.s);
01316
01317 return 1;
01318 }
01319
01320 int ds_mark_dst(struct sip_msg *msg, int mode)
01321 {
01322 int group, ret;
01323 struct usr_avp *prev_avp;
01324 int_str avp_value;
01325
01326 if(!(ds_flags&DS_FAILOVER_ON))
01327 {
01328 LM_WARN("failover support disabled\n");
01329 return -1;
01330 }
01331
01332 prev_avp = search_first_avp(grp_avp_type, grp_avp_name, &avp_value, 0);
01333
01334 if(prev_avp==NULL || prev_avp->flags&AVP_VAL_STR)
01335 return -1;
01336 group = avp_value.n;
01337
01338 prev_avp = search_first_avp(dst_avp_type, dst_avp_name, &avp_value, 0);
01339
01340 if(prev_avp==NULL || !(prev_avp->flags&AVP_VAL_STR))
01341 return -1;
01342
01343 if(mode==1) {
01344 ret = ds_set_state(group, &avp_value.s,
01345 DS_INACTIVE_DST|DS_PROBING_DST, 0);
01346 } else if(mode==2) {
01347 ret = ds_set_state(group, &avp_value.s, DS_PROBING_DST, 1);
01348 if (ret == 0) ret = ds_set_state(group, &avp_value.s,
01349 DS_INACTIVE_DST, 0);
01350 } else {
01351 ret = ds_set_state(group, &avp_value.s, DS_INACTIVE_DST, 1);
01352 if (ret == 0) ret = ds_set_state(group, &avp_value.s,
01353 DS_PROBING_DST, 0);
01354 }
01355
01356 LM_DBG("mode [%d] grp [%d] dst [%.*s]\n", mode, group, avp_value.s.len,
01357 avp_value.s.s);
01358
01359 return (ret==0)?1:-1;
01360 }
01361
01362 int ds_set_state(int group, str *address, int state, int type)
01363 {
01364 int i=0;
01365 ds_set_p idx = NULL;
01366
01367 if(_ds_list==NULL || _ds_list_nr<=0)
01368 {
01369 LM_ERR("the list is null\n");
01370 return -1;
01371 }
01372
01373
01374 if(ds_get_index(group, &idx)!=0)
01375 {
01376 LM_ERR("destination set [%d] not found\n", group);
01377 return -1;
01378 }
01379
01380 while(i<idx->nr)
01381 {
01382 if(idx->dlist[i].uri.len==address->len
01383 && strncasecmp(idx->dlist[i].uri.s, address->s,
01384 address->len)==0)
01385 {
01386
01387
01388 if (state == DS_PROBING_DST) {
01389 if (type) {
01390 if (idx->dlist[i].flags & DS_INACTIVE_DST) {
01391 LM_INFO("Ignoring the request to set this destination"
01392 " to probing: It is already inactive!\n");
01393 return 0;
01394 }
01395
01396 idx->dlist[i].failure_count++;
01397
01398 if (idx->dlist[i].failure_count
01399 < probing_threshhold) return 0;
01400 if (idx->dlist[i].failure_count
01401 > probing_threshhold)
01402 idx->dlist[i].failure_count
01403 = probing_threshhold;
01404 }
01405 }
01406
01407 if ((state & DS_RESET_FAIL_DST) > 0) {
01408 idx->dlist[i].failure_count = 0;
01409 state &= ~DS_RESET_FAIL_DST;
01410 }
01411
01412 if(type)
01413 idx->dlist[i].flags |= state;
01414 else
01415 idx->dlist[i].flags &= ~state;
01416
01417 return 0;
01418 }
01419 i++;
01420 }
01421
01422 return -1;
01423 }
01424
01425 int ds_print_list(FILE *fout)
01426 {
01427 int j;
01428 ds_set_p list;
01429
01430 if(_ds_list==NULL || _ds_list_nr<=0)
01431 {
01432 LM_ERR("no destination sets\n");
01433 return -1;
01434 }
01435
01436 fprintf(fout, "\nnumber of destination sets: %d\n", _ds_list_nr);
01437
01438 for(list = _ds_list; list!= NULL; list= list->next)
01439 {
01440 for(j=0; j<list->nr; j++)
01441 {
01442 fprintf(fout, "\n set #%d\n", list->id);
01443
01444 if (list->dlist[j].flags&DS_INACTIVE_DST)
01445 fprintf(fout, " Disabled ");
01446 else if (list->dlist[j].flags&DS_PROBING_DST)
01447 fprintf(fout, " Probing ");
01448 else {
01449 fprintf(fout, " Active");
01450
01451 if (list->dlist[j].failure_count > 0) {
01452 fprintf(fout, " (Fail %d/%d)",
01453 list->dlist[j].failure_count,
01454 probing_threshhold);
01455 } else {
01456 fprintf(fout, " ");
01457 }
01458 }
01459
01460 fprintf(fout, " %.*s\n",
01461 list->dlist[j].uri.len, list->dlist[j].uri.s);
01462 }
01463 }
01464 return 0;
01465 }
01466
01467
01468
01469
01470
01471 int ds_is_from_list(struct sip_msg *_m, int group)
01472 {
01473 pv_value_t val;
01474 ds_set_p list;
01475 int j;
01476
01477 memset(&val, 0, sizeof(pv_value_t));
01478 val.flags = PV_VAL_INT|PV_TYPE_INT;
01479
01480 for(list = _ds_list; list!= NULL; list= list->next)
01481 {
01482
01483 if ((group == -1) || (group == list->id))
01484 {
01485 for(j=0; j<list->nr; j++)
01486 {
01487
01488 if (ip_addr_cmp(&_m->rcv.src_ip, &list->dlist[j].ip_address)
01489 && (list->dlist[j].port==0
01490 || _m->rcv.src_port == list->dlist[j].port))
01491 {
01492 if(group==-1 && ds_setid_pvname.s!=0)
01493 {
01494 val.ri = list->id;
01495 if(ds_setid_pv.setf(_m, &ds_setid_pv.pvp,
01496 (int)EQ_T, &val)<0)
01497 {
01498 LM_ERR("setting PV failed\n");
01499 return -2;
01500 }
01501 }
01502 return 1;
01503 }
01504 }
01505 }
01506 }
01507 return -1;
01508 }
01509
01510
01511 int ds_print_mi_list(struct mi_node* rpl)
01512 {
01513 int len, j;
01514 char* p;
01515 char c;
01516 ds_set_p list;
01517 struct mi_node* node = NULL;
01518 struct mi_node* set_node = NULL;
01519 struct mi_attr* attr = NULL;
01520
01521 if(_ds_list==NULL || _ds_list_nr<=0)
01522 {
01523 LM_ERR("no destination sets\n");
01524 return 0;
01525 }
01526
01527 p= int2str(_ds_list_nr, &len);
01528 node = add_mi_node_child(rpl, MI_DUP_VALUE, "SET_NO",6, p, len);
01529 if(node== NULL)
01530 return -1;
01531
01532 for(list = _ds_list; list!= NULL; list= list->next)
01533 {
01534 p = int2str(list->id, &len);
01535 set_node= add_mi_node_child(rpl, MI_DUP_VALUE,"SET", 3, p, len);
01536 if(set_node == NULL)
01537 return -1;
01538
01539 for(j=0; j<list->nr; j++)
01540 {
01541 node= add_mi_node_child(set_node, 0, "URI", 3,
01542 list->dlist[j].uri.s, list->dlist[j].uri.len);
01543 if(node == NULL)
01544 return -1;
01545
01546 if (list->dlist[j].flags & DS_INACTIVE_DST) c = 'I';
01547 else if (list->dlist[j].flags & DS_PROBING_DST) c = 'P';
01548 else c = 'A';
01549
01550 attr = add_mi_attr (node, MI_DUP_VALUE, "flag",4, &c, 1);
01551 if(attr == 0)
01552 return -1;
01553
01554 }
01555 }
01556
01557 return 0;
01558 }
01559
01560
01561
01562
01563
01564
01565
01566 static void ds_options_callback( struct cell *t, int type,
01567 struct tmcb_params *ps )
01568 {
01569 int group = 0;
01570 str uri = {0, 0};
01571
01572
01573 if (!*ps->param)
01574 {
01575 LM_DBG("No parameter provided, OPTIONS-Request was finished"
01576 " with code %d\n", ps->code);
01577 return;
01578 }
01579
01580
01581 group = (int)(long)(*ps->param);
01582
01583
01584
01585 uri.s = t->to.s + 4;
01586 uri.len = t->to.len - 6;
01587 LM_DBG("OPTIONS-Request was finished with code %d (to %.*s, group %d)\n",
01588 ps->code, uri.len, uri.s, group);
01589
01590
01591
01592
01593
01594
01595
01596 if ((ps->code == 200) || (ps->code == 501) || (ps->code == 403) || (ps->code == 405))
01597 {
01598
01599
01600 if (ds_set_state(group, &uri,
01601 DS_INACTIVE_DST|DS_PROBING_DST|DS_RESET_FAIL_DST, 0) != 0)
01602 {
01603 LM_ERR("Setting the state failed (%.*s, group %d)\n", uri.len,
01604 uri.s, group);
01605 }
01606 }
01607 if(ds_probing_mode==1 && ps->code == 408)
01608 {
01609 if (ds_set_state(group, &uri, DS_PROBING_DST, 1) != 0)
01610 {
01611 LM_ERR("Setting the probing state failed (%.*s, group %d)\n",
01612 uri.len, uri.s, group);
01613 }
01614 }
01615
01616 return;
01617 }
01618
01619
01620
01621
01622
01623
01624 void ds_check_timer(unsigned int ticks, void* param)
01625 {
01626 int j;
01627 ds_set_p list;
01628
01629
01630 if(_ds_list==NULL || _ds_list_nr<=0)
01631 {
01632 LM_ERR("no destination sets\n");
01633 return;
01634 }
01635
01636
01637 for(list = _ds_list; list!= NULL; list= list->next)
01638 {
01639 for(j=0; j<list->nr; j++)
01640 {
01641
01642 if (ds_probing_mode==1 ||
01643 (list->dlist[j].flags&DS_PROBING_DST) != 0)
01644 {
01645 LM_DBG("probing set #%d, URI %.*s\n", list->id,
01646 list->dlist[j].uri.len, list->dlist[j].uri.s);
01647
01648
01649
01650
01651
01652 if (tmb.t_request(&ds_ping_method,
01653 &list->dlist[j].uri,
01654 &list->dlist[j].uri,
01655 &ds_ping_from,
01656 NULL,
01657 NULL,
01658 NULL,
01659 ds_options_callback,
01660 (void*)(long)list->id) < 0) {
01661 LM_ERR("unable to ping [%.*s]\n",
01662 list->dlist[j].uri.len, list->dlist[j].uri.s);
01663 }
01664 }
01665 }
01666 }
01667 }