PageRenderTime 64ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/openser-1.3.4-tls/modules/lcr/lcr_mod.c

#
C | 2178 lines | 1699 code | 246 blank | 233 comment | 436 complexity | 8ee89f557e78add9e5ebc84d8e5a0b63 MD5 | raw file
Possible License(s): AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * $Id: lcr_mod.c 4718 2008-08-23 07:16:06Z juhe $
  3. *
  4. * Least Cost Routing module (also implements sequential forking)
  5. *
  6. * Copyright (C) 2005 Juha Heinanen
  7. * Copyright (C) 2006 Voice Sistem SRL
  8. *
  9. * This file is part of openser, a free SIP server.
  10. *
  11. * openser is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version
  15. *
  16. * openser is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24. *
  25. * History:
  26. * -------
  27. * 2005-02-14: Introduced lcr module (jh)
  28. * 2005-02-20: Added sequential forking functions (jh)
  29. * 2005-02-25: Added support for int AVP names, combined addr and port
  30. * AVPs (jh)
  31. * 2005-07-28: Added support for gw URI scheme and transport,
  32. * backport from ser (kd)
  33. * 2005-08-20: Added support for gw prefixes (jh)
  34. * 2005-09-03: Request-URI user part can be modified between load_gws()
  35. * and first next_gw() calls.
  36. */
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <arpa/inet.h>
  41. #include <regex.h>
  42. #include "../../sr_module.h"
  43. #include "../../dprint.h"
  44. #include "../../ut.h"
  45. #include "../../error.h"
  46. #include "../../mem/mem.h"
  47. #include "../../mem/shm_mem.h"
  48. #include "../../db/db.h"
  49. #include "../../usr_avp.h"
  50. #include "../../parser/parse_uri.h"
  51. #include "../../parser/parse_from.h"
  52. #include "../../parser/msg_parser.h"
  53. #include "../../action.h"
  54. #include "../../qvalue.h"
  55. #include "../../dset.h"
  56. #include "../../ip_addr.h"
  57. #include "../../mi/mi.h"
  58. #include "../../mod_fix.h"
  59. #include "../../socket_info.h"
  60. #include "mi.h"
  61. MODULE_VERSION
  62. /*
  63. * Version of gw and lcr tables required by the module,
  64. * increment this value if you change the table in
  65. * an backwards incompatible way
  66. */
  67. #define GW_TABLE_VERSION 5
  68. #define LCR_TABLE_VERSION 2
  69. /* usr_avp flag for sequential forking */
  70. #define Q_FLAG (1<<2)
  71. static void destroy(void); /* Module destroy function */
  72. static int child_init(int rank); /* Per-child initialization function */
  73. static int mi_child_init(void);
  74. static int mod_init(void); /* Module initialization function */
  75. static int fixstringloadgws(void **param, int param_count);
  76. int reload_gws ( void );
  77. #define GW_TABLE "gw"
  78. #define GW_NAME_COL "gw_name"
  79. #define IP_ADDR_COL "ip_addr"
  80. #define PORT_COL "port"
  81. #define URI_SCHEME_COL "uri_scheme"
  82. #define TRANSPORT_COL "transport"
  83. #define GRP_ID_COL "grp_id"
  84. #define DM_COL "dm"
  85. #define LCR_TABLE "lcr"
  86. #define STRIP_COL "strip"
  87. #define PREFIX_COL "prefix"
  88. #define FROM_URI_COL "from_uri"
  89. #define PRIORITY_COL "priority"
  90. #define MAX_QUERY_SIZE 512
  91. #define MAX_NO_OF_GWS 32
  92. #define MAX_NO_OF_LCRS 256
  93. #define MAX_PREFIX_LEN 16
  94. #define MAX_FROM_URI_LEN 256
  95. /* Default module parameter values */
  96. #define DEF_FR_INV_TIMER 90
  97. #define DEF_FR_INV_TIMER_NEXT 30
  98. /*
  99. * Type definitions
  100. */
  101. typedef enum sip_protos uri_transport;
  102. struct gw_info {
  103. unsigned int ip_addr;
  104. unsigned int port;
  105. unsigned int grp_id;
  106. uri_type scheme;
  107. uri_transport transport;
  108. unsigned int strip;
  109. char prefix[MAX_PREFIX_LEN];
  110. unsigned short prefix_len;
  111. unsigned short dm; /* gw supports directed media */
  112. };
  113. struct lcr_info {
  114. char prefix[MAX_PREFIX_LEN];
  115. unsigned short prefix_len;
  116. char from_uri[MAX_FROM_URI_LEN + 1];
  117. unsigned short from_uri_len;
  118. unsigned int grp_id;
  119. unsigned short priority;
  120. unsigned short end_record;
  121. };
  122. struct from_uri_regex {
  123. regex_t re;
  124. short int valid;
  125. };
  126. struct mi {
  127. int gw_index;
  128. int route_index;
  129. int randomizer;
  130. };
  131. /*
  132. * Database variables
  133. */
  134. static db_con_t* db_handle = 0; /* Database connection handle */
  135. static db_func_t lcr_dbf;
  136. /*
  137. * Module parameter variables
  138. */
  139. /* database */
  140. static str db_url = str_init(DEFAULT_RODB_URL);
  141. str gw_table = str_init(GW_TABLE);
  142. str gw_name_col = str_init(GW_NAME_COL);
  143. str ip_addr_col = str_init(IP_ADDR_COL);
  144. str port_col = str_init(PORT_COL);
  145. str uri_scheme_col = str_init(URI_SCHEME_COL);
  146. str transport_col = str_init(TRANSPORT_COL);
  147. str grp_id_col = str_init(GRP_ID_COL);
  148. str dm_col = str_init(DM_COL);
  149. str lcr_table = str_init(LCR_TABLE);
  150. str strip_col = str_init(STRIP_COL);
  151. str prefix_col = str_init(PREFIX_COL);
  152. str from_uri_col = str_init(FROM_URI_COL);
  153. str priority_col = str_init(PRIORITY_COL);
  154. /* timer */
  155. int fr_inv_timer = DEF_FR_INV_TIMER;
  156. int fr_inv_timer_next = DEF_FR_INV_TIMER_NEXT;
  157. /* avps */
  158. static char *fr_inv_timer_avp_param = NULL;
  159. static char *gw_uri_avp_param = NULL;
  160. static char *ruri_user_avp_param = NULL;
  161. static char *contact_avp_param = NULL;
  162. static char *rpid_avp_param = NULL;
  163. /* flags */
  164. unsigned int dm_flag = 1024;
  165. /*
  166. * Other module types and variables
  167. */
  168. struct contact {
  169. str uri;
  170. qvalue_t q;
  171. str dst_uri;
  172. str path;
  173. unsigned int flags;
  174. struct socket_info* sock;
  175. unsigned short q_flag;
  176. struct contact *next;
  177. };
  178. static int fr_inv_timer_avp_type;
  179. static int_str fr_inv_timer_avp;
  180. static int gw_uri_avp_type;
  181. static int_str gw_uri_avp;
  182. static int ruri_user_avp_type;
  183. static int_str ruri_user_avp;
  184. static int contact_avp_type;
  185. static int_str contact_avp;
  186. static int rpid_avp_type;
  187. static int_str rpid_avp;
  188. struct gw_info **gws; /* Pointer to current gw table pointer */
  189. struct gw_info *gws_1; /* Pointer to gw table 1 */
  190. struct gw_info *gws_2; /* Pointer to gw table 2 */
  191. struct lcr_info **lcrs; /* Pointer to current lcr table pointer */
  192. struct lcr_info *lcrs_1; /* Pointer to lcr table 1 */
  193. struct lcr_info *lcrs_2; /* Pointer to lcr table 2 */
  194. unsigned int *lcrs_ws_reload_counter;
  195. unsigned int reload_counter;
  196. struct from_uri_regex from_uri_reg[MAX_NO_OF_LCRS];
  197. /*
  198. * Module functions that are defined later
  199. */
  200. int load_gws(struct sip_msg* _m, char* _s1, char* _s2);
  201. int load_gws_grp(struct sip_msg* _m, char* _s1, char* _s2);
  202. int next_gw(struct sip_msg* _m, char* _s1, char* _s2);
  203. int from_gw(struct sip_msg* _m, char* _s1, char* _s2);
  204. int from_gw_grp(struct sip_msg* _m, char* _s1, char* _s2);
  205. int to_gw(struct sip_msg* _m, char* _s1, char* _s2);
  206. int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2);
  207. int load_contacts (struct sip_msg*, char*, char*);
  208. int next_contacts (struct sip_msg*, char*, char*);
  209. /*
  210. * Exported functions
  211. */
  212. static cmd_export_t cmds[] = {
  213. {"load_gws", load_gws, 0, 0, 0, REQUEST_ROUTE},
  214. {"load_gws", load_gws_grp, 1, fixstringloadgws, 0,
  215. REQUEST_ROUTE},
  216. {"next_gw", next_gw, 0, 0, 0,
  217. REQUEST_ROUTE | FAILURE_ROUTE},
  218. {"from_gw", from_gw, 0, 0, 0,
  219. REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
  220. {"from_gw", from_gw_grp, 1, fixup_str2int, 0,
  221. REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
  222. {"to_gw", to_gw, 0, 0, 0,
  223. REQUEST_ROUTE | FAILURE_ROUTE},
  224. {"to_gw", to_gw_grp, 1, fixup_str2int, 0,
  225. REQUEST_ROUTE | FAILURE_ROUTE},
  226. {"load_contacts", load_contacts, 0, 0, 0,
  227. REQUEST_ROUTE},
  228. {"next_contacts", next_contacts, 0, 0, 0,
  229. REQUEST_ROUTE | FAILURE_ROUTE},
  230. {0, 0, 0, 0, 0, 0}
  231. };
  232. /*
  233. * Exported parameters
  234. */
  235. static param_export_t params[] = {
  236. {"db_url", STR_PARAM, &db_url.s },
  237. {"gw_table", STR_PARAM, &gw_table.s },
  238. {"gw_name_column", STR_PARAM, &gw_name_col.s },
  239. {"ip_addr_column", STR_PARAM, &ip_addr_col.s },
  240. {"port_column", STR_PARAM, &port_col.s },
  241. {"uri_scheme_column", STR_PARAM, &uri_scheme_col.s },
  242. {"transport_column", STR_PARAM, &transport_col.s },
  243. {"grp_id_column", STR_PARAM, &grp_id_col.s },
  244. {"dm_column", STR_PARAM, &dm_col.s },
  245. {"lcr_table", STR_PARAM, &lcr_table.s },
  246. {"strip_column", STR_PARAM, &strip_col.s },
  247. {"prefix_column", STR_PARAM, &prefix_col.s },
  248. {"from_uri_column", STR_PARAM, &from_uri_col.s },
  249. {"priority_column", STR_PARAM, &priority_col.s },
  250. {"fr_inv_timer_avp", STR_PARAM, &fr_inv_timer_avp_param },
  251. {"gw_uri_avp", STR_PARAM, &gw_uri_avp_param },
  252. {"ruri_user_avp", STR_PARAM, &ruri_user_avp_param },
  253. {"contact_avp", STR_PARAM, &contact_avp_param },
  254. {"rpid_avp", STR_PARAM, &rpid_avp_param },
  255. {"fr_inv_timer", INT_PARAM, &fr_inv_timer },
  256. {"fr_inv_timer_next", INT_PARAM, &fr_inv_timer_next },
  257. {"dm_flag", INT_PARAM, &dm_flag },
  258. {0, 0, 0}
  259. };
  260. /*
  261. * Exported MI functions
  262. */
  263. static mi_export_t mi_cmds[] = {
  264. { MI_LCR_RELOAD, mi_lcr_reload, MI_NO_INPUT_FLAG, 0, mi_child_init },
  265. { MI_LCR_DUMP, mi_lcr_dump, MI_NO_INPUT_FLAG, 0, 0 },
  266. { 0, 0, 0, 0 ,0}
  267. };
  268. /*
  269. * Module interface
  270. */
  271. struct module_exports exports = {
  272. "lcr",
  273. DEFAULT_DLFLAGS, /* dlopen flags */
  274. cmds, /* Exported functions */
  275. params, /* Exported parameters */
  276. 0, /* exported statistics */
  277. mi_cmds, /* exported MI functions */
  278. 0, /* exported pseudo-variables */
  279. 0, /* extra processes */
  280. mod_init, /* module initialization function */
  281. 0, /* response function */
  282. destroy, /* destroy function */
  283. child_init /* child initialization function */
  284. };
  285. int lcr_db_init(char* db_url)
  286. {
  287. if (lcr_dbf.init==0){
  288. LM_CRIT("Null lcr_dbf\n");
  289. goto error;
  290. }
  291. db_handle=lcr_dbf.init(db_url);
  292. if (db_handle==0){
  293. LM_ERR("Unable to connect to the database\n");
  294. goto error;
  295. }
  296. return 0;
  297. error:
  298. return -1;
  299. }
  300. int lcr_db_bind(char* db_url)
  301. {
  302. if (bind_dbmod(db_url, &lcr_dbf)<0){
  303. LM_ERR("Unable to bind to the database module\n");
  304. return -1;
  305. }
  306. if (!DB_CAPABILITY(lcr_dbf, DB_CAP_QUERY)) {
  307. LM_ERR("Database module does not implement 'query' function\n");
  308. return -1;
  309. }
  310. return 0;
  311. }
  312. void lcr_db_close(void)
  313. {
  314. if (db_handle && lcr_dbf.close){
  315. lcr_dbf.close(db_handle);
  316. db_handle=0;
  317. }
  318. }
  319. int lcr_db_ver(char* db_url, str* name)
  320. {
  321. db_con_t* dbh;
  322. int ver;
  323. if (lcr_dbf.init==0){
  324. LM_CRIT("Unbound database\n");
  325. return -1;
  326. }
  327. dbh=lcr_dbf.init(db_url);
  328. if (dbh==0){
  329. LM_ERR("Unable to open database connection\n");
  330. return -1;
  331. }
  332. ver=table_version(&lcr_dbf, dbh, name);
  333. lcr_dbf.close(dbh);
  334. return ver;
  335. }
  336. /*
  337. * Module initialization function callee in each child separately
  338. */
  339. static int child_init(int rank)
  340. {
  341. /* don't do anything for non-worker process */
  342. if (rank<1)
  343. return 0;
  344. if (lcr_db_init(db_url.s) < 0) {
  345. LM_ERR("Unable to connect to database\n");
  346. return -1;
  347. }
  348. return 0;
  349. }
  350. static int mi_child_init(void)
  351. {
  352. return lcr_db_init(db_url.s);
  353. }
  354. /*
  355. * Module initialization function that is called before the main process forks
  356. */
  357. static int mod_init(void)
  358. {
  359. int ver, i;
  360. pv_spec_t avp_spec;
  361. str s;
  362. unsigned short avp_flags;
  363. LM_DBG("Initializing\n");
  364. /* Bind database */
  365. if (lcr_db_bind(db_url.s)) {
  366. LM_ERR("No database module found\n");
  367. return -1;
  368. }
  369. /* Update length of module variables */
  370. db_url.len = strlen(db_url.s);
  371. gw_table.len = strlen(gw_table.s);
  372. gw_name_col.len = strlen(gw_name_col.s);
  373. ip_addr_col.len = strlen(ip_addr_col.s);
  374. port_col.len = strlen(port_col.s);
  375. uri_scheme_col.len = strlen(uri_scheme_col.s);
  376. transport_col.len = strlen(transport_col.s);
  377. grp_id_col.len = strlen(grp_id_col.s);
  378. lcr_table.len = strlen(lcr_table.s);
  379. strip_col.len = strlen(strip_col.s);
  380. prefix_col.len = strlen(prefix_col.s);
  381. from_uri_col.len = strlen(from_uri_col.s);
  382. priority_col.len = strlen(priority_col.s);
  383. /* Process AVP params */
  384. if (fr_inv_timer_avp_param && *fr_inv_timer_avp_param) {
  385. s.s = fr_inv_timer_avp_param; s.len = strlen(s.s);
  386. if (pv_parse_spec(&s, &avp_spec)==0
  387. || avp_spec.type!=PVT_AVP) {
  388. LM_ERR("Malformed or non AVP definition <%s>\n",
  389. fr_inv_timer_avp_param);
  390. return -1;
  391. }
  392. if(pv_get_avp_name(0, &(avp_spec.pvp), &fr_inv_timer_avp, &avp_flags)!=0) {
  393. LM_ERR("Invalid AVP definition <%s>\n", fr_inv_timer_avp_param);
  394. return -1;
  395. }
  396. fr_inv_timer_avp_type = avp_flags;
  397. } else {
  398. LM_ERR("AVP fr_inv_timer_avp has not been defined\n");
  399. return -1;
  400. }
  401. if (gw_uri_avp_param && *gw_uri_avp_param) {
  402. s.s = gw_uri_avp_param; s.len = strlen(s.s);
  403. if (pv_parse_spec(&s, &avp_spec)==0
  404. || avp_spec.type!=PVT_AVP) {
  405. LM_ERR("Malformed or non AVP definition <%s>\n", gw_uri_avp_param);
  406. return -1;
  407. }
  408. if(pv_get_avp_name(0, &(avp_spec.pvp), &gw_uri_avp, &avp_flags)!=0) {
  409. LM_ERR("Invalid AVP definition <%s>\n", gw_uri_avp_param);
  410. return -1;
  411. }
  412. gw_uri_avp_type = avp_flags;
  413. } else {
  414. LM_ERR("AVP gw_uri_avp has not been defined\n");
  415. return -1;
  416. }
  417. if (ruri_user_avp_param && *ruri_user_avp_param) {
  418. s.s = ruri_user_avp_param; s.len = strlen(s.s);
  419. if (pv_parse_spec(&s, &avp_spec)==0
  420. || avp_spec.type!=PVT_AVP) {
  421. LM_ERR("Malformed or non AVP definition <%s>\n",
  422. ruri_user_avp_param);
  423. return -1;
  424. }
  425. if(pv_get_avp_name(0, &(avp_spec.pvp), &ruri_user_avp, &avp_flags)!=0) {
  426. LM_ERR("Invalid AVP definition <%s>\n", ruri_user_avp_param);
  427. return -1;
  428. }
  429. ruri_user_avp_type = avp_flags;
  430. } else {
  431. LM_ERR("AVP ruri_user_avp has not been defined\n");
  432. return -1;
  433. }
  434. if (contact_avp_param && *contact_avp_param) {
  435. s.s = contact_avp_param; s.len = strlen(s.s);
  436. if (pv_parse_spec(&s, &avp_spec)==0
  437. || avp_spec.type!=PVT_AVP) {
  438. LM_ERR("Malformed or non AVP definition <%s>\n",
  439. contact_avp_param);
  440. return -1;
  441. }
  442. if(pv_get_avp_name(0, &(avp_spec.pvp), &contact_avp, &avp_flags)!=0) {
  443. LM_ERR("Invalid AVP definition <%s>\n", contact_avp_param);
  444. return -1;
  445. }
  446. contact_avp_type = avp_flags;
  447. } else {
  448. LM_ERR("AVP contact_avp has not been defined\n");
  449. return -1;
  450. }
  451. if (rpid_avp_param && *rpid_avp_param) {
  452. s.s = rpid_avp_param; s.len = strlen(s.s);
  453. if (pv_parse_spec(&s, &avp_spec)==0
  454. || avp_spec.type!=PVT_AVP) {
  455. LM_ERR("Malformed or non AVP definition <%s>\n", rpid_avp_param);
  456. return -1;
  457. }
  458. if(pv_get_avp_name(0, &(avp_spec.pvp), &rpid_avp, &avp_flags)!=0) {
  459. LM_ERR("Invalid AVP definition <%s>\n", rpid_avp_param);
  460. return -1;
  461. }
  462. rpid_avp_type = avp_flags;
  463. } else {
  464. LM_ERR("AVP rpid_avp has not been defined\n");
  465. return -1;
  466. }
  467. /* Check dm_flag value */
  468. if (dm_flag > 31) {
  469. LM_ERR("Undefined or invalid dm_flag value <%u>\n", dm_flag);
  470. return -1;
  471. }
  472. /* Check table version */
  473. ver = lcr_db_ver(db_url.s, &gw_table);
  474. if (ver < 0) {
  475. LM_ERR("Error while querying gw table version\n");
  476. goto err;
  477. } else if (ver < GW_TABLE_VERSION) {
  478. LM_ERR("Invalid table version of gw table <%d>\n", ver);
  479. goto err;
  480. }
  481. /* Check table version */
  482. ver = lcr_db_ver(db_url.s, &lcr_table);
  483. if (ver < 0) {
  484. LM_ERR("Error while querying lcr table version\n");
  485. goto err;
  486. } else if (ver < LCR_TABLE_VERSION) {
  487. LM_ERR("Invalid table version of lcr table <%d>\n", ver);
  488. goto err;
  489. }
  490. /* Initializing gw tables and gw table pointer variable */
  491. gws_1 = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
  492. (MAX_NO_OF_GWS + 1));
  493. if (gws_1 == 0) {
  494. LM_ERR("No memory for gw table\n");
  495. goto err;
  496. }
  497. gws_2 = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
  498. (MAX_NO_OF_GWS + 1));
  499. if (gws_2 == 0) {
  500. LM_ERR("No memory for gw table\n");
  501. goto err;
  502. }
  503. for (i = 0; i < MAX_NO_OF_GWS + 1; i++) {
  504. gws_1[i].ip_addr = gws_2[i].ip_addr = 0;
  505. }
  506. gws = (struct gw_info **)shm_malloc(sizeof(struct gw_info *));
  507. if (gws == 0) {
  508. LM_ERR("No memory for gw table pointer\n");
  509. }
  510. *gws = gws_1;
  511. /* Initializing lcr tables and lcr table pointer variable */
  512. lcrs_1 = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info) *
  513. (MAX_NO_OF_LCRS + 1));
  514. if (lcrs_1 == 0) {
  515. LM_ERR("No memory for lcr table\n");
  516. goto err;
  517. }
  518. lcrs_2 = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info) *
  519. (MAX_NO_OF_LCRS + 1));
  520. if (lcrs_2 == 0) {
  521. LM_ERR("No memory for lcr table\n");
  522. goto err;
  523. }
  524. for (i = 0; i < MAX_NO_OF_LCRS + 1; i++) {
  525. lcrs_1[i].end_record = lcrs_2[i].end_record = 0;
  526. }
  527. lcrs = (struct lcr_info **)shm_malloc(sizeof(struct lcr_info *));
  528. if (lcrs == 0) {
  529. LM_ERR("No memory for lcr table pointer\n");
  530. goto err;
  531. }
  532. *lcrs = lcrs_1;
  533. lcrs_ws_reload_counter = (unsigned int *)shm_malloc(sizeof(unsigned int));
  534. if (lcrs_ws_reload_counter == 0) {
  535. LM_ERR("No memory for reload counter\n");
  536. goto err;
  537. }
  538. *lcrs_ws_reload_counter = reload_counter = 0;
  539. memset(from_uri_reg, 0, sizeof(struct from_uri_regex) * MAX_NO_OF_LCRS);
  540. /* First reload */
  541. if (reload_gws() == -1) {
  542. LM_CRIT("Failed to reload gateways and routes\n");
  543. goto err;
  544. }
  545. return 0;
  546. err:
  547. return -1;
  548. }
  549. static void destroy(void)
  550. {
  551. lcr_db_close();
  552. }
  553. /*
  554. * Sort lcr records by prefix_len and priority.
  555. */
  556. static int comp_lcrs(const void *m1, const void *m2)
  557. {
  558. int result = -1;
  559. struct mi *mi1 = (struct mi *) m1;
  560. struct mi *mi2 = (struct mi *) m2;
  561. struct lcr_info lcr_record1 = (*lcrs)[mi1->route_index];
  562. struct lcr_info lcr_record2 = (*lcrs)[mi2->route_index];
  563. /* Sort by prefix. */
  564. if (lcr_record1.prefix_len > lcr_record2.prefix_len) {
  565. result = 1;
  566. }
  567. else if (lcr_record1.prefix_len == lcr_record2.prefix_len) {
  568. /* Sort by priority. */
  569. if (lcr_record1.priority < lcr_record2.priority) {
  570. result = 1;
  571. }
  572. else if (lcr_record1.priority == lcr_record2.priority) {
  573. /* Nothing to do. */
  574. result = 0;
  575. }
  576. }
  577. return result;
  578. }
  579. /*
  580. * Sort lcr records by rand table.
  581. */
  582. static int rand_lcrs(const void *m1, const void *m2)
  583. {
  584. int result = -1;
  585. struct mi mi1 = *((struct mi *) m1);
  586. struct mi mi2 = *((struct mi *) m2);
  587. if (mi1.randomizer > mi2.randomizer) {
  588. result = 1;
  589. } else if (mi1.randomizer == mi2.randomizer) {
  590. result = 0;
  591. }
  592. return result;
  593. }
  594. /*
  595. * regcomp each from_uri.
  596. */
  597. int load_from_uri_regex(void)
  598. {
  599. int i, status, result = 0;
  600. for (i = 0; i < MAX_NO_OF_LCRS; i++) {
  601. if ((*lcrs)[i].end_record != 0) {
  602. break;
  603. }
  604. if (from_uri_reg[i].valid) {
  605. regfree(&(from_uri_reg[i].re));
  606. from_uri_reg[i].valid = 0;
  607. }
  608. memset(&(from_uri_reg[i].re), 0, sizeof(regex_t));
  609. if ((status=regcomp(&(from_uri_reg[i].re),(*lcrs)[i].from_uri,0))!=0){
  610. LM_ERR("Bad from_uri re <%s>\n", (*lcrs)[i].from_uri);
  611. result = -1;
  612. break;
  613. }
  614. from_uri_reg[i].valid = 1;
  615. }
  616. if (result != -1) {
  617. reload_counter = *lcrs_ws_reload_counter;
  618. }
  619. return result;
  620. }
  621. /*
  622. * Reload gws to unused gw table and lcrs to unused lcr table, and, when done
  623. * make unused gw and lcr table the one in use.
  624. */
  625. int reload_gws ( void )
  626. {
  627. unsigned int i, port, strip, prefix_len, from_uri_len, grp_id, priority;
  628. unsigned int dm;
  629. struct in_addr ip_addr;
  630. uri_type scheme;
  631. uri_transport transport;
  632. db_con_t* dbh;
  633. char *prefix, *from_uri;
  634. db_res_t* res = NULL;
  635. db_row_t* row;
  636. db_key_t gw_cols[8];
  637. db_key_t lcr_cols[4];
  638. gw_cols[0] = ip_addr_col.s;
  639. gw_cols[1] = port_col.s;
  640. gw_cols[2] = uri_scheme_col.s;
  641. gw_cols[3] = transport_col.s;
  642. gw_cols[4] = strip_col.s;
  643. gw_cols[5] = prefix_col.s;
  644. /* FIXME: is this ok if we have different names for grp_id
  645. in the two tables? (ge vw lcr) */
  646. gw_cols[6] = grp_id_col.s;
  647. gw_cols[7] = dm_col.s;
  648. lcr_cols[0] = prefix_col.s;
  649. lcr_cols[1] = from_uri_col.s;
  650. /* FIXME: is this ok if we have different names for grp_id
  651. in the two tables? (ge vw lcr) */
  652. lcr_cols[2] = grp_id_col.s;
  653. lcr_cols[3] = priority_col.s;
  654. if (lcr_dbf.init==0){
  655. LM_CRIT("Unbound database\n");
  656. return -1;
  657. }
  658. dbh=lcr_dbf.init(db_url.s);
  659. if (dbh==0){
  660. LM_ERR("Unable to open database connection\n");
  661. return -1;
  662. }
  663. if (lcr_dbf.use_table(dbh, gw_table.s) < 0) {
  664. LM_ERR("Error while trying to use gw table\n");
  665. return -1;
  666. }
  667. if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 8, 0, &res) < 0) {
  668. LM_ERR("Failed to query gw data\n");
  669. lcr_dbf.close(dbh);
  670. return -1;
  671. }
  672. if (RES_ROW_N(res) + 1 > MAX_NO_OF_GWS) {
  673. LM_ERR("Too many gateways\n");
  674. lcr_dbf.free_result(dbh, res);
  675. lcr_dbf.close(dbh);
  676. return -1;
  677. }
  678. for (i = 0; i < RES_ROW_N(res); i++) {
  679. row = RES_ROWS(res) + i;
  680. if (!((VAL_TYPE(ROW_VALUES(row)) == DB_STRING) &&
  681. !VAL_NULL(ROW_VALUES(row)) &&
  682. inet_aton((char *)VAL_STRING(ROW_VALUES(row)), &ip_addr) != 0)) {
  683. LM_ERR("Invalid IP address of gw <%s>\n",
  684. (char *)VAL_STRING(ROW_VALUES(row)));
  685. lcr_dbf.free_result(dbh, res);
  686. lcr_dbf.close(dbh);
  687. return -1;
  688. }
  689. if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
  690. port = 0;
  691. } else {
  692. port = (unsigned int)VAL_INT(ROW_VALUES(row) + 1);
  693. }
  694. if (port > 65536) {
  695. LM_ERR("Port of gw is too large <%u>\n", port);
  696. lcr_dbf.free_result(dbh, res);
  697. lcr_dbf.close(dbh);
  698. return -1;
  699. }
  700. if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {
  701. scheme = SIP_URI_T;
  702. } else {
  703. scheme = (uri_type)VAL_INT(ROW_VALUES(row) + 2);
  704. if ((scheme != SIP_URI_T) && (scheme != SIPS_URI_T)) {
  705. LM_ERR("Unknown or unsupported URI scheme <%u>\n",
  706. (unsigned int)scheme);
  707. lcr_dbf.free_result(dbh, res);
  708. lcr_dbf.close(dbh);
  709. return -1;
  710. }
  711. }
  712. if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {
  713. transport = PROTO_NONE;
  714. } else {
  715. transport = (uri_transport)VAL_INT(ROW_VALUES(row) + 3);
  716. if ((transport != PROTO_UDP) && (transport != PROTO_TCP) &&
  717. (transport != PROTO_TLS) && (transport != PROTO_SCTP)) {
  718. LM_ERR("Unknown or unsupported transport <%u>\n",
  719. (unsigned int)transport);
  720. lcr_dbf.free_result(dbh, res);
  721. lcr_dbf.close(dbh);
  722. return -1;
  723. }
  724. }
  725. if (VAL_NULL(ROW_VALUES(row) + 4) == 1) {
  726. strip = 0;
  727. } else {
  728. strip = (unsigned int)VAL_INT(ROW_VALUES(row) + 4);
  729. }
  730. if (VAL_NULL(ROW_VALUES(row) + 5) == 1) {
  731. prefix_len = 0;
  732. prefix = (char *)0;
  733. } else {
  734. prefix = (char *)VAL_STRING(ROW_VALUES(row) + 5);
  735. prefix_len = strlen(prefix);
  736. if (prefix_len > MAX_PREFIX_LEN) {
  737. LM_ERR("Too long gw prefix <%u>\n", prefix_len);
  738. lcr_dbf.free_result(dbh, res);
  739. lcr_dbf.close(dbh);
  740. return -1;
  741. }
  742. }
  743. if (VAL_NULL(ROW_VALUES(row) + 6) == 1) {
  744. grp_id = 0;
  745. } else {
  746. grp_id = VAL_INT(ROW_VALUES(row) + 6);
  747. }
  748. if (!VAL_NULL(ROW_VALUES(row) + 7) &&
  749. (VAL_TYPE(ROW_VALUES(row) + 7) == DB_INT)) {
  750. dm = (unsigned int)VAL_INT(ROW_VALUES(row) + 7);
  751. if ((dm != 0) && (dm != 1)) {
  752. LM_ERR("Invalid dm value <%u>\n", dm);
  753. lcr_dbf.free_result(dbh, res);
  754. lcr_dbf.close(dbh);
  755. return -1;
  756. }
  757. } else {
  758. LM_ERR("Attribute dm is NULL or non-int\n");
  759. lcr_dbf.free_result(dbh, res);
  760. lcr_dbf.close(dbh);
  761. return -1;
  762. }
  763. if (*gws == gws_1) {
  764. gws_2[i].ip_addr = (unsigned int)ip_addr.s_addr;
  765. gws_2[i].port = port;
  766. gws_2[i].grp_id = grp_id;
  767. gws_2[i].scheme = scheme;
  768. gws_2[i].transport = transport;
  769. gws_2[i].dm = dm;
  770. gws_2[i].strip = strip;
  771. gws_2[i].prefix_len = prefix_len;
  772. if (prefix_len)
  773. memcpy(&(gws_2[i].prefix[0]), prefix, prefix_len);
  774. } else {
  775. gws_1[i].ip_addr = (unsigned int)ip_addr.s_addr;
  776. gws_1[i].port = port;
  777. gws_1[i].grp_id = grp_id;
  778. gws_1[i].scheme = scheme;
  779. gws_1[i].transport = transport;
  780. gws_1[i].dm = dm;
  781. gws_1[i].strip = strip;
  782. gws_1[i].prefix_len = prefix_len;
  783. if (prefix_len)
  784. memcpy(&(gws_1[i].prefix[0]), prefix, prefix_len);
  785. }
  786. }
  787. lcr_dbf.free_result(dbh, res);
  788. if (*gws == gws_1) {
  789. gws_2[i].ip_addr = 0;
  790. *gws = gws_2;
  791. } else {
  792. gws_1[i].ip_addr = 0;
  793. *gws = gws_1;
  794. }
  795. if (lcr_dbf.use_table(dbh, lcr_table.s) < 0) {
  796. LM_ERR("Error while trying to use lcr table\n");
  797. return -1;
  798. }
  799. if (lcr_dbf.query(dbh, NULL, 0, NULL, lcr_cols, 0, 4, 0, &res) < 0) {
  800. LM_ERR("Failed to query lcr data\n");
  801. lcr_dbf.close(dbh);
  802. return -1;
  803. }
  804. if (RES_ROW_N(res) + 1 > MAX_NO_OF_LCRS) {
  805. LM_ERR("Too many lcr entries <%d>\n", RES_ROW_N(res));
  806. lcr_dbf.free_result(dbh, res);
  807. lcr_dbf.close(dbh);
  808. return -1;
  809. }
  810. for (i = 0; i < RES_ROW_N(res); i++) {
  811. row = RES_ROWS(res) + i;
  812. if (VAL_NULL(ROW_VALUES(row)) == 1) {
  813. prefix_len = 0;
  814. prefix = 0;
  815. } else {
  816. prefix = (char *)VAL_STRING(ROW_VALUES(row));
  817. prefix_len = strlen(prefix);
  818. if (prefix_len > MAX_PREFIX_LEN) {
  819. LM_ERR("Too long lcr prefix <%u>\n", prefix_len);
  820. lcr_dbf.free_result(dbh, res);
  821. lcr_dbf.close(dbh);
  822. return -1;
  823. }
  824. }
  825. if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
  826. from_uri_len = 0;
  827. from_uri = 0;
  828. } else {
  829. from_uri = (char *)VAL_STRING(ROW_VALUES(row) + 1);
  830. from_uri_len = strlen(from_uri);
  831. if (from_uri_len > MAX_FROM_URI_LEN) {
  832. LM_ERR("Too long from_uri <%u>\n", from_uri_len);
  833. lcr_dbf.free_result(dbh, res);
  834. lcr_dbf.close(dbh);
  835. return -1;
  836. }
  837. }
  838. if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {
  839. LM_ERR("Route grp_id is NULL\n");
  840. lcr_dbf.free_result(dbh, res);
  841. lcr_dbf.close(dbh);
  842. return -1;
  843. }
  844. grp_id = (unsigned int)VAL_INT(ROW_VALUES(row) + 2);
  845. if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {
  846. LM_ERR("Route priority is NULL\n");
  847. lcr_dbf.free_result(dbh, res);
  848. lcr_dbf.close(dbh);
  849. return -1;
  850. }
  851. priority = (unsigned int)VAL_INT(ROW_VALUES(row) + 3);
  852. if (*lcrs == lcrs_1) {
  853. lcrs_2[i].prefix_len = prefix_len;
  854. if (prefix_len)
  855. memcpy(&(lcrs_2[i].prefix[0]), prefix, prefix_len);
  856. lcrs_2[i].from_uri_len = from_uri_len;
  857. if (from_uri_len) {
  858. memcpy(&(lcrs_2[i].from_uri[0]), from_uri, from_uri_len);
  859. lcrs_2[i].from_uri[from_uri_len] = '\0';
  860. }
  861. lcrs_2[i].grp_id = grp_id;
  862. lcrs_2[i].priority = priority;
  863. lcrs_2[i].end_record = 0;
  864. } else {
  865. lcrs_1[i].prefix_len = prefix_len;
  866. if (prefix_len)
  867. memcpy(&(lcrs_1[i].prefix[0]), prefix, prefix_len);
  868. lcrs_1[i].from_uri_len = from_uri_len;
  869. if (from_uri_len) {
  870. memcpy(&(lcrs_1[i].from_uri[0]), from_uri, from_uri_len);
  871. lcrs_1[i].from_uri[from_uri_len] = '\0';
  872. }
  873. lcrs_1[i].grp_id = grp_id;
  874. lcrs_1[i].priority = priority;
  875. lcrs_1[i].end_record = 0;
  876. }
  877. }
  878. lcr_dbf.free_result(dbh, res);
  879. lcr_dbf.close(dbh);
  880. if (*lcrs == lcrs_1) {
  881. lcrs_2[i].end_record = 1;
  882. *lcrs = lcrs_2;
  883. } else {
  884. lcrs_1[i].end_record = 1;
  885. *lcrs = lcrs_1;
  886. }
  887. (*lcrs_ws_reload_counter)++;
  888. if (0 != load_from_uri_regex()) {
  889. return -1;
  890. }
  891. return 1;
  892. }
  893. int mi_print_gws (struct mi_node* rpl)
  894. {
  895. unsigned int i;
  896. struct mi_attr* attr;
  897. uri_transport transport;
  898. char *transp;
  899. struct mi_node* node;
  900. struct ip_addr address;
  901. char* p;
  902. int len;
  903. for (i = 0; i < MAX_NO_OF_GWS; i++) {
  904. if ((*gws)[i].ip_addr == 0)
  905. break;
  906. node= add_mi_node_child(rpl,0 ,"GW", 2, 0, 0);
  907. if(node == NULL)
  908. return -1;
  909. p = int2str((unsigned long)(*gws)[i].grp_id, &len );
  910. attr = add_mi_attr(node, MI_DUP_VALUE, "GRP_ID", 6, p, len );
  911. if(attr == NULL)
  912. return -1;
  913. transport = (*gws)[i].transport;
  914. if (transport == PROTO_UDP)
  915. transp= ";transport=udp";
  916. else if (transport == PROTO_TCP)
  917. transp= ";transport=tcp";
  918. else if (transport == PROTO_TLS)
  919. transp= ";transport=tls";
  920. else if (transport == PROTO_SCTP)
  921. transp= ";transport=sctp";
  922. else
  923. transp= "";
  924. address.af = AF_INET;
  925. address.len = 4;
  926. address.u.addr32[0] = (*gws)[i].ip_addr;
  927. attr= addf_mi_attr(node,0 ,"URI", 3,"%s:%s:%d%s",
  928. ((*gws)[i].scheme == SIP_URI_T)?"sip":"sips",
  929. ip_addr2a(&address),
  930. ((*gws)[i].port == 0)?5060:(*gws)[i].port,transp);
  931. if(attr == NULL)
  932. return -1;
  933. p = int2str((unsigned long)(*gws)[i].strip, &len );
  934. attr = add_mi_attr(node, MI_DUP_VALUE, "STRIP", 5, p, len);
  935. if(attr == NULL)
  936. return -1;
  937. attr = add_mi_attr(node, MI_DUP_VALUE, "PREFIX", 6,
  938. (*gws)[i].prefix, (*gws)[i].prefix_len );
  939. if(attr == NULL)
  940. return -1;
  941. p = int2str((unsigned long)(*gws)[i].dm, &len );
  942. attr = add_mi_attr(node, MI_DUP_VALUE, "DM", 2, p, len);
  943. if(attr == NULL)
  944. return -1;
  945. }
  946. for (i = 0; i < MAX_NO_OF_LCRS; i++) {
  947. if ((*lcrs)[i].end_record != 0)
  948. break;
  949. node= add_mi_node_child(rpl, 0, "RULE", 4, 0, 0);
  950. attr = add_mi_attr(node, 0, "PREFIX", 6, (*lcrs)[i].prefix,
  951. (*lcrs)[i].prefix_len );
  952. if(attr== 0)
  953. return -1;
  954. attr = add_mi_attr(node, 0, "FROM_URI", 8, (*lcrs)[i].from_uri,
  955. (*lcrs)[i].from_uri_len );
  956. if(attr== 0)
  957. return -1;
  958. p = int2str((unsigned long)(*lcrs)[i].grp_id, &len );
  959. attr = add_mi_attr(node, MI_DUP_VALUE, "GRP_ID", 6, p, len );
  960. if(attr == NULL)
  961. return -1;
  962. p = int2str((unsigned long)(*lcrs)[i].priority, &len );
  963. attr = add_mi_attr(node, MI_DUP_VALUE, "PRIORITY", 8, p, len );
  964. if(attr == NULL)
  965. return -1;
  966. }
  967. return 0;
  968. }
  969. /*
  970. * Load info of matching GWs from database to gw_uri AVPs
  971. */
  972. static int do_load_gws(struct sip_msg* _m, int grp_id)
  973. {
  974. str ruri_user, from_uri, value;
  975. char from_uri_str[MAX_FROM_URI_LEN + 1];
  976. char ruri[MAX_URI_SIZE];
  977. unsigned int i, j, k, index, have_rpid_avp;
  978. unsigned int addr, port;
  979. unsigned int strip, gw_index, duplicated_gw;
  980. unsigned short dm;
  981. uri_type scheme;
  982. uri_transport transport;
  983. struct ip_addr address;
  984. str addr_str, port_str;
  985. char *at, *prefix, *strip_string;
  986. struct usr_avp *avp;
  987. int_str val;
  988. struct mi matched_gws[MAX_NO_OF_GWS + 1];
  989. unsigned short prefix_len, priority;
  990. int randomizer_start, randomizer_end, randomizer_flag, strip_len;
  991. struct lcr_info lcr_rec;
  992. /* Find Request-URI user */
  993. if (parse_sip_msg_uri(_m) < 0) {
  994. LM_ERR("Error while parsing R-URI\n");
  995. return -1;
  996. }
  997. ruri_user = _m->parsed_uri.user;
  998. /* Look for Caller RPID or From URI */
  999. have_rpid_avp = 0;
  1000. avp = search_first_avp(rpid_avp_type, rpid_avp, &val, 0);
  1001. if (avp != NULL) {
  1002. /* Get URI user from RPID if not empty */
  1003. if (avp->flags & AVP_VAL_STR) {
  1004. if (val.s.s && val.s.len) {
  1005. from_uri = val.s;
  1006. have_rpid_avp = 1;
  1007. }
  1008. } else {
  1009. from_uri.s = int2str(val.n, &from_uri.len);
  1010. have_rpid_avp = 1;
  1011. }
  1012. }
  1013. if (!have_rpid_avp) {
  1014. /* Get URI from From URI */
  1015. if ((!_m->from) && (parse_headers(_m, HDR_FROM_F, 0) == -1)) {
  1016. LM_ERR("Error while parsing headers\n");
  1017. return -1;
  1018. }
  1019. if (!_m->from) {
  1020. LM_ERR("From header field not found\n");
  1021. return -1;
  1022. }
  1023. if ((!(_m->from)->parsed) && (parse_from_header(_m) < 0)) {
  1024. LM_ERR("Error while parsing From header\n");
  1025. return -1;
  1026. }
  1027. from_uri = get_from(_m)->uri;
  1028. }
  1029. if (from_uri.len <= MAX_FROM_URI_LEN) {
  1030. strncpy(from_uri_str, from_uri.s, from_uri.len);
  1031. from_uri_str[from_uri.len] = '\0';
  1032. } else {
  1033. LM_ERR("From URI is too long <%u>\n", from_uri.len);
  1034. return -1;
  1035. }
  1036. /*
  1037. * Check if the gws and lcrs were reloaded
  1038. */
  1039. if (reload_counter != *lcrs_ws_reload_counter) {
  1040. if (load_from_uri_regex() != 0) {
  1041. return -1;
  1042. }
  1043. }
  1044. /*
  1045. * Let's match the gws:
  1046. * 1. prefix matching
  1047. * 2. from_uri matching
  1048. * 3. grp_id matching
  1049. *
  1050. * Note: A gateway must be in the list _only_ once.
  1051. */
  1052. gw_index = 0;
  1053. duplicated_gw = 0;
  1054. for (i = 0; i < MAX_NO_OF_LCRS; i++) {
  1055. lcr_rec = (*lcrs)[i];
  1056. if (lcr_rec.end_record != 0) {
  1057. break;
  1058. }
  1059. if ((lcr_rec.prefix_len <= ruri_user.len) &&
  1060. (strncmp(lcr_rec.prefix, ruri_user.s, lcr_rec.prefix_len)==0)) {
  1061. /* 1. Prefix matching is done */
  1062. if ((lcr_rec.from_uri_len == 0) ||
  1063. (from_uri_reg[i].valid &&
  1064. (regexec(&(from_uri_reg[i].re), from_uri_str, 0,
  1065. (regmatch_t *)NULL, 0) == 0))) {
  1066. /* 2. from_uri matching is done */
  1067. for (j = 0; j < MAX_NO_OF_GWS; j++) {
  1068. if ((*gws)[j].ip_addr == 0) {
  1069. break;
  1070. }
  1071. if (lcr_rec.grp_id == (*gws)[j].grp_id &&
  1072. (grp_id < 0 || (*gws)[j].grp_id == grp_id)) {
  1073. /* 3. grp_id matching is done */
  1074. for (k = 0; k < gw_index; k++) {
  1075. if ((*gws)[j].ip_addr ==
  1076. (*gws)[matched_gws[k].gw_index].ip_addr) {
  1077. /* Found the same gw in the list */
  1078. /* Let's keep the one with higher */
  1079. /* match on prefix len */
  1080. LM_DBG("Duplicate gw for index"
  1081. " %d [%d,%d] and current [%d,%d] \n",
  1082. k, matched_gws[k].route_index,
  1083. matched_gws[k].route_index, i, j);
  1084. duplicated_gw = 1;
  1085. if (lcr_rec.prefix_len >
  1086. (*lcrs)[matched_gws[k].route_index].prefix_len) {
  1087. /* Replace the old entry with the new one */
  1088. LM_DBG("Replace [%d,%d]"
  1089. " with [%d,%d] on index %d:"
  1090. " prefix reason %d>%d\n",
  1091. matched_gws[k].route_index,
  1092. matched_gws[k].gw_index, i, j, k,
  1093. lcr_rec.prefix_len,
  1094. (*lcrs)[matched_gws[k].route_index].prefix_len);
  1095. matched_gws[k].route_index = i;
  1096. matched_gws[k].gw_index = j;
  1097. /* Stop searching in the matched_gws list */
  1098. break;
  1099. } else if (lcr_rec.prefix_len ==
  1100. (*lcrs)[matched_gws[k].route_index].prefix_len) {
  1101. if (lcr_rec.priority >
  1102. (*lcrs)[matched_gws[k].route_index].priority) {
  1103. /* Replace the old entry with the new one */
  1104. LM_DBG("Replace [%d,%d] with"
  1105. " [%d,%d] on index %d:"
  1106. " priority reason %d>%d\n",
  1107. matched_gws[k].route_index,
  1108. matched_gws[k].gw_index,
  1109. i, j, k, lcr_rec.priority,
  1110. (*lcrs)[matched_gws[k].route_index].priority);
  1111. matched_gws[k].route_index = i;
  1112. matched_gws[k].gw_index = j;
  1113. /* Stop searching in the matched_gws list */
  1114. break;
  1115. }
  1116. }
  1117. }
  1118. }
  1119. if (duplicated_gw == 0) {
  1120. /* This is a new gw */
  1121. matched_gws[gw_index].route_index = i;
  1122. matched_gws[gw_index].gw_index = j;
  1123. LM_DBG("Added matched_gws[%d]=[%d,%d]\n",
  1124. gw_index, i, j);
  1125. gw_index++;
  1126. } else {
  1127. duplicated_gw = 0;
  1128. }
  1129. }
  1130. }
  1131. }
  1132. }
  1133. }
  1134. matched_gws[gw_index].route_index = -1;
  1135. matched_gws[gw_index].gw_index = -1;
  1136. /*
  1137. * Sort the gateways based on:
  1138. * 1. prefix len
  1139. * 2. priority
  1140. */
  1141. qsort(matched_gws, gw_index, sizeof(struct mi), comp_lcrs);
  1142. randomizer_start = 0;
  1143. /* Randomizing the gateways with same prefix_len and same priority */
  1144. randomizer_flag = 0;
  1145. prefix_len = (*lcrs)[matched_gws[0].route_index].prefix_len;
  1146. priority = (*lcrs)[matched_gws[0].route_index].priority;
  1147. for (i = 1; i < gw_index; i++) {
  1148. if ( prefix_len == (*lcrs)[matched_gws[i].route_index].prefix_len &&
  1149. priority == (*lcrs)[matched_gws[i].route_index].priority) {
  1150. /* we have a match */
  1151. if (randomizer_flag == 0) {
  1152. randomizer_flag = 1;
  1153. randomizer_start = i - 1;
  1154. }
  1155. matched_gws[i - 1].randomizer = rand();
  1156. }
  1157. else {
  1158. if (randomizer_flag == 1) {
  1159. randomizer_end = i - 1;
  1160. randomizer_flag = 0;
  1161. qsort(&matched_gws[randomizer_start],
  1162. randomizer_end - randomizer_start + 1,
  1163. sizeof(struct mi), rand_lcrs);
  1164. }
  1165. prefix_len = (*lcrs)[matched_gws[i].route_index].prefix_len;
  1166. priority = (*lcrs)[matched_gws[i].route_index].priority;
  1167. }
  1168. }
  1169. if (randomizer_flag == 1) {
  1170. randomizer_end = gw_index - 1;
  1171. matched_gws[i - 1].randomizer = rand();
  1172. qsort(&matched_gws[randomizer_start],
  1173. randomizer_end - randomizer_start + 1,
  1174. sizeof(struct mi), rand_lcrs);
  1175. }
  1176. for (i = 0; i < MAX_NO_OF_GWS; i++) {
  1177. index = matched_gws[i].gw_index;
  1178. if (index == -1) {
  1179. break;
  1180. }
  1181. addr = (*gws)[index].ip_addr;
  1182. port = (*gws)[index].port;
  1183. scheme = (*gws)[index].scheme;
  1184. transport = (*gws)[index].transport;
  1185. dm = (*gws)[index].dm;
  1186. strip = (*gws)[index].strip;
  1187. if (strip > ruri_user.len) {
  1188. LM_ERR("Strip count of gw is too large <%u>\n", strip);
  1189. goto skip;
  1190. }
  1191. strip_string = int2str(strip, &strip_len);
  1192. prefix_len = (*gws)[index].prefix_len;
  1193. prefix = (*gws)[index].prefix;
  1194. if (6 + prefix_len + 1 + strip_len + 1 + 15 + 1 + 5 + 1 + 14 >
  1195. MAX_URI_SIZE) {
  1196. LM_ERR("Request URI would be too long\n");
  1197. goto skip;
  1198. }
  1199. at = (char *)&(ruri[0]);
  1200. if (dm == 0)
  1201. *at = '0';
  1202. else
  1203. *at = '1';
  1204. at = at + 1;
  1205. if (scheme == SIP_URI_T) {
  1206. memcpy(at, "sip:", 4); at = at + 4;
  1207. } else if (scheme == SIPS_URI_T) {
  1208. memcpy(at, "sips:", 5); at = at + 5;
  1209. } else {
  1210. LM_ERR("Unknown or unsupported URI scheme <%u>\n",
  1211. (unsigned int)scheme);
  1212. goto skip;
  1213. }
  1214. if (prefix_len) {
  1215. memcpy(at, prefix, prefix_len); at = at + prefix_len;
  1216. }
  1217. /* Add strip in this form |number.
  1218. * For example: |3 means strip first 3 characters.
  1219. */
  1220. *at = '|'; at = at + 1;
  1221. memcpy(at, strip_string, strip_len);
  1222. at = at + strip_len;
  1223. *at = '@'; at = at + 1;
  1224. address.af = AF_INET;
  1225. address.len = 4;
  1226. address.u.addr32[0] = addr;
  1227. addr_str.s = ip_addr2a(&address);
  1228. addr_str.len = strlen(addr_str.s);
  1229. memcpy(at, addr_str.s, addr_str.len); at = at + addr_str.len;
  1230. if (port != 0) {
  1231. if (port > 65536) {
  1232. LM_ERR("Port of GW is too large <%u>\n", port);
  1233. goto skip;
  1234. }
  1235. *at = ':'; at = at + 1;
  1236. port_str.s = int2str(port, &port_str.len);
  1237. memcpy(at, port_str.s, port_str.len); at = at + port_str.len;
  1238. }
  1239. if (transport != PROTO_NONE) {
  1240. memcpy(at, ";transport=", 11); at = at + 11;
  1241. if (transport == PROTO_UDP) {
  1242. memcpy(at, "udp", 3); at = at + 3;
  1243. } else if (transport == PROTO_TCP) {
  1244. memcpy(at, "tcp", 3); at = at + 3;
  1245. } else if (transport == PROTO_TLS) {
  1246. memcpy(at, "tls", 3); at = at + 3;
  1247. } else if (transport == PROTO_SCTP) {
  1248. memcpy(at, "sctp", 4); at = at + 4;
  1249. } else {
  1250. LM_ERR("Unknown or unsupported transport <%u>\n",
  1251. (unsigned int)transport);
  1252. goto skip;
  1253. }
  1254. }
  1255. value.s = (char *)&(ruri[0]);
  1256. value.len = at - value.s;
  1257. val.s = value;
  1258. add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val);
  1259. LM_DBG("Added gw_uri_avp <%.*s>\n", value.len, value.s);
  1260. skip:
  1261. continue;
  1262. }
  1263. return 1;
  1264. }
  1265. /*
  1266. * Load info of matching GWs from database to gw_uri AVPs
  1267. * taking into account the given group id.
  1268. */
  1269. int load_gws_grp(struct sip_msg* _m, char* _s1, char* _s2)
  1270. {
  1271. str grp_s;
  1272. unsigned int grp_id;
  1273. if(((pv_elem_p)_s1)->spec.getf!=NULL)
  1274. {
  1275. if(pv_printf_s(_m, (pv_elem_p)_s1, &grp_s)!=0)
  1276. return -1;
  1277. if(str2int(&grp_s, &grp_id)!=0)
  1278. return -1;
  1279. } else {
  1280. grp_id = ((pv_elem_p)_s1)->spec.pvp.pvn.u.isname.name.n;
  1281. }
  1282. if (grp_id > 0) return do_load_gws(_m, (int)grp_id);
  1283. else return -1;
  1284. }
  1285. /*
  1286. * Load info of matching GWs from database to gw_uri AVPs
  1287. * ignoring the group id.
  1288. */
  1289. int load_gws(struct sip_msg* _m, char* _s1, char* _s2)
  1290. {
  1291. return do_load_gws(_m, -1);
  1292. }
  1293. /*
  1294. * If called from request route block, rewrites scheme, host, port, and
  1295. * transport parts of R-URI based on first gw_uri AVP value, which is then
  1296. * destroyed. Also saves R-URI user to ruri_user AVP for later use in
  1297. * failure route block.
  1298. * If called from failure route block, appends a new branch to request
  1299. * where scheme, host, port, and transport of URI are taken from the first
  1300. * gw_uri AVP value, which is then destroyed. URI user is taken from
  1301. * ruri_user AVP value saved earlier.
  1302. * Returns 1 upon success and -1 upon failure.
  1303. */
  1304. int next_gw(struct sip_msg* _m, char* _s1, char* _s2)
  1305. {
  1306. int_str gw_uri_val, ruri_user_val, val;
  1307. struct action act;
  1308. struct usr_avp *gu_avp, *ru_avp;
  1309. int rval;
  1310. str new_ruri;
  1311. char *at, *at_char, *strip_char, *endptr;
  1312. unsigned int strip;
  1313. gu_avp = search_first_avp(gw_uri_avp_type, gw_uri_avp, &gw_uri_val, 0);
  1314. if (!gu_avp) return -1;
  1315. /* Set dm_flag based on first char of gw_uri */
  1316. if (*(gw_uri_val.s.s) == '0')
  1317. resetflag(_m, dm_flag);
  1318. else
  1319. setflag(_m, dm_flag);
  1320. gw_uri_val.s.s = gw_uri_val.s.s + 1;
  1321. gw_uri_val.s.len = gw_uri_val.s.len - 1;
  1322. if (route_type == REQUEST_ROUTE) {
  1323. /* Create new Request-URI taking URI user from current Request-URI
  1324. and other parts of from gw_uri AVP. */
  1325. if (parse_sip_msg_uri(_m) < 0) {
  1326. LM_ERR("Parsing of R-URI failed\n");
  1327. return -1;
  1328. }
  1329. new_ruri.s = pkg_malloc(gw_uri_val.s.len + _m->parsed_uri.user.len);
  1330. if (!new_ruri.s) {
  1331. LM_ERR("No memory for new R-URI\n");
  1332. return -1;
  1333. }
  1334. at_char = memchr(gw_uri_val.s.s, '@', gw_uri_val.s.len);
  1335. if (!at_char) {
  1336. pkg_free(new_ruri.s);
  1337. LM_ERR("No @ in gateway URI <%.*s>\n",
  1338. gw_uri_val.s.len, gw_uri_val.s.s);
  1339. return -1;
  1340. }
  1341. strip_char = memchr(gw_uri_val.s.s, '|', gw_uri_val.s.len);
  1342. if (!strip_char || strip_char + 1 >= at_char) {
  1343. pkg_free(new_ruri.s);
  1344. LM_ERR("No strip character | and at least one "
  1345. "character before @ in gateway URI <%.*s>\n",
  1346. gw_uri_val.s.len, gw_uri_val.s.s);
  1347. return -1;
  1348. }
  1349. at = new_ruri.s;
  1350. memcpy(at, gw_uri_val.s.s, strip_char - gw_uri_val.s.s);
  1351. at = at + (strip_char - gw_uri_val.s.s);
  1352. strip = strtol(strip_char + 1, &endptr, 10);
  1353. if (endptr != at_char) {
  1354. pkg_free(new_ruri.s);
  1355. LM_ERR("Non-digit char between | and @ chars in gw URI <%.*s>\n",
  1356. gw_uri_val.s.len, gw_uri_val.s.s);
  1357. return -1;
  1358. }
  1359. if (_m->parsed_uri.user.len - strip > 0) {
  1360. memcpy(at, _m->parsed_uri.user.s + strip,
  1361. _m->parsed_uri.user.len - strip);
  1362. at = at + _m->parsed_uri.user.len - strip;
  1363. }
  1364. if (*(at - 1) != ':') {
  1365. memcpy(at, at_char, gw_uri_val.s.len - (at_char - gw_uri_val.s.s));
  1366. at = at + gw_uri_val.s.len - (at_char - gw_uri_val.s.s);
  1367. } else {
  1368. memcpy(at, at_char + 1, gw_uri_val.s.len -
  1369. (at_char + 1 - gw_uri_val.s.s));
  1370. at = at + gw_uri_val.s.len - (at_char + 1 - gw_uri_val.s.s);
  1371. }
  1372. *at = '\0';
  1373. /* Save Request-URI user for use in FAILURE_ROUTE */
  1374. val.s = _m->parsed_uri.user;
  1375. add_avp(ruri_user_avp_type|AVP_VAL_STR, ruri_user_avp, val);
  1376. LM_DBG("Added ruri_user_avp <%.*s>\n", val.s.len, val.s.s);
  1377. /* Rewrite Request URI */
  1378. act.type = SET_URI_T;
  1379. act.elem[0].type = STRING_ST;
  1380. act.elem[0].u.string = new_ruri.s;
  1381. rval = do_action(&act, _m);
  1382. pkg_free(new_ruri.s);
  1383. destroy_avp(gu_avp);
  1384. if (rval != 1) {
  1385. LM_ERR("Calling do_action failed with return value <%d>\n", rval);
  1386. return -1;
  1387. }
  1388. return 1;
  1389. } else if (route_type == FAILURE_ROUTE) {
  1390. /* Create new Request-URI taking URI user from ruri_user AVP
  1391. and other parts of from gateway URI AVP. */
  1392. ru_avp = search_first_avp(ruri_user_avp_type, ruri_user_avp,
  1393. &ruri_user_val, 0);
  1394. if (!ru_avp) {
  1395. LM_ERR("No ruri_user AVP\n");
  1396. return -1;
  1397. }
  1398. new_ruri.s = pkg_malloc(gw_uri_val.s.len + _m->parsed_uri.user.len);
  1399. if (!new_ruri.s) {
  1400. LM_ERR("No memory for new R-URI.\n");
  1401. return -1;
  1402. }
  1403. at_char = memchr(gw_uri_val.s.s, '@', gw_uri_val.s.len);
  1404. if (!at_char) {
  1405. pkg_free(new_ruri.s);
  1406. LM_ERR("No @ in gateway URI <%.*s>\n",
  1407. gw_uri_val.s.len, gw_uri_val.s.s);
  1408. return -1;
  1409. }
  1410. strip_char = memchr(gw_uri_val.s.s, '|', gw_uri_val.s.len);
  1411. if (!strip_char || strip_char + 1 >= at_char) {
  1412. pkg_free(new_ruri.s);
  1413. LM_ERR("No strip char | and at least one "
  1414. "char before @ in gateway URI <%.*s>\n",
  1415. gw_uri_val.s.len, gw_uri_val.s.s);
  1416. return -1;
  1417. }
  1418. at = new_ruri.s;
  1419. memcpy(at, gw_uri_val.s.s, strip_char - gw_uri_val.s.s);
  1420. at = at + (strip_char - gw_uri_val.s.s);
  1421. strip = strtol(strip_char + 1, &endptr, 10);
  1422. if (endptr != at_char) {
  1423. pkg_free(new_ruri.s);
  1424. LM_ERR("Non-digit char between | and @ chars in gw URI <%.*s>\n",
  1425. gw_uri_val.s.len, gw_uri_val.s.s);
  1426. return -1;
  1427. }
  1428. if (ruri_user_val.s.len - strip > 0) {
  1429. memcpy(at, ruri_user_val.s.s + strip,
  1430. ruri_user_val.s.len - strip);
  1431. at = at + ruri_user_val.s.len - strip;
  1432. }
  1433. if (*(at - 1) != ':') {
  1434. memcpy(at, at_char, gw_uri_val.s.len - (at_char - gw_uri_val.s.s));
  1435. at = at + gw_uri_val.s.len - (at_char - gw_uri_val.s.s);
  1436. } else {
  1437. memcpy(at, at_char + 1, gw_uri_val.s.len -
  1438. (at_char + 1 - gw_uri_val.s.s));
  1439. at = at + gw_uri_val.s.len - (at_char + 1 - gw_uri_val.s.s);
  1440. }
  1441. new_ruri.len = at - new_ruri.s;
  1442. act.type = APPEND_BRANCH_T;
  1443. act.elem[0].type = STRING_ST;
  1444. act.elem[0].u.s = new_ruri;
  1445. act.elem[1].type = NUMBER_ST;
  1446. act.elem[1].u.number = 0;
  1447. rval = do_action(&act, _m);
  1448. pkg_free(new_ruri.s);
  1449. destroy_avp(gu_avp);
  1450. if (rval != 1) {
  1451. LM_ERR("Calling do_action failed with return value <%d>\n", rval);
  1452. return -1;
  1453. }
  1454. return 1;
  1455. }
  1456. /* unsupported route type */
  1457. LM_ERR("Unsupported route type\n");
  1458. return -1;
  1459. }
  1460. /*
  1461. * Checks if request comes from a gateway
  1462. */
  1463. static int do_from_gw(struct sip_msg* _m, int grp_id)
  1464. {
  1465. int i;
  1466. unsigned int src_addr;
  1467. src_addr = _m->rcv.src_ip.u.addr32[0];
  1468. for (i = 0; i < MAX_NO_OF_GWS; i++) {
  1469. if ((*gws)[i].ip_addr == 0) {
  1470. return -1;
  1471. }
  1472. if ((*gws)[i].ip_addr == src_addr &&
  1473. (grp_id < 0 || (*gws)[i].grp_id == grp_id)) {
  1474. if ((*gws)[i].dm == 0)
  1475. resetflag(_m, dm_flag);
  1476. else
  1477. setflag(_m, dm_flag);
  1478. return 1;
  1479. }
  1480. }
  1481. return -1;
  1482. }
  1483. /*
  1484. * Checks if request comes from a gateway, taking
  1485. * into account the group id.
  1486. */
  1487. int from_gw_grp(struct sip_msg* _m, char* _s1, char* _s2)
  1488. {
  1489. int grp_id;
  1490. grp_id = (int)(long)_s1;
  1491. return do_from_gw(_m, grp_id);
  1492. }
  1493. /*
  1494. * Checks if request comes from a gateway, ignoring
  1495. * the group id.
  1496. */
  1497. int from_gw(struct sip_msg* _m, char* _s1, char* _s2)
  1498. {
  1499. return do_from_gw(_m, -1);
  1500. }
  1501. /*
  1502. * Checks if in-dialog request goes to gateway
  1503. */
  1504. static int do_to_gw(struct sip_msg* _m, int grp_id)
  1505. {
  1506. char host[16];
  1507. struct in_addr addr;
  1508. unsigned int i;
  1509. if((_m->parsed_uri_ok == 0) && (parse_sip_msg_uri(_m) < 0)) {
  1510. LM_ERR("Error while parsing the R-URI\n");
  1511. return -1;
  1512. }
  1513. if (_m->parsed_uri.host.len > 15) {
  1514. return -1;
  1515. }
  1516. memcpy(host, _m->parsed_uri.host.s, _m->parsed_uri.host.len);
  1517. host[_m->parsed_uri.host.len] = 0;
  1518. if (!inet_aton(host, &addr)) {
  1519. return -1;
  1520. }
  1521. for (i = 0; i < MAX_NO_OF_GWS; i++) {
  1522. if ((*gws)[i].ip_addr == 0) {
  1523. return -1;
  1524. }
  1525. if ((*gws)[i].ip_addr == addr.s_addr &&
  1526. (grp_id < 0 || (*gws)[i].grp_id == grp_id)) {
  1527. return 1;
  1528. }
  1529. }
  1530. return -1;
  1531. }
  1532. /*
  1533. * Checks if in-dialog request goes to gateway, taking
  1534. * into account the group id.
  1535. */
  1536. int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2)
  1537. {
  1538. int grp_id;
  1539. grp_id = (int)(long)_s1;
  1540. return do_to_gw(_m, grp_id);
  1541. }
  1542. /*
  1543. * Checks if in-dialog request goes to gateway, ignoring
  1544. * the group id.
  1545. */
  1546. int to_gw(struct sip_msg* _m, char* _s1, char* _s2)
  1547. {
  1548. return do_to_gw(_m, -1);
  1549. }
  1550. /*
  1551. * Frees contact list used by load_contacts function
  1552. */
  1553. static inline void free_contact_list(struct contact *curr) {
  1554. struct contact *prev;
  1555. while (curr) {
  1556. prev = curr;
  1557. curr = curr->next;
  1558. pkg_free(prev);
  1559. }
  1560. }
  1561. /* Encode branch info from contact struct to str */
  1562. inline int encode_branch_info(str *info, struct contact *con)
  1563. {
  1564. char *at, *s;
  1565. int len;
  1566. info->len = con->uri.len + con->dst_uri.len +
  1567. con->path.len + MAX_SOCKET_STR + INT2STR_MAX_LEN + 5;
  1568. info->s = pkg_malloc(info->len);
  1569. if (!info->s) {
  1570. LM_ERR("No memory left for branch info\n");
  1571. return 0;
  1572. }
  1573. at = info->s;
  1574. memcpy(at, con->uri.s, con->uri.len);
  1575. at = at + con->uri.len;
  1576. *at = '\n';
  1577. at++;
  1578. memcpy(at, con->dst_uri.s, con->dst_uri.len);
  1579. at = at + con->dst_uri.len;
  1580. *at = '\n';
  1581. at++;
  1582. memcpy(at, con->path.s, con->path.len);
  1583. at = at + con->path.len;
  1584. *at = '\n';
  1585. at++;
  1586. if (con->sock) {
  1587. len = MAX_SOCKET_STR;
  1588. if (!socket2str(con->sock, at, &len)) {
  1589. LM_ERR("Failed to convert socket to str\n");
  1590. return 0;
  1591. }
  1592. } else {
  1593. len = 0;
  1594. }
  1595. at = at + len;
  1596. *at = '\n';
  1597. at++;
  1598. s = int2str(con->flags, &len);
  1599. memcpy(at, s, len);
  1600. at = at + len;
  1601. *at = '\n';
  1602. info->len = at - info->s + 1;
  1603. return 1;
  1604. }
  1605. /* Encode branch info from str */
  1606. inline int decode_branch_info(char *info, str *uri, str *dst, str *path,
  1607. struct socket_info **sock, unsigned int *flags)
  1608. {
  1609. str s, host;
  1610. int port, proto;
  1611. char *pos, *at;
  1612. pos = strchr(info, '\n');
  1613. uri->len = pos - info;
  1614. if (uri->len) {
  1615. uri->s = info;
  1616. } else {
  1617. uri->s = 0;
  1618. }
  1619. at = pos + 1;
  1620. pos = strchr(at, '\n');
  1621. dst->len = pos - at;
  1622. if (dst->len) {
  1623. dst->s = at;
  1624. } else {
  1625. dst->s = 0;
  1626. }
  1627. at = pos + 1;
  1628. pos = strchr(at, '\n');
  1629. path->len = pos - at;
  1630. if (path->len) {
  1631. path->s = at;
  1632. } else {
  1633. path->s = 0;
  1634. }
  1635. at = pos + 1;
  1636. pos = strchr(at, '\n');
  1637. s.len = pos - at;
  1638. if (s.len) {
  1639. s.s = at;
  1640. if (parse_phostport(s.s, s.len, &host.s, &host.len,
  1641. &port, &proto) != 0) {
  1642. LM_ERR("Parsing of socket info <%.*s> failed\n", s.len, s.s);
  1643. return 0;
  1644. }
  1645. *sock = grep_sock_info(&host, (unsigned short)port,
  1646. (unsigned short)proto);
  1647. if (*sock == 0) {
  1648. LM_ERR("Invalid socket <%.*s>\n", s.len, s.s);
  1649. return 0;
  1650. }
  1651. } else {
  1652. *sock = 0;
  1653. }
  1654. at = pos + 1;
  1655. pos = strchr(at, '\n');
  1656. s.len = pos - at;
  1657. if (s.len) {
  1658. s.s = at;
  1659. if (str2int(&s, flags) != 0) {
  1660. LM_ERR("Failed to decode flags <%.*s>\n", s.len, s.s);
  1661. return 0;
  1662. }
  1663. } else {
  1664. *flags = 0;
  1665. }
  1666. return 1;
  1667. }
  1668. /*
  1669. * Loads contacts in destination set into "lcr_contact" AVP in reverse
  1670. * priority order and associated each contact with Q_FLAG telling if
  1671. * contact is the last one in its priority class. Finally, removes
  1672. * all branches from destination set.
  1673. */
  1674. int load_contacts(struct sip_msg* msg, char* key, char* value)
  1675. {
  1676. str uri, dst_uri, path, branch_info, *ruri;
  1677. qvalue_t q, ruri_q;
  1678. struct contact *contacts, *next, *prev, *curr;
  1679. int_str val;

Large files files are truncated, but you can click here to view the full file