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 #include "stdlib.h"
00030 #include "stdio.h"
00031 #include "assert.h"
00032 #include <unistd.h>
00033
00034 #include "../../sr_module.h"
00035 #include "../../str.h"
00036 #include "../../dprint.h"
00037 #include "../../usr_avp.h"
00038 #include "../../lib/srdb1/db.h"
00039 #include "../../mem/mem.h"
00040 #include "../../mem/shm_mem.h"
00041 #include "../../locking.h"
00042 #include "../../action.h"
00043 #include "../../error.h"
00044 #include "../../ut.h"
00045 #include "../../resolve.h"
00046 #include "../../parser/parse_from.h"
00047 #include "../../parser/parse_uri.h"
00048 #include "../../dset.h"
00049 #include "../../lib/kmi/mi.h"
00050
00051 #include "dr_load.h"
00052 #include "prefix_tree.h"
00053 #include "routing.h"
00054
00055
00056
00057
00058 static str db_url = {NULL,0};
00059 static str drg_table = str_init("dr_groups");
00060 static str drd_table = str_init("dr_gateways");
00061 static str drr_table = str_init("dr_rules");
00062 static str drl_table = str_init("dr_gw_lists");
00063
00064 static int use_domain = 1;
00070 static int sort_order = 0;
00071 int dr_fetch_rows = 1000;
00072 int dr_force_dns = 1;
00073
00074
00075 static str drg_user_col = str_init("username");
00076 static str drg_domain_col = str_init("domain");
00077 static str drg_grpid_col = str_init("groupid");
00078
00079 static db1_con_t *db_hdl=0;
00080 static db_func_t dr_dbf;
00081
00082
00083 static rt_data_t **rdata = 0;
00084
00085
00086 static struct _ruri_avp{
00087 unsigned short type;
00088 int_str name;
00089 }ruri_avp = { 0, {.n=(int)0xad346b2f} };
00090 static str ruri_avp_spec = {0,0};
00091
00092
00093 static struct _attrs_avp{
00094 unsigned short type;
00095 int_str name;
00096 }attrs_avp = { 0, {.n=(int)0xad346b30} };
00097 static str attrs_avp_spec = {0,0};
00098
00099
00100 int tree_size = 0;
00101 int inode = 0;
00102 int unode = 0;
00103
00104
00105 static gen_lock_t *ref_lock = 0;
00106 static int* data_refcnt = 0;
00107 static int* reload_flag = 0;
00108
00109 static int dr_init(void);
00110 static int dr_child_init(int rank);
00111 static int dr_exit(void);
00112
00113 static int fixup_do_routing(void** param, int param_no);
00114 static int fixup_from_gw(void** param, int param_no);
00115
00116 static int do_routing(struct sip_msg* msg, dr_group_t *drg);
00117 static int do_routing_0(struct sip_msg* msg, char* str1, char* str2);
00118 static int do_routing_1(struct sip_msg* msg, char* str1, char* str2);
00119 static int use_next_gw(struct sip_msg* msg);
00120 static int is_from_gw_0(struct sip_msg* msg, char* str1, char* str2);
00121 static int is_from_gw_1(struct sip_msg* msg, char* str1, char* str2);
00122 static int is_from_gw_2(struct sip_msg* msg, char* str1, char* str2);
00123 static int goes_to_gw_0(struct sip_msg* msg, char* f1, char* f2);
00124 static int goes_to_gw_1(struct sip_msg* msg, char* f1, char* f2);
00125
00126 static struct mi_root* dr_reload_cmd(struct mi_root *cmd_tree, void *param);
00127
00128 #define RELOAD_MI_CMD "dr_reload"
00129
00130
00131 MODULE_VERSION
00132
00133
00134
00135
00136 static cmd_export_t cmds[] = {
00137 {"do_routing", (cmd_function)do_routing_0, 0, 0, 0,
00138 REQUEST_ROUTE|FAILURE_ROUTE},
00139 {"do_routing", (cmd_function)do_routing_1, 1, fixup_do_routing, 0,
00140 REQUEST_ROUTE|FAILURE_ROUTE},
00141 {"use_next_gw", (cmd_function)use_next_gw, 0, 0, 0,
00142 REQUEST_ROUTE|FAILURE_ROUTE},
00143 {"next_routing", (cmd_function)use_next_gw, 0, 0, 0,
00144 FAILURE_ROUTE},
00145 {"is_from_gw", (cmd_function)is_from_gw_0, 0, 0, 0,
00146 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE},
00147 {"is_from_gw", (cmd_function)is_from_gw_1, 1, fixup_from_gw, 0,
00148 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE},
00149 {"is_from_gw", (cmd_function)is_from_gw_2, 2, fixup_from_gw, 0,
00150 REQUEST_ROUTE},
00151 {"goes_to_gw", (cmd_function)goes_to_gw_0, 0, 0, 0,
00152 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE},
00153 {"goes_to_gw", (cmd_function)goes_to_gw_1, 1, fixup_from_gw, 0,
00154 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE},
00155 {0, 0, 0, 0, 0, 0}
00156 };
00157
00158
00159
00160
00161
00162 static param_export_t params[] = {
00163 {"db_url", STR_PARAM, &db_url.s },
00164 {"drd_table", STR_PARAM, &drd_table.s },
00165 {"drr_table", STR_PARAM, &drr_table.s },
00166 {"drg_table", STR_PARAM, &drg_table.s },
00167 {"drl_table", STR_PARAM, &drl_table.s },
00168 {"use_domain", INT_PARAM, &use_domain },
00169 {"drg_user_col", STR_PARAM, &drg_user_col.s },
00170 {"drg_domain_col", STR_PARAM, &drg_domain_col.s},
00171 {"drg_grpid_col", STR_PARAM, &drg_grpid_col.s },
00172 {"ruri_avp", STR_PARAM, &ruri_avp_spec.s },
00173 {"attrs_avp", STR_PARAM, &attrs_avp_spec.s},
00174 {"sort_order", INT_PARAM, &sort_order },
00175 {"fetch_rows", INT_PARAM, &dr_fetch_rows },
00176 {"force_dns", INT_PARAM, &dr_force_dns },
00177 {0, 0, 0}
00178 };
00179
00180
00181
00182
00183
00184 static mi_export_t mi_cmds[] = {
00185 { RELOAD_MI_CMD, dr_reload_cmd, MI_NO_INPUT_FLAG, 0, 0 },
00186 { 0, 0, 0, 0, 0}
00187 };
00188
00189
00190
00191 struct module_exports exports = {
00192 "drouting",
00193 DEFAULT_DLFLAGS,
00194 cmds,
00195 params,
00196 0,
00197 mi_cmds,
00198 0,
00199 0,
00200 dr_init,
00201 (response_function) 0,
00202 (destroy_function) dr_exit,
00203 (child_init_function) dr_child_init
00204 };
00205
00206
00210 static inline int rewrite_ruri(struct sip_msg* _m, char* _s)
00211 {
00212 struct action act;
00213 struct run_act_ctx ra_ctx;
00214
00215 memset(&act, '\0', sizeof(act));
00216 act.type = SET_URI_T;
00217 act.val[0].type = STRING_ST;
00218 act.val[0].u.string = _s;
00219 init_run_actions_ctx(&ra_ctx);
00220 if (do_action(&ra_ctx, &act, _m) < 0)
00221 {
00222 LM_ERR("do_action failed\n");
00223 return -1;
00224 }
00225 return 0;
00226 }
00227
00228 static inline int dr_reload_data( void )
00229 {
00230 rt_data_t *new_data;
00231 rt_data_t *old_data;
00232
00233 new_data = dr_load_routing_info( &dr_dbf, db_hdl,
00234 &drd_table, &drl_table, &drr_table);
00235 if ( new_data==0 ) {
00236 LM_CRIT("failed to load routing info\n");
00237 return -1;
00238 }
00239
00240
00241 lock_get( ref_lock );
00242 *reload_flag = 1;
00243 lock_release( ref_lock );
00244
00245
00246
00247
00248 while (*data_refcnt) {
00249 usleep(10);
00250 }
00251
00252
00253 old_data = *rdata;
00254 *rdata = new_data;
00255
00256
00257 *reload_flag = 0;
00258
00259
00260 if (old_data)
00261 free_rt_data( old_data, 1 );
00262
00263 return 0;
00264 }
00265
00266
00267
00268 static int dr_init(void)
00269 {
00270 pv_spec_t avp_spec;
00271
00272 LM_INFO("DRouting - initializing\n");
00273
00274 if(register_mi_mod(exports.name, mi_cmds)!=0)
00275 {
00276 LM_ERR("failed to register MI commands\n");
00277 return -1;
00278 }
00279
00280
00281 if (db_url.s==NULL || db_url.s[0]==0) {
00282 LM_CRIT("mandatory parameter \"DB_URL\" found empty\n");
00283 goto error;
00284 }
00285 db_url.len = strlen(db_url.s);
00286
00287 drd_table.len = strlen(drd_table.s);
00288 if (drd_table.s[0]==0) {
00289 LM_CRIT("mandatory parameter \"DRD_TABLE\" found empty\n");
00290 goto error;
00291 }
00292
00293 drr_table.len = strlen(drr_table.s);
00294 if (drr_table.s[0]==0) {
00295 LM_CRIT("mandatory parameter \"DRR_TABLE\" found empty\n");
00296 goto error;
00297 }
00298
00299 drg_table.len = strlen(drg_table.s);
00300 if (drg_table.s[0]==0) {
00301 LM_CRIT("mandatory parameter \"DRG_TABLE\" found empty\n");
00302 goto error;
00303 }
00304
00305 drl_table.len = strlen(drl_table.s);
00306 if (drl_table.s[0]==0) {
00307 LM_CRIT("mandatory parameter \"DRL_TABLE\" found empty\n");
00308 goto error;
00309 }
00310
00311 drg_user_col.len = strlen(drg_user_col.s);
00312 drg_domain_col.len = strlen(drg_domain_col.s);
00313 drg_grpid_col.len = strlen(drg_grpid_col.s);
00314
00315
00316 if (ruri_avp_spec.s) {
00317 ruri_avp_spec.len = strlen(ruri_avp_spec.s);
00318
00319 if (pv_parse_spec( &ruri_avp_spec, &avp_spec)==0
00320 || avp_spec.type!=PVT_AVP) {
00321 LM_ERR("malformed or non AVP [%.*s] for RURI AVP definition\n",
00322 ruri_avp_spec.len, ruri_avp_spec.s);
00323 return E_CFG;
00324 }
00325
00326 if( pv_get_avp_name(0, &(avp_spec.pvp), &(ruri_avp.name),
00327 &(ruri_avp.type) )!=0) {
00328 LM_ERR("[%.*s]- invalid AVP definition for RURI AVP\n",
00329 ruri_avp_spec.len, ruri_avp_spec.s);
00330 return E_CFG;
00331 }
00332 }
00333 if (attrs_avp_spec.s) {
00334 attrs_avp_spec.len = strlen(attrs_avp_spec.s);
00335
00336 if (pv_parse_spec( &attrs_avp_spec, &avp_spec)==0
00337 || avp_spec.type!=PVT_AVP) {
00338 LM_ERR("malformed or non AVP [%.*s] for ATTRS AVP definition\n",
00339 attrs_avp_spec.len, attrs_avp_spec.s);
00340 return E_CFG;
00341 }
00342
00343 if( pv_get_avp_name(0, &(avp_spec.pvp), &(attrs_avp.name),
00344 &(attrs_avp.type) )!=0) {
00345 LM_ERR("[%.*s]- invalid AVP definition for ATTRS AVP\n",
00346 attrs_avp_spec.len, attrs_avp_spec.s);
00347 return E_CFG;
00348 }
00349 }
00350
00351
00352 rdata = (rt_data_t**)shm_malloc( sizeof(rt_data_t*) );
00353 if (rdata==0) {
00354 LM_CRIT("failed to get shm mem for data ptr\n");
00355 goto error;
00356 }
00357 *rdata = 0;
00358
00359
00360 if ( (ref_lock=lock_alloc())==0) {
00361 LM_CRIT("failed to alloc ref_lock\n");
00362 goto error;
00363 }
00364 if (lock_init(ref_lock)==0 ) {
00365 LM_CRIT("failed to init ref_lock\n");
00366 goto error;
00367 }
00368 data_refcnt = (int*)shm_malloc(sizeof(int));
00369 reload_flag = (int*)shm_malloc(sizeof(int));
00370 if(!data_refcnt || !reload_flag)
00371 {
00372 LM_ERR("no more shared memory\n");
00373 goto error;
00374 }
00375 *data_refcnt = 0;
00376 *reload_flag = 0;
00377
00378
00379 if (db_bind_mod( &db_url, &dr_dbf )) {
00380 LM_CRIT("cannot bind to database module! "
00381 "Did you forget to load a database module ?\n");
00382 goto error;
00383 }
00384
00385 if (!DB_CAPABILITY( dr_dbf, DB_CAP_QUERY)) {
00386 LM_CRIT( "database modules does not "
00387 "provide QUERY functions needed by DRounting module\n");
00388 return -1;
00389 }
00390
00391 return 0;
00392 error:
00393 if (ref_lock) {
00394 lock_destroy( ref_lock );
00395 lock_dealloc( ref_lock );
00396 ref_lock = 0;
00397 }
00398 if (db_hdl) {
00399 dr_dbf.close(db_hdl);
00400 db_hdl = 0;
00401 }
00402 if (rdata) {
00403 shm_free(rdata);
00404 rdata = 0;
00405 }
00406 return -1;
00407 }
00408
00409
00410
00411 static int dr_child_init(int rank)
00412 {
00413
00414 if (rank==PROC_MAIN || rank==PROC_TCP_MAIN || rank==PROC_INIT)
00415 return 0;
00416
00417
00418 if ( (db_hdl=dr_dbf.init(&db_url))==0 ) {
00419 LM_CRIT("cannot initialize database connection\n");
00420 return -1;
00421 }
00422
00423
00424 if ( (rank==1) && dr_reload_data()!=0 ) {
00425 LM_CRIT("failed to load routing data\n");
00426 return -1;
00427 }
00428
00429
00430 if (dr_dbf.use_table( db_hdl, &drg_table) < 0) {
00431 LM_ERR("cannot select table \"%.*s\"\n", drg_table.len, drg_table.s);
00432 return -1;
00433 }
00434 srand(getpid()+time(0)+rank);
00435 return 0;
00436 }
00437
00438
00439 static int dr_exit(void)
00440 {
00441
00442 if (db_hdl) {
00443 dr_dbf.close(db_hdl);
00444 db_hdl = 0;
00445 }
00446
00447
00448 if ( rdata) {
00449 if (*rdata)
00450 free_rt_data( *rdata, 1 );
00451 shm_free( rdata );
00452 rdata = 0;
00453 }
00454
00455
00456 if (ref_lock) {
00457 lock_destroy( ref_lock );
00458 lock_dealloc( ref_lock );
00459 ref_lock = 0;
00460 }
00461
00462 if(reload_flag)
00463 shm_free(reload_flag);
00464 if(data_refcnt)
00465 shm_free(data_refcnt);
00466
00467 return 0;
00468 }
00469
00470
00471
00472 static struct mi_root* dr_reload_cmd(struct mi_root *cmd_tree, void *param)
00473 {
00474 int n;
00475
00476 LM_INFO("\"%s\" MI command received!\n",RELOAD_MI_CMD);
00477
00478
00479 if (db_hdl==NULL) {
00480 db_hdl=dr_dbf.init(&db_url);
00481 if(db_hdl==0 ) {
00482 LM_CRIT("cannot initialize database connection\n");
00483 goto error;
00484 }
00485 }
00486
00487 if ( (n=dr_reload_data())!=0 ) {
00488 LM_CRIT("failed to load routing data\n");
00489 goto error;
00490 }
00491
00492 return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00493 error:
00494 return init_mi_tree( 500, "Failed to reload",16);
00495 }
00496
00497
00498
00499 static inline int get_group_id(struct sip_uri *uri)
00500 {
00501 db_key_t keys_ret[1];
00502 db_key_t keys_cmp[2];
00503 db_val_t vals_cmp[2];
00504 db1_res_t* res;
00505 int n;
00506
00507
00508
00509 keys_cmp[0] = &drg_user_col;
00510 vals_cmp[0].type = DB1_STR;
00511 vals_cmp[0].nul = 0;
00512 vals_cmp[0].val.str_val = uri->user;
00513 n = 1;
00514
00515 if (use_domain) {
00516 keys_cmp[1] = &drg_domain_col;
00517 vals_cmp[1].type = DB1_STR;
00518 vals_cmp[1].nul = 0;
00519 vals_cmp[1].val.str_val = uri->host;
00520 n++;
00521 }
00522
00523 keys_ret[0] = &drg_grpid_col;
00524 res = 0;
00525
00526 if ( dr_dbf.query(db_hdl,keys_cmp,0,vals_cmp,keys_ret,n,1,0,&res)<0 ) {
00527 LM_ERR("DB query failed\n");
00528 goto error;
00529 }
00530
00531 if (RES_ROW_N(res) == 0) {
00532 LM_ERR("no group for user "
00533 "\"%.*s\"@\"%.*s\"\n", uri->user.len, uri->user.s,
00534 uri->host.len, uri->host.s);
00535 goto error;
00536 }
00537 if (res->rows[0].values[0].nul || res->rows[0].values[0].type!=DB1_INT) {
00538 LM_ERR("null or non-integer group_id\n");
00539 goto error;
00540 }
00541 n = res->rows[0].values[0].val.int_val;
00542
00543 dr_dbf.free_result(db_hdl, res);
00544 return n;
00545 error:
00546 if (res)
00547 dr_dbf.free_result(db_hdl, res);
00548 return -1;
00549 }
00550
00551
00552
00553 static inline str* build_ruri(struct sip_uri *uri, int strip, str *pri,
00554 str *hostport)
00555 {
00556 static str uri_str;
00557 char *p;
00558
00559 if (uri->user.len<=strip) {
00560 LM_ERR("stripping %d makes "
00561 "username <%.*s> null\n",strip,uri->user.len,uri->user.s);
00562 return 0;
00563 }
00564
00565 uri_str.len = 4 + uri->user.len - strip +pri->len +
00566 (uri->passwd.s?(uri->passwd.len+1):0) + 1 + hostport->len +
00567 (uri->params.s?(uri->params.len+1):0) +
00568 (uri->headers.s?(uri->headers.len+1):0);
00569
00570 if ( (uri_str.s=(char*)pkg_malloc( uri_str.len + 1))==0) {
00571 LM_ERR("no more pkg mem\n");
00572 return 0;
00573 }
00574
00575 p = uri_str.s;
00576 *(p++)='s';
00577 *(p++)='i';
00578 *(p++)='p';
00579 *(p++)=':';
00580 if (pri->len) {
00581 memcpy(p, pri->s, pri->len);
00582 p += pri->len;
00583 }
00584 memcpy(p, uri->user.s+strip, uri->user.len-strip);
00585 p += uri->user.len-strip;
00586 if (uri->passwd.len) {
00587 *(p++)=':';
00588 memcpy(p, uri->passwd.s, uri->passwd.len);
00589 p += uri->passwd.len;
00590 }
00591 *(p++)='@';
00592 memcpy(p, hostport->s, hostport->len);
00593 p += hostport->len;
00594 if (uri->params.len) {
00595 *(p++)=';';
00596 memcpy(p, uri->params.s, uri->params.len);
00597 p += uri->params.len;
00598 }
00599 if (uri->headers.len) {
00600 *(p++)='?';
00601 memcpy(p, uri->headers.s, uri->headers.len);
00602 p += uri->headers.len;
00603 }
00604 *p = 0;
00605
00606 if (p-uri_str.s!=uri_str.len) {
00607 LM_CRIT("difference between allocated(%d)"
00608 " and written(%d)\n",uri_str.len,(int)(long)(p-uri_str.s));
00609 return 0;
00610 }
00611 return &uri_str;
00612 }
00613
00614
00615 static int do_routing_0(struct sip_msg* msg, char* str1, char* str2)
00616 {
00617 return do_routing(msg, NULL);
00618 }
00619
00620 static int do_routing_1(struct sip_msg* msg, char* str1, char* str2)
00621 {
00622 return do_routing(msg, (dr_group_t*)str1);
00623 }
00624
00625
00626 static int use_next_gw(struct sip_msg* msg)
00627 {
00628 struct usr_avp *avp;
00629 int_str val;
00630
00631
00632 do {
00633 avp = search_first_avp(ruri_avp.type, ruri_avp.name, &val, 0);
00634 }while (avp && (avp->flags&AVP_VAL_STR)==0 );
00635
00636 if (!avp) return -1;
00637
00638 if (rewrite_ruri(msg, val.s.s)==-1) {
00639 LM_ERR("failed to rewite RURI\n");
00640 return -1;
00641 }
00642 destroy_avp(avp);
00643 LM_DBG("new RURI set to <%.*s>\n", val.s.len,val.s.s);
00644
00645
00646 avp = NULL;
00647 do {
00648 if (avp) destroy_avp(avp);
00649 avp = search_first_avp(attrs_avp.type, attrs_avp.name, NULL, 0);
00650 }while (avp && (avp->flags&AVP_VAL_STR)==0 );
00651 if (avp) destroy_avp(avp);
00652
00653 return 1;
00654 }
00655
00656
00657 static int do_routing(struct sip_msg* msg, dr_group_t *drg)
00658 {
00659 struct to_body *from;
00660 struct sip_uri uri;
00661 rt_info_t *rt_info;
00662 int grp_id;
00663 int i, j, l, t;
00664 str *ruri;
00665 int_str val;
00666 struct usr_avp *avp;
00667 #define DR_MAX_GWLIST 32
00668 static int local_gwlist[DR_MAX_GWLIST];
00669 int gwlist_size;
00670 int ret;
00671
00672 ret = -1;
00673
00674 if ( (*rdata)==0 || (*rdata)->pgw_l==0 ) {
00675 LM_DBG("empty ruting table\n");
00676 goto error1;
00677 }
00678
00679
00680 if (parse_from_header(msg)!=0) {
00681 LM_ERR("unable to parse from hdr\n");
00682 goto error1;
00683 }
00684 from = (struct to_body*)msg->from->parsed;
00685
00686 if (parse_uri( from->uri.s, from->uri.len, &uri)!=0) {
00687 LM_ERR("unable to parse from uri\n");
00688 goto error1;
00689 }
00690
00691
00692 if(drg==NULL)
00693 {
00694 grp_id = get_group_id( &uri );
00695 if (grp_id<0) {
00696 LM_ERR("failed to get group id\n");
00697 goto error1;
00698 }
00699 } else {
00700 if(drg->type==0)
00701 grp_id = (int)drg->u.grp_id;
00702 else if(drg->type==1) {
00703 grp_id = 0;
00704 if((avp=search_first_avp( drg->u.avp_id.type,
00705 drg->u.avp_id.name, &val, 0))==NULL||(avp->flags&AVP_VAL_STR)) {
00706 LM_ERR( "failed to get group id\n");
00707 goto error1;
00708 }
00709 grp_id = val.n;
00710 } else
00711 grp_id = 0;
00712 }
00713 LM_DBG("using dr group %d\n",grp_id);
00714
00715
00716 ruri = GET_RURI(msg);
00717
00718 if (parse_uri( ruri->s, ruri->len, &uri)!=0) {
00719 LM_ERR("unable to parse RURI\n");
00720 goto error1;
00721 }
00722
00723
00724 again:
00725 lock_get( ref_lock );
00726
00727
00728 if (*reload_flag) {
00729 lock_release( ref_lock );
00730 usleep(5);
00731 goto again;
00732 }
00733 *data_refcnt = *data_refcnt + 1;
00734 lock_release( ref_lock );
00735
00736
00737 rt_info = get_prefix( (*rdata)->pt, &uri.user , (unsigned int)grp_id);
00738 if (rt_info==0) {
00739 LM_DBG("no matching for prefix \"%.*s\"\n",
00740 uri.user.len, uri.user.s);
00741
00742 rt_info = check_rt( &(*rdata)->noprefix, (unsigned int)grp_id);
00743 if (rt_info==0) {
00744 LM_DBG("no prefixless matching for "
00745 "grp %d\n", grp_id);
00746 goto error2;
00747 }
00748 }
00749
00750 if (rt_info->route_idx>0 && rt_info->route_idx<RT_NO) {
00751 ret = run_top_route(main_rt.rlist[rt_info->route_idx], msg, 0);
00752 if (ret<1) {
00753
00754 LM_DBG("script route %d drops routing "
00755 "by %d\n", rt_info->route_idx, ret);
00756 goto error2;
00757 }
00758 ret = -1;
00759 }
00760
00761 gwlist_size
00762 = (rt_info->pgwa_len>DR_MAX_GWLIST)?DR_MAX_GWLIST:rt_info->pgwa_len;
00763
00764
00765 if(sort_order>=1&&gwlist_size>1)
00766 {
00767 j = 0;
00768 t = 0;
00769 while(j<gwlist_size)
00770 {
00771
00772 for(i=j+1; i<gwlist_size; i++)
00773 if(rt_info->pgwl[j].grpid!=rt_info->pgwl[i].grpid)
00774 break;
00775 if(i-j==1)
00776 {
00777 local_gwlist[t++] = j;
00778
00779
00780 } else {
00781 if(i-j==2)
00782 {
00783 local_gwlist[t++] = j + rand()%2;
00784 if(sort_order==1)
00785 {
00786 local_gwlist[t++] = j + (local_gwlist[j]-j+1)%2;
00787
00788
00789
00790 }
00791 } else {
00792 local_gwlist[t++] = j + rand()%(i-j);
00793 if(sort_order==1)
00794 {
00795 do{
00796 local_gwlist[t] = j + rand()%(i-j);
00797 }while(local_gwlist[t]==local_gwlist[t-1]);
00798 t++;
00799
00800
00801
00802
00803
00804
00805 for(l=j; l<i; l++)
00806 {
00807 if(l==local_gwlist[j] || l==local_gwlist[j+1])
00808 continue;
00809 local_gwlist[t++] = l;
00810
00811
00812 }
00813 }
00814 }
00815 }
00816
00817 j=i;
00818 }
00819 } else {
00820 for(i=0; i<gwlist_size; i++)
00821 local_gwlist[i] = i;
00822 t = i;
00823 }
00824
00825
00826 destroy_avps( ruri_avp.type, ruri_avp.name, 1);
00827
00828
00829 for( j=t-1 ; j>=1 ; j-- ) {
00830
00831 ruri = build_ruri(&uri, rt_info->pgwl[local_gwlist[j]].pgw->strip,
00832 &rt_info->pgwl[local_gwlist[j]].pgw->pri,
00833 &rt_info->pgwl[local_gwlist[j]].pgw->ip);
00834 if (ruri==0) {
00835 LM_ERR("failed to build avp ruri\n");
00836 goto error2;
00837 }
00838 LM_DBG("adding gw [%d] as avp \"%.*s\"\n",
00839 local_gwlist[j], ruri->len, ruri->s);
00840
00841 val.s = *ruri;
00842 if (add_avp( AVP_VAL_STR|(ruri_avp.type),ruri_avp.name, val)!=0 ) {
00843 LM_ERR("failed to insert ruri avp\n");
00844 pkg_free(ruri->s);
00845 goto error2;
00846 }
00847 pkg_free(ruri->s);
00848
00849 val.s = rt_info->pgwl[local_gwlist[j]].pgw->attrs;
00850 LM_DBG("setting attr [%.*s] as avp\n",val.s.len,val.s.s);
00851 if (add_avp( AVP_VAL_STR|(attrs_avp.type),attrs_avp.name, val)!=0 ) {
00852 LM_ERR("failed to insert attrs avp\n");
00853 goto error2;
00854 }
00855 }
00856
00857
00858 ruri = build_ruri(&uri, rt_info->pgwl[local_gwlist[0]].pgw->strip,
00859 &rt_info->pgwl[local_gwlist[0]].pgw->pri,
00860 &rt_info->pgwl[local_gwlist[0]].pgw->ip);
00861
00862
00863 val.s = rt_info->pgwl[local_gwlist[0]].pgw->attrs;
00864 LM_DBG("setting attr [%.*s] as for ruri\n",val.s.len,val.s.s);
00865 if (add_avp( AVP_VAL_STR|(attrs_avp.type),attrs_avp.name, val)!=0 ) {
00866 LM_ERR("failed to insert attrs avp\n");
00867 goto error2;
00868 }
00869
00870
00871 lock_get( ref_lock );
00872 *data_refcnt = *data_refcnt - 1;
00873 lock_release( ref_lock );
00874
00875
00876 if (ruri==0) {
00877 LM_ERR("failed to build ruri\n");
00878 goto error1;
00879 }
00880 LM_DBG("setting the gw [%d] as ruri \"%.*s\"\n",
00881 local_gwlist[0], ruri->len, ruri->s);
00882 if (msg->new_uri.s)
00883 pkg_free(msg->new_uri.s);
00884 msg->new_uri = *ruri;
00885 msg->parsed_uri_ok = 0;
00886 ruri_mark_new();
00887
00888 return 1;
00889 error2:
00890
00891 lock_get( ref_lock );
00892 *data_refcnt = *data_refcnt - 1;
00893 lock_release( ref_lock );
00894 error1:
00895 return ret;
00896 }
00897
00898
00899 static int fixup_do_routing(void** param, int param_no)
00900 {
00901 char *s;
00902 dr_group_t *drg;
00903 pv_spec_t avp_spec;
00904 str r;
00905
00906 s = (char*)*param;
00907
00908 if (param_no==1)
00909 {
00910 drg = (dr_group_t*)pkg_malloc(sizeof(dr_group_t));
00911 if(drg==NULL)
00912 {
00913 LM_ERR( "no more memory\n");
00914 return E_OUT_OF_MEM;
00915 }
00916 memset(drg, 0, sizeof(dr_group_t));
00917
00918 if ( s==NULL || s[0]==0 ) {
00919 LM_CRIT("empty group id definition");
00920 return E_CFG;
00921 }
00922
00923 if (s[0]=='$') {
00924
00925 r.s = s;
00926 r.len = strlen(s);
00927 if (pv_parse_spec( &r, &avp_spec)==0
00928 || avp_spec.type!=PVT_AVP) {
00929 LM_ERR("malformed or non AVP %s AVP definition\n", s);
00930 return E_CFG;
00931 }
00932
00933 if( pv_get_avp_name(0, &(avp_spec.pvp), &(drg->u.avp_id.name),
00934 &(drg->u.avp_id.type) )!=0) {
00935 LM_ERR("[%s]- invalid AVP definition\n", s);
00936 return E_CFG;
00937 }
00938 drg->type = 1;
00939
00940
00941 } else {
00942 while(s && *s) {
00943 if(*s<'0' || *s>'9') {
00944 LM_ERR( "bad number\n");
00945 return E_UNSPEC;
00946 }
00947 drg->u.grp_id = (drg->u.grp_id)*10+(*s-'0');
00948 s++;
00949 }
00950 pkg_free(*param);
00951 }
00952 *param = (void*)drg;
00953 }
00954
00955 return 0;
00956 }
00957
00958
00959 static int fixup_from_gw( void** param, int param_no)
00960 {
00961 unsigned long type;
00962 int err;
00963
00964 if (param_no == 1 || param_no == 2) {
00965 type = str2s(*param, strlen(*param), &err);
00966 if (err == 0) {
00967 pkg_free(*param);
00968 *param = (void *)type;
00969 return 0;
00970 } else {
00971 LM_ERR( "bad number <%s>\n",
00972 (char *)(*param));
00973 return E_CFG;
00974 }
00975 }
00976 return 0;
00977 }
00978
00979 static int strip_username(struct sip_msg* msg, int strip)
00980 {
00981 struct action act;
00982 struct run_act_ctx ra_ctx;
00983
00984 act.type = STRIP_T;
00985 act.val[0].type = NUMBER_ST;
00986 act.val[0].u.number = strip;
00987 act.next = 0;
00988
00989 init_run_actions_ctx(&ra_ctx);
00990 if (do_action(&ra_ctx, &act, msg) < 0)
00991 {
00992 LM_ERR( "Error in do_action\n");
00993 return -1;
00994 }
00995 return 0;
00996 }
00997
00998
00999 static int is_from_gw_0(struct sip_msg* msg, char* str, char* str2)
01000 {
01001 pgw_addr_t *pgwa = NULL;
01002
01003 if(rdata==NULL || *rdata==NULL || msg==NULL)
01004 return -1;
01005
01006 pgwa = (*rdata)->pgw_addr_l;
01007 while(pgwa) {
01008 if( (pgwa->port==0 || pgwa->port==msg->rcv.src_port) &&
01009 ip_addr_cmp(&pgwa->ip, &msg->rcv.src_ip))
01010 return 1;
01011 pgwa = pgwa->next;
01012 }
01013 return -1;
01014 }
01015
01016
01017 static int is_from_gw_1(struct sip_msg* msg, char* str, char* str2)
01018 {
01019 pgw_addr_t *pgwa = NULL;
01020 int type = (int)(long)str;
01021
01022 if(rdata==NULL || *rdata==NULL || msg==NULL)
01023 return -1;
01024
01025 pgwa = (*rdata)->pgw_addr_l;
01026 while(pgwa) {
01027 if( type==pgwa->type &&
01028 (pgwa->port==0 || pgwa->port==msg->rcv.src_port) &&
01029 ip_addr_cmp(&pgwa->ip, &msg->rcv.src_ip) )
01030 return 1;
01031 pgwa = pgwa->next;
01032 }
01033 return -1;
01034 }
01035
01036 static int is_from_gw_2(struct sip_msg* msg, char* str1, char* str2)
01037 {
01038 pgw_addr_t *pgwa = NULL;
01039 int type = (int)(long)str1;
01040 int flags = (int)(long)str2;
01041
01042 if(rdata==NULL || *rdata==NULL || msg==NULL)
01043 return -1;
01044
01045 pgwa = (*rdata)->pgw_addr_l;
01046 while(pgwa) {
01047 if( type==pgwa->type &&
01048 (pgwa->port==0 || pgwa->port==msg->rcv.src_port) &&
01049 ip_addr_cmp(&pgwa->ip, &msg->rcv.src_ip) ) {
01050 if (flags!=0 && pgwa->strip>0)
01051 strip_username(msg, pgwa->strip);
01052 return 1;
01053 }
01054 pgwa = pgwa->next;
01055 }
01056 return -1;
01057 }
01058
01059
01060 static int goes_to_gw_1(struct sip_msg* msg, char* _type, char* _f2)
01061 {
01062 pgw_addr_t *pgwa = NULL;
01063 struct sip_uri puri;
01064 struct ip_addr *ip;
01065 str *uri;
01066 int type;
01067
01068 if(rdata==NULL || *rdata==NULL || msg==NULL)
01069 return -1;
01070
01071 uri = GET_NEXT_HOP(msg);
01072 type = (int)(long)_type;
01073
01074 if (parse_uri(uri->s, uri->len, &puri)<0){
01075 LM_ERR("bad uri <%.*s>\n", uri->len, uri->s);
01076 return -1;
01077 }
01078
01079 if ( ((ip=str2ip(&puri.host))!=0)
01080 #ifdef USE_IPV6
01081 || ((ip=str2ip6(&puri.host))!=0)
01082 #endif
01083 ){
01084 pgwa = (*rdata)->pgw_addr_l;
01085 while(pgwa) {
01086 if( (type<0 || type==pgwa->type) && ip_addr_cmp(&pgwa->ip, ip))
01087 return 1;
01088 pgwa = pgwa->next;
01089 }
01090 }
01091
01092 return -1;
01093 }
01094
01095
01096 static int goes_to_gw_0(struct sip_msg* msg, char* _type, char* _f2)
01097 {
01098 return goes_to_gw_1(msg, (char*)(long)-1, _f2);
01099 }
01100