drouting.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2005-2009 Voice Sistem SRL
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Kamailio is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * Kamailio is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  21. * History:
  22. * ---------
  23. * 2005-02-20 first version (cristian)
  24. * 2005-02-27 ported to 0.9.0 (bogdan)
  25. */
  26. #include "stdlib.h"
  27. #include "stdio.h"
  28. #include "assert.h"
  29. #include <unistd.h>
  30. #include "../../sr_module.h"
  31. #include "../../str.h"
  32. #include "../../dprint.h"
  33. #include "../../usr_avp.h"
  34. #include "../../lib/srdb1/db.h"
  35. #include "../../mem/mem.h"
  36. #include "../../mem/shm_mem.h"
  37. #include "../../locking.h"
  38. #include "../../action.h"
  39. #include "../../error.h"
  40. #include "../../ut.h"
  41. #include "../../resolve.h"
  42. #include "../../parser/parse_from.h"
  43. #include "../../parser/parse_uri.h"
  44. #include "../../dset.h"
  45. #include "../../rpc_lookup.h"
  46. #include "dr_load.h"
  47. #include "prefix_tree.h"
  48. #include "routing.h"
  49. /*** DB relatede stuff ***/
  50. /* parameters */
  51. static str db_url = {NULL,0};
  52. static str drg_table = str_init("dr_groups");
  53. static str drd_table = str_init("dr_gateways");
  54. static str drr_table = str_init("dr_rules");
  55. static str drl_table = str_init("dr_gw_lists");
  56. /* DRG use domain */
  57. static int use_domain = 1;
  58. /**
  59. * - 0 - normal order
  60. * - 1 - random order, full set
  61. * - 2 - random order, one per set
  62. */
  63. static int sort_order = 0;
  64. int dr_fetch_rows = 1000;
  65. int dr_force_dns = 1;
  66. /* DRG table columns */
  67. static str drg_user_col = str_init("username");
  68. static str drg_domain_col = str_init("domain");
  69. static str drg_grpid_col = str_init("groupid");
  70. /* variables */
  71. static db1_con_t *db_hdl=0; /* DB handler */
  72. static db_func_t dr_dbf; /* DB functions */
  73. /* current dr data - pointer to a pointer in shm */
  74. static rt_data_t **rdata = 0;
  75. /* AVP used to store serial RURIs */
  76. static struct _ruri_avp{
  77. unsigned short type; /* AVP ID */
  78. int_str name; /* AVP name*/
  79. }ruri_avp = { 0, {.n=(int)0xad346b2f} };
  80. static str ruri_avp_spec = {0,0};
  81. /* AVP used to store serial ATTRs */
  82. static struct _attrs_avp{
  83. unsigned short type; /* AVP ID */
  84. int_str name; /* AVP name*/
  85. }attrs_avp = { 0, {.n=(int)0xad346b30} };
  86. static str attrs_avp_spec = {0,0};
  87. /* statistic data */
  88. int tree_size = 0;
  89. int inode = 0;
  90. int unode = 0;
  91. /* lock, ref counter and flag used for reloading the date */
  92. static gen_lock_t *ref_lock = 0;
  93. static int* data_refcnt = 0;
  94. static int* reload_flag = 0;
  95. static int dr_init(void);
  96. static int dr_child_init(int rank);
  97. static int dr_exit(void);
  98. static int fixup_do_routing(void** param, int param_no);
  99. static int fixup_from_gw(void** param, int param_no);
  100. static int do_routing(struct sip_msg* msg, dr_group_t *drg);
  101. static int do_routing_0(struct sip_msg* msg, char* str1, char* str2);
  102. static int do_routing_1(struct sip_msg* msg, char* str1, char* str2);
  103. static int use_next_gw(struct sip_msg* msg);
  104. static int is_from_gw_0(struct sip_msg* msg, char* str1, char* str2);
  105. static int is_from_gw_1(struct sip_msg* msg, char* str1, char* str2);
  106. static int is_from_gw_2(struct sip_msg* msg, char* str1, char* str2);
  107. static int goes_to_gw_0(struct sip_msg* msg, char* f1, char* f2);
  108. static int goes_to_gw_1(struct sip_msg* msg, char* f1, char* f2);
  109. MODULE_VERSION
  110. /*
  111. * Exported functions
  112. */
  113. static cmd_export_t cmds[] = {
  114. {"do_routing", (cmd_function)do_routing_0, 0, 0, 0,
  115. REQUEST_ROUTE|FAILURE_ROUTE},
  116. {"do_routing", (cmd_function)do_routing_1, 1, fixup_do_routing, 0,
  117. REQUEST_ROUTE|FAILURE_ROUTE},
  118. {"use_next_gw", (cmd_function)use_next_gw, 0, 0, 0,
  119. REQUEST_ROUTE|FAILURE_ROUTE},
  120. {"next_routing", (cmd_function)use_next_gw, 0, 0, 0,
  121. FAILURE_ROUTE},
  122. {"is_from_gw", (cmd_function)is_from_gw_0, 0, 0, 0,
  123. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE},
  124. {"is_from_gw", (cmd_function)is_from_gw_1, 1, fixup_from_gw, 0,
  125. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE},
  126. {"is_from_gw", (cmd_function)is_from_gw_2, 2, fixup_from_gw, 0,
  127. REQUEST_ROUTE},
  128. {"goes_to_gw", (cmd_function)goes_to_gw_0, 0, 0, 0,
  129. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE},
  130. {"goes_to_gw", (cmd_function)goes_to_gw_1, 1, fixup_from_gw, 0,
  131. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE},
  132. {0, 0, 0, 0, 0, 0}
  133. };
  134. /*
  135. * Exported parameters
  136. */
  137. static param_export_t params[] = {
  138. {"db_url", PARAM_STR, &db_url },
  139. {"drd_table", PARAM_STR, &drd_table },
  140. {"drr_table", PARAM_STR, &drr_table },
  141. {"drg_table", PARAM_STR, &drg_table },
  142. {"drl_table", PARAM_STR, &drl_table },
  143. {"use_domain", INT_PARAM, &use_domain },
  144. {"drg_user_col", PARAM_STR, &drg_user_col },
  145. {"drg_domain_col", PARAM_STR, &drg_domain_col},
  146. {"drg_grpid_col", PARAM_STR, &drg_grpid_col },
  147. {"ruri_avp", PARAM_STR, &ruri_avp_spec },
  148. {"attrs_avp", PARAM_STR, &attrs_avp_spec},
  149. {"sort_order", INT_PARAM, &sort_order },
  150. {"fetch_rows", INT_PARAM, &dr_fetch_rows },
  151. {"force_dns", INT_PARAM, &dr_force_dns },
  152. {0, 0, 0}
  153. };
  154. static rpc_export_t rpc_methods[];
  155. struct module_exports exports = {
  156. "drouting",
  157. DEFAULT_DLFLAGS, /* dlopen flags */
  158. cmds, /* Exported functions */
  159. params, /* Exported parameters */
  160. NULL, /* exported statistics */
  161. NULL, /* exported MI functions */
  162. NULL, /* exported pseudo-variables */
  163. 0, /* additional processes */
  164. dr_init, /* Module initialization function */
  165. (response_function) NULL,
  166. (destroy_function) dr_exit,
  167. (child_init_function) dr_child_init /* per-child init function */
  168. };
  169. /**
  170. * Rewrite Request-URI
  171. */
  172. static inline int rewrite_ruri(struct sip_msg* _m, char* _s)
  173. {
  174. struct action act;
  175. struct run_act_ctx ra_ctx;
  176. memset(&act, '\0', sizeof(act));
  177. act.type = SET_URI_T;
  178. act.val[0].type = STRING_ST;
  179. act.val[0].u.string = _s;
  180. init_run_actions_ctx(&ra_ctx);
  181. if (do_action(&ra_ctx, &act, _m) < 0)
  182. {
  183. LM_ERR("do_action failed\n");
  184. return -1;
  185. }
  186. return 0;
  187. }
  188. static inline int dr_reload_data( void )
  189. {
  190. rt_data_t *new_data;
  191. rt_data_t *old_data;
  192. new_data = dr_load_routing_info( &dr_dbf, db_hdl,
  193. &drd_table, &drl_table, &drr_table);
  194. if ( new_data==0 ) {
  195. LM_CRIT("failed to load routing info\n");
  196. return -1;
  197. }
  198. /* block access to data for all readers */
  199. lock_get( ref_lock );
  200. *reload_flag = 1;
  201. lock_release( ref_lock );
  202. /* wait for all readers to finish - it's a kind of busy waitting but
  203. * it's not critical;
  204. * at this point, data_refcnt can only be decremented */
  205. while (*data_refcnt) {
  206. usleep(10);
  207. }
  208. /* no more activ readers -> do the swapping */
  209. old_data = *rdata;
  210. *rdata = new_data;
  211. /* release the readers */
  212. *reload_flag = 0;
  213. /* destroy old data */
  214. if (old_data)
  215. free_rt_data( old_data, 1 );
  216. return 0;
  217. }
  218. static int dr_init(void)
  219. {
  220. pv_spec_t avp_spec;
  221. LM_INFO("DRouting - initializing\n");
  222. if (rpc_register_array(rpc_methods)!=0) {
  223. LM_ERR("failed to register RPC commands\n");
  224. return -1;
  225. }
  226. /* check the module params */
  227. if (db_url.s==NULL || db_url.len<=0) {
  228. LM_CRIT("mandatory parameter \"DB_URL\" found empty\n");
  229. goto error;
  230. }
  231. if (drd_table.len<=0) {
  232. LM_CRIT("mandatory parameter \"DRD_TABLE\" found empty\n");
  233. goto error;
  234. }
  235. if (drr_table.len<=0) {
  236. LM_CRIT("mandatory parameter \"DRR_TABLE\" found empty\n");
  237. goto error;
  238. }
  239. if (drg_table.len<=0) {
  240. LM_CRIT("mandatory parameter \"DRG_TABLE\" found empty\n");
  241. goto error;
  242. }
  243. if (drl_table.len<=0) {
  244. LM_CRIT("mandatory parameter \"DRL_TABLE\" found empty\n");
  245. goto error;
  246. }
  247. /* fix AVP spec */
  248. if (ruri_avp_spec.s) {
  249. if (pv_parse_spec( &ruri_avp_spec, &avp_spec)==0
  250. || avp_spec.type!=PVT_AVP) {
  251. LM_ERR("malformed or non AVP [%.*s] for RURI AVP definition\n",
  252. ruri_avp_spec.len, ruri_avp_spec.s);
  253. return E_CFG;
  254. }
  255. if( pv_get_avp_name(0, &(avp_spec.pvp), &(ruri_avp.name),
  256. &(ruri_avp.type) )!=0) {
  257. LM_ERR("[%.*s]- invalid AVP definition for RURI AVP\n",
  258. ruri_avp_spec.len, ruri_avp_spec.s);
  259. return E_CFG;
  260. }
  261. }
  262. if (attrs_avp_spec.s) {
  263. if (pv_parse_spec( &attrs_avp_spec, &avp_spec)==0
  264. || avp_spec.type!=PVT_AVP) {
  265. LM_ERR("malformed or non AVP [%.*s] for ATTRS AVP definition\n",
  266. attrs_avp_spec.len, attrs_avp_spec.s);
  267. return E_CFG;
  268. }
  269. if( pv_get_avp_name(0, &(avp_spec.pvp), &(attrs_avp.name),
  270. &(attrs_avp.type) )!=0) {
  271. LM_ERR("[%.*s]- invalid AVP definition for ATTRS AVP\n",
  272. attrs_avp_spec.len, attrs_avp_spec.s);
  273. return E_CFG;
  274. }
  275. }
  276. /* data pointer in shm */
  277. rdata = (rt_data_t**)shm_malloc( sizeof(rt_data_t*) );
  278. if (rdata==0) {
  279. LM_CRIT("failed to get shm mem for data ptr\n");
  280. goto error;
  281. }
  282. *rdata = 0;
  283. /* create & init lock */
  284. if ( (ref_lock=lock_alloc())==0) {
  285. LM_CRIT("failed to alloc ref_lock\n");
  286. goto error;
  287. }
  288. if (lock_init(ref_lock)==0 ) {
  289. LM_CRIT("failed to init ref_lock\n");
  290. goto error;
  291. }
  292. data_refcnt = (int*)shm_malloc(sizeof(int));
  293. reload_flag = (int*)shm_malloc(sizeof(int));
  294. if(!data_refcnt || !reload_flag)
  295. {
  296. LM_ERR("no more shared memory\n");
  297. goto error;
  298. }
  299. *data_refcnt = 0;
  300. *reload_flag = 0;
  301. /* bind to the mysql module */
  302. if (db_bind_mod( &db_url, &dr_dbf )) {
  303. LM_CRIT("cannot bind to database module! "
  304. "Did you forget to load a database module ?\n");
  305. goto error;
  306. }
  307. if (!DB_CAPABILITY( dr_dbf, DB_CAP_QUERY)) {
  308. LM_CRIT( "database modules does not "
  309. "provide QUERY functions needed by DRounting module\n");
  310. return -1;
  311. }
  312. return 0;
  313. error:
  314. if (ref_lock) {
  315. lock_destroy( ref_lock );
  316. lock_dealloc( ref_lock );
  317. ref_lock = 0;
  318. }
  319. if (db_hdl) {
  320. dr_dbf.close(db_hdl);
  321. db_hdl = 0;
  322. }
  323. if (rdata) {
  324. shm_free(rdata);
  325. rdata = 0;
  326. }
  327. return -1;
  328. }
  329. static int dr_child_init(int rank)
  330. {
  331. /* only workers needs DB connection */
  332. if (rank==PROC_MAIN || rank==PROC_TCP_MAIN || rank==PROC_INIT)
  333. return 0;
  334. /* init DB connection */
  335. if ( (db_hdl=dr_dbf.init(&db_url))==0 ) {
  336. LM_CRIT("cannot initialize database connection\n");
  337. return -1;
  338. }
  339. /* child 1 load the routing info */
  340. if ( (rank==1) && dr_reload_data()!=0 ) {
  341. LM_CRIT("failed to load routing data\n");
  342. return -1;
  343. }
  344. /* set GROUP table for workers */
  345. if (dr_dbf.use_table( db_hdl, &drg_table) < 0) {
  346. LM_ERR("cannot select table \"%.*s\"\n", drg_table.len, drg_table.s);
  347. return -1;
  348. }
  349. srand(getpid()+time(0)+rank);
  350. return 0;
  351. }
  352. static int dr_exit(void)
  353. {
  354. /* close DB connection */
  355. if (db_hdl) {
  356. dr_dbf.close(db_hdl);
  357. db_hdl = 0;
  358. }
  359. /* destroy data */
  360. if ( rdata) {
  361. if (*rdata)
  362. free_rt_data( *rdata, 1 );
  363. shm_free( rdata );
  364. rdata = 0;
  365. }
  366. /* destroy lock */
  367. if (ref_lock) {
  368. lock_destroy( ref_lock );
  369. lock_dealloc( ref_lock );
  370. ref_lock = 0;
  371. }
  372. if(reload_flag)
  373. shm_free(reload_flag);
  374. if(data_refcnt)
  375. shm_free(data_refcnt);
  376. return 0;
  377. }
  378. /* rpc function documentation */
  379. static const char *rpc_reload_doc[2] = {
  380. "Write back to disk modified tables", 0
  381. };
  382. /* rpc function implementations */
  383. static void rpc_reload(rpc_t *rpc, void *c)
  384. {
  385. int n;
  386. LM_INFO("RPC command received!\n");
  387. /* init DB connection if needed */
  388. if (db_hdl==NULL) {
  389. db_hdl=dr_dbf.init(&db_url);
  390. if(db_hdl==0 ) {
  391. rpc->rpl_printf(c, "cannot initialize database connection");
  392. return;
  393. }
  394. }
  395. if ( (n=dr_reload_data())!=0 ) {
  396. rpc->rpl_printf(c, "failed to load routing data");
  397. return;
  398. }
  399. rpc->rpl_printf(c, "relaad OK");
  400. return;
  401. }
  402. static rpc_export_t rpc_methods[] = {
  403. {"drouting.reload", rpc_reload, rpc_reload_doc, 0},
  404. {0, 0, 0, 0}
  405. };
  406. static inline int get_group_id(struct sip_uri *uri)
  407. {
  408. db_key_t keys_ret[1];
  409. db_key_t keys_cmp[2];
  410. db_val_t vals_cmp[2];
  411. db1_res_t* res;
  412. int n;
  413. /* user */
  414. keys_cmp[0] = &drg_user_col;
  415. vals_cmp[0].type = DB1_STR;
  416. vals_cmp[0].nul = 0;
  417. vals_cmp[0].val.str_val = uri->user;
  418. n = 1;
  419. if (use_domain) {
  420. keys_cmp[1] = &drg_domain_col;
  421. vals_cmp[1].type = DB1_STR;
  422. vals_cmp[1].nul = 0;
  423. vals_cmp[1].val.str_val = uri->host;
  424. n++;
  425. }
  426. keys_ret[0] = &drg_grpid_col;
  427. res = 0;
  428. if ( dr_dbf.query(db_hdl,keys_cmp,0,vals_cmp,keys_ret,n,1,0,&res)<0 ) {
  429. LM_ERR("DB query failed\n");
  430. goto error;
  431. }
  432. if (RES_ROW_N(res) == 0) {
  433. LM_ERR("no group for user "
  434. "\"%.*s\"@\"%.*s\"\n", uri->user.len, uri->user.s,
  435. uri->host.len, uri->host.s);
  436. goto error;
  437. }
  438. if (res->rows[0].values[0].nul || res->rows[0].values[0].type!=DB1_INT) {
  439. LM_ERR("null or non-integer group_id\n");
  440. goto error;
  441. }
  442. n = res->rows[0].values[0].val.int_val;
  443. dr_dbf.free_result(db_hdl, res);
  444. return n;
  445. error:
  446. if (res)
  447. dr_dbf.free_result(db_hdl, res);
  448. return -1;
  449. }
  450. static inline str* build_ruri(struct sip_uri *uri, int strip, str *pri,
  451. str *hostport)
  452. {
  453. static str uri_str;
  454. char *p;
  455. if (uri->user.len<=strip) {
  456. LM_ERR("stripping %d makes "
  457. "username <%.*s> null\n",strip,uri->user.len,uri->user.s);
  458. return 0;
  459. }
  460. uri_str.len = 4 /*sip:*/ + uri->user.len - strip +pri->len +
  461. (uri->passwd.s?(uri->passwd.len+1):0) + 1/*@*/ + hostport->len +
  462. (uri->params.s?(uri->params.len+1):0) +
  463. (uri->headers.s?(uri->headers.len+1):0);
  464. if ( (uri_str.s=(char*)pkg_malloc( uri_str.len + 1))==0) {
  465. LM_ERR("no more pkg mem\n");
  466. return 0;
  467. }
  468. p = uri_str.s;
  469. *(p++)='s';
  470. *(p++)='i';
  471. *(p++)='p';
  472. *(p++)=':';
  473. if (pri->len) {
  474. memcpy(p, pri->s, pri->len);
  475. p += pri->len;
  476. }
  477. memcpy(p, uri->user.s+strip, uri->user.len-strip);
  478. p += uri->user.len-strip;
  479. if (uri->passwd.len) {
  480. *(p++)=':';
  481. memcpy(p, uri->passwd.s, uri->passwd.len);
  482. p += uri->passwd.len;
  483. }
  484. *(p++)='@';
  485. memcpy(p, hostport->s, hostport->len);
  486. p += hostport->len;
  487. if (uri->params.len) {
  488. *(p++)=';';
  489. memcpy(p, uri->params.s, uri->params.len);
  490. p += uri->params.len;
  491. }
  492. if (uri->headers.len) {
  493. *(p++)='?';
  494. memcpy(p, uri->headers.s, uri->headers.len);
  495. p += uri->headers.len;
  496. }
  497. *p = 0;
  498. if (p-uri_str.s!=uri_str.len) {
  499. LM_CRIT("difference between allocated(%d)"
  500. " and written(%d)\n",uri_str.len,(int)(long)(p-uri_str.s));
  501. return 0;
  502. }
  503. return &uri_str;
  504. }
  505. static int do_routing_0(struct sip_msg* msg, char* str1, char* str2)
  506. {
  507. return do_routing(msg, NULL);
  508. }
  509. static int do_routing_1(struct sip_msg* msg, char* str1, char* str2)
  510. {
  511. return do_routing(msg, (dr_group_t*)str1);
  512. }
  513. static int use_next_gw(struct sip_msg* msg)
  514. {
  515. struct usr_avp *avp;
  516. int_str val;
  517. /* search for the first RURI AVP containing a string */
  518. do {
  519. avp = search_first_avp(ruri_avp.type, ruri_avp.name, &val, 0);
  520. }while (avp && (avp->flags&AVP_VAL_STR)==0 );
  521. if (!avp) return -1;
  522. if (rewrite_ruri(msg, val.s.s)==-1) {
  523. LM_ERR("failed to rewite RURI\n");
  524. return -1;
  525. }
  526. destroy_avp(avp);
  527. LM_DBG("new RURI set to <%.*s>\n", val.s.len,val.s.s);
  528. /* remove the old attrs */
  529. avp = NULL;
  530. do {
  531. if (avp) destroy_avp(avp);
  532. avp = search_first_avp(attrs_avp.type, attrs_avp.name, NULL, 0);
  533. }while (avp && (avp->flags&AVP_VAL_STR)==0 );
  534. if (avp) destroy_avp(avp);
  535. return 1;
  536. }
  537. int dr_already_choosen(rt_info_t* rt_info, int* local_gwlist, int lgw_size, int check)
  538. {
  539. int l;
  540. for ( l = 0; l<lgw_size; l++ ) {
  541. if ( rt_info->pgwl[local_gwlist[l]].pgw == rt_info->pgwl[check].pgw ) {
  542. LM_INFO("Gateway already chosen %.*s, local_gwlist[%d]=%d, %d\n",
  543. rt_info->pgwl[check].pgw->ip.len, rt_info->pgwl[check].pgw->ip.s, l, local_gwlist[l], check);
  544. return 1;
  545. }
  546. }
  547. return 0;
  548. }
  549. static int do_routing(struct sip_msg* msg, dr_group_t *drg)
  550. {
  551. struct to_body *from;
  552. struct sip_uri uri;
  553. rt_info_t *rt_info;
  554. int grp_id;
  555. int i, j, l, t;
  556. str *ruri;
  557. int_str val;
  558. struct usr_avp *avp;
  559. #define DR_MAX_GWLIST 32
  560. static int local_gwlist[DR_MAX_GWLIST];
  561. int gwlist_size;
  562. int ret;
  563. ret = -1;
  564. if ( (*rdata)==0 || (*rdata)->pgw_l==0 ) {
  565. LM_DBG("empty ruting table\n");
  566. goto error1;
  567. }
  568. /* get the username from FROM_HDR */
  569. if (parse_from_header(msg)!=0) {
  570. LM_ERR("unable to parse from hdr\n");
  571. goto error1;
  572. }
  573. from = (struct to_body*)msg->from->parsed;
  574. /* parse uri */
  575. if (parse_uri( from->uri.s, from->uri.len, &uri)!=0) {
  576. LM_ERR("unable to parse from uri\n");
  577. goto error1;
  578. }
  579. /* get user's routing group */
  580. if(drg==NULL)
  581. {
  582. grp_id = get_group_id( &uri );
  583. if (grp_id<0) {
  584. LM_ERR("failed to get group id\n");
  585. goto error1;
  586. }
  587. } else {
  588. if(drg->type==0)
  589. grp_id = (int)drg->u.grp_id;
  590. else if(drg->type==1) {
  591. grp_id = 0; /* call get avp here */
  592. if((avp=search_first_avp( drg->u.avp_id.type,
  593. drg->u.avp_id.name, &val, 0))==NULL||(avp->flags&AVP_VAL_STR)) {
  594. LM_ERR( "failed to get group id\n");
  595. goto error1;
  596. }
  597. grp_id = val.n;
  598. } else
  599. grp_id = 0;
  600. }
  601. LM_DBG("using dr group %d\n",grp_id);
  602. /* get the number */
  603. ruri = GET_RURI(msg);
  604. /* parse ruri */
  605. if (parse_uri( ruri->s, ruri->len, &uri)!=0) {
  606. LM_ERR("unable to parse RURI\n");
  607. goto error1;
  608. }
  609. /* ref the data for reading */
  610. again:
  611. lock_get( ref_lock );
  612. /* if reload must be done, do un ugly busy waiting
  613. * until reload is finished */
  614. if (*reload_flag) {
  615. lock_release( ref_lock );
  616. usleep(5);
  617. goto again;
  618. }
  619. *data_refcnt = *data_refcnt + 1;
  620. lock_release( ref_lock );
  621. /* search a prefix */
  622. rt_info = get_prefix( (*rdata)->pt, &uri.user , (unsigned int)grp_id);
  623. if (rt_info==0) {
  624. LM_DBG("no matching for prefix \"%.*s\"\n",
  625. uri.user.len, uri.user.s);
  626. /* try prefixless rules */
  627. rt_info = check_rt( &(*rdata)->noprefix, (unsigned int)grp_id);
  628. if (rt_info==0) {
  629. LM_DBG("no prefixless matching for "
  630. "grp %d\n", grp_id);
  631. goto error2;
  632. }
  633. }
  634. if (rt_info->route_idx>0 && main_rt.rlist[rt_info->route_idx]!=NULL) {
  635. ret = run_top_route(main_rt.rlist[rt_info->route_idx], msg, 0);
  636. if (ret<1) {
  637. /* drop the action */
  638. LM_DBG("script route %d drops routing "
  639. "by %d\n", rt_info->route_idx, ret);
  640. goto error2;
  641. }
  642. ret = -1;
  643. }
  644. gwlist_size
  645. = (rt_info->pgwa_len>DR_MAX_GWLIST)?DR_MAX_GWLIST:rt_info->pgwa_len;
  646. /* set gw order */
  647. if(sort_order>=1&&gwlist_size>1)
  648. {
  649. j = 0;
  650. t = 0;
  651. while(j<gwlist_size)
  652. {
  653. /* identify the group: [j..i) */
  654. for(i=j+1; i<gwlist_size; i++)
  655. if(rt_info->pgwl[j].grpid!=rt_info->pgwl[i].grpid)
  656. break;
  657. if(i-j==1)
  658. {
  659. local_gwlist[t++] = j;
  660. /*LM_DBG("selected gw[%d]=%d\n",
  661. j, local_gwlist[j]);*/
  662. } else {
  663. if(i-j==2)
  664. {
  665. local_gwlist[t++] = j + rand()%2;
  666. if(sort_order==1)
  667. {
  668. local_gwlist[t++] = j + (local_gwlist[j]-j+1)%2;
  669. /*LM_DBG("selected gw[%d]=%d"
  670. * " gw[%d]=%d\n", j, local_gwlist[j], j+1,
  671. * local_gwlist[j+1]);*/
  672. }
  673. } else {
  674. local_gwlist[t++] = j + rand()%(i-j);
  675. if(sort_order==1)
  676. {
  677. do{
  678. local_gwlist[t] = j + rand()%(i-j);
  679. }while(local_gwlist[t]==local_gwlist[t-1]);
  680. t++;
  681. /*
  682. LM_DBG("selected gw[%d]=%d"
  683. " gw[%d]=%d.\n",
  684. j, local_gwlist[j], j+1, local_gwlist[j+1]); */
  685. /* add the rest in this group */
  686. for(l=j; l<i; l++)
  687. {
  688. if(l==local_gwlist[j] || l==local_gwlist[j+1])
  689. continue;
  690. local_gwlist[t++] = l;
  691. /* LM_DBG("selected gw[%d]=%d.\n",
  692. j+k, local_gwlist[t]); */
  693. }
  694. }
  695. }
  696. }
  697. if ( sort_order == 2 ) {
  698. /* check not to use the same gateway as before */
  699. if ( t>1 ) {
  700. /* check if all in the current set were already chosen */
  701. if (i-j <= t-1) {
  702. for( l = j; l< i; l++) {
  703. if ( ! dr_already_choosen(rt_info, local_gwlist, t-1, l) )
  704. break;
  705. }
  706. if ( l == i ) {
  707. LM_INFO("All gateways in group from %d - %d were already used\n", j, i);
  708. t--; /* jump over this group, nothing to choose here */
  709. j=i; continue;
  710. }
  711. }
  712. while ( dr_already_choosen(rt_info, local_gwlist, t-1, local_gwlist[t-1]) ) {
  713. local_gwlist[t-1] = j + rand()%(i-j);
  714. }
  715. }
  716. LM_DBG("The %d gateway is %.*s [%d]\n", t, rt_info->pgwl[local_gwlist[t-1]].pgw->ip.len,
  717. rt_info->pgwl[local_gwlist[t-1]].pgw->ip.s, local_gwlist[t-1]);
  718. }
  719. /* next group starts from i */
  720. j=i;
  721. }
  722. } else {
  723. for(i=0; i<gwlist_size; i++)
  724. local_gwlist[i] = i;
  725. t = i;
  726. }
  727. /* do some cleanup first */
  728. destroy_avps( ruri_avp.type, ruri_avp.name, 1);
  729. /* push gwlist into avps in reverse order */
  730. for( j=t-1 ; j>=1 ; j-- ) {
  731. /* build uri*/
  732. ruri = build_ruri(&uri, rt_info->pgwl[local_gwlist[j]].pgw->strip,
  733. &rt_info->pgwl[local_gwlist[j]].pgw->pri,
  734. &rt_info->pgwl[local_gwlist[j]].pgw->ip);
  735. if (ruri==0) {
  736. LM_ERR("failed to build avp ruri\n");
  737. goto error2;
  738. }
  739. LM_DBG("adding gw [%d] as avp \"%.*s\"\n",
  740. local_gwlist[j], ruri->len, ruri->s);
  741. /* add ruri avp */
  742. val.s = *ruri;
  743. if (add_avp( AVP_VAL_STR|(ruri_avp.type),ruri_avp.name, val)!=0 ) {
  744. LM_ERR("failed to insert ruri avp\n");
  745. pkg_free(ruri->s);
  746. goto error2;
  747. }
  748. pkg_free(ruri->s);
  749. /* add attrs avp */
  750. val.s = rt_info->pgwl[local_gwlist[j]].pgw->attrs;
  751. LM_DBG("setting attr [%.*s] as avp\n",val.s.len,val.s.s);
  752. if (add_avp( AVP_VAL_STR|(attrs_avp.type),attrs_avp.name, val)!=0 ) {
  753. LM_ERR("failed to insert attrs avp\n");
  754. goto error2;
  755. }
  756. }
  757. /* use first GW in RURI */
  758. ruri = build_ruri(&uri, rt_info->pgwl[local_gwlist[0]].pgw->strip,
  759. &rt_info->pgwl[local_gwlist[0]].pgw->pri,
  760. &rt_info->pgwl[local_gwlist[0]].pgw->ip);
  761. /* add attrs avp */
  762. val.s = rt_info->pgwl[local_gwlist[0]].pgw->attrs;
  763. LM_DBG("setting attr [%.*s] as for ruri\n",val.s.len,val.s.s);
  764. if (add_avp( AVP_VAL_STR|(attrs_avp.type),attrs_avp.name, val)!=0 ) {
  765. LM_ERR("failed to insert attrs avp\n");
  766. goto error2;
  767. }
  768. /* we are done reading -> unref the data */
  769. lock_get( ref_lock );
  770. *data_refcnt = *data_refcnt - 1;
  771. lock_release( ref_lock );
  772. /* what hev we get here?? */
  773. if (ruri==0) {
  774. LM_ERR("failed to build ruri\n");
  775. goto error1;
  776. }
  777. LM_DBG("setting the gw [%d] as ruri \"%.*s\"\n",
  778. local_gwlist[0], ruri->len, ruri->s);
  779. if (msg->new_uri.s)
  780. pkg_free(msg->new_uri.s);
  781. msg->new_uri = *ruri;
  782. msg->parsed_uri_ok = 0;
  783. ruri_mark_new();
  784. return 1;
  785. error2:
  786. /* we are done reading -> unref the data */
  787. lock_get( ref_lock );
  788. *data_refcnt = *data_refcnt - 1;
  789. lock_release( ref_lock );
  790. error1:
  791. return ret;
  792. }
  793. static int fixup_do_routing(void** param, int param_no)
  794. {
  795. char *s;
  796. dr_group_t *drg;
  797. pv_spec_t avp_spec;
  798. str r;
  799. s = (char*)*param;
  800. if (param_no==1)
  801. {
  802. drg = (dr_group_t*)pkg_malloc(sizeof(dr_group_t));
  803. if(drg==NULL)
  804. {
  805. LM_ERR( "no more memory\n");
  806. return E_OUT_OF_MEM;
  807. }
  808. memset(drg, 0, sizeof(dr_group_t));
  809. if ( s==NULL || s[0]==0 ) {
  810. LM_CRIT("empty group id definition");
  811. return E_CFG;
  812. }
  813. if (s[0]=='$') {
  814. /* param is a PV (AVP only supported) */
  815. r.s = s;
  816. r.len = strlen(s);
  817. if (pv_parse_spec( &r, &avp_spec)==0
  818. || avp_spec.type!=PVT_AVP) {
  819. LM_ERR("malformed or non AVP %s AVP definition\n", s);
  820. return E_CFG;
  821. }
  822. if( pv_get_avp_name(0, &(avp_spec.pvp), &(drg->u.avp_id.name),
  823. &(drg->u.avp_id.type) )!=0) {
  824. LM_ERR("[%s]- invalid AVP definition\n", s);
  825. return E_CFG;
  826. }
  827. drg->type = 1;
  828. /* do not free the param as the AVP spec may point inside
  829. this string*/
  830. } else {
  831. while(s && *s) {
  832. if(*s<'0' || *s>'9') {
  833. LM_ERR( "bad number\n");
  834. return E_UNSPEC;
  835. }
  836. drg->u.grp_id = (drg->u.grp_id)*10+(*s-'0');
  837. s++;
  838. }
  839. pkg_free(*param);
  840. }
  841. *param = (void*)drg;
  842. }
  843. return 0;
  844. }
  845. static int fixup_from_gw( void** param, int param_no)
  846. {
  847. unsigned long type;
  848. int err;
  849. if (param_no == 1 || param_no == 2) {
  850. type = str2s(*param, strlen(*param), &err);
  851. if (err == 0) {
  852. pkg_free(*param);
  853. *param = (void *)type;
  854. return 0;
  855. } else {
  856. LM_ERR( "bad number <%s>\n",
  857. (char *)(*param));
  858. return E_CFG;
  859. }
  860. }
  861. return 0;
  862. }
  863. static int strip_username(struct sip_msg* msg, int strip)
  864. {
  865. struct action act;
  866. struct run_act_ctx ra_ctx;
  867. act.type = STRIP_T;
  868. act.val[0].type = NUMBER_ST;
  869. act.val[0].u.number = strip;
  870. act.next = 0;
  871. init_run_actions_ctx(&ra_ctx);
  872. if (do_action(&ra_ctx, &act, msg) < 0)
  873. {
  874. LM_ERR( "Error in do_action\n");
  875. return -1;
  876. }
  877. return 0;
  878. }
  879. static int is_from_gw_0(struct sip_msg* msg, char* str, char* str2)
  880. {
  881. pgw_addr_t *pgwa = NULL;
  882. if(rdata==NULL || *rdata==NULL || msg==NULL)
  883. return -1;
  884. pgwa = (*rdata)->pgw_addr_l;
  885. while(pgwa) {
  886. if( (pgwa->port==0 || pgwa->port==msg->rcv.src_port) &&
  887. ip_addr_cmp(&pgwa->ip, &msg->rcv.src_ip))
  888. return 1;
  889. pgwa = pgwa->next;
  890. }
  891. return -1;
  892. }
  893. static int is_from_gw_1(struct sip_msg* msg, char* str, char* str2)
  894. {
  895. pgw_addr_t *pgwa = NULL;
  896. int type = (int)(long)str;
  897. if(rdata==NULL || *rdata==NULL || msg==NULL)
  898. return -1;
  899. pgwa = (*rdata)->pgw_addr_l;
  900. while(pgwa) {
  901. if( type==pgwa->type &&
  902. (pgwa->port==0 || pgwa->port==msg->rcv.src_port) &&
  903. ip_addr_cmp(&pgwa->ip, &msg->rcv.src_ip) )
  904. return 1;
  905. pgwa = pgwa->next;
  906. }
  907. return -1;
  908. }
  909. static int is_from_gw_2(struct sip_msg* msg, char* str1, char* str2)
  910. {
  911. pgw_addr_t *pgwa = NULL;
  912. int type = (int)(long)str1;
  913. int flags = (int)(long)str2;
  914. if(rdata==NULL || *rdata==NULL || msg==NULL)
  915. return -1;
  916. pgwa = (*rdata)->pgw_addr_l;
  917. while(pgwa) {
  918. if( type==pgwa->type &&
  919. (pgwa->port==0 || pgwa->port==msg->rcv.src_port) &&
  920. ip_addr_cmp(&pgwa->ip, &msg->rcv.src_ip) ) {
  921. if (flags!=0 && pgwa->strip>0)
  922. strip_username(msg, pgwa->strip);
  923. return 1;
  924. }
  925. pgwa = pgwa->next;
  926. }
  927. return -1;
  928. }
  929. static int goes_to_gw_1(struct sip_msg* msg, char* _type, char* _f2)
  930. {
  931. pgw_addr_t *pgwa = NULL;
  932. struct sip_uri puri;
  933. struct ip_addr *ip;
  934. str *uri;
  935. int type;
  936. if(rdata==NULL || *rdata==NULL || msg==NULL)
  937. return -1;
  938. uri = GET_NEXT_HOP(msg);
  939. type = (int)(long)_type;
  940. if (parse_uri(uri->s, uri->len, &puri)<0){
  941. LM_ERR("bad uri <%.*s>\n", uri->len, uri->s);
  942. return -1;
  943. }
  944. if ( ((ip=str2ip(&puri.host))!=0)
  945. || ((ip=str2ip6(&puri.host))!=0)
  946. ){
  947. pgwa = (*rdata)->pgw_addr_l;
  948. while(pgwa) {
  949. if( (type<0 || type==pgwa->type) && ip_addr_cmp(&pgwa->ip, ip))
  950. return 1;
  951. pgwa = pgwa->next;
  952. }
  953. }
  954. return -1;
  955. }
  956. static int goes_to_gw_0(struct sip_msg* msg, char* _type, char* _f2)
  957. {
  958. return goes_to_gw_1(msg, (char*)(long)-1, _f2);
  959. }