Wed, 10 Feb 2010 21:14:04 +0100
Import unmodified vendor sources for correction and improvement.
1 /*
2 * $Id: lcr_mod.c 6015 2009-08-22 21:45:06Z bogdan_iancu $
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 opensips, a free SIP server.
10 *
11 * opensips 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 * opensips 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 */
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45 #include <regex.h>
46 #include "../../sr_module.h"
47 #include "../../dprint.h"
48 #include "../../ut.h"
49 #include "../../error.h"
50 #include "../../mem/mem.h"
51 #include "../../mem/shm_mem.h"
52 #include "../../db/db.h"
53 #include "../../usr_avp.h"
54 #include "../../parser/parse_uri.h"
55 #include "../../parser/parse_from.h"
56 #include "../../parser/msg_parser.h"
57 #include "../../action.h"
58 #include "../../qvalue.h"
59 #include "../../dset.h"
60 #include "../../ip_addr.h"
61 #include "../../resolve.h"
62 #include "../../mi/mi.h"
63 #include "../../mod_fix.h"
64 #include "../../socket_info.h"
65 #include "../../pvar.h"
66 #include "../../mod_fix.h"
67 #include "mi.h"
71 /*
72 * Version of gw and lcr tables required by the module,
73 * increment this value if you change the table in
74 * an backwards incompatible way
75 */
76 #define GW_TABLE_VERSION 8
77 #define LCR_TABLE_VERSION 3
79 /* usr_avp flag for sequential forking */
80 #define Q_FLAG (1<<2)
82 static void destroy(void); /* Module destroy function */
83 static int mi_child_init(void);
84 static int mod_init(void); /* Module initialization function */
85 static int fixstringloadgws(void **param, int param_count);
87 int reload_gws ( void );
89 #define GW_TABLE "gw"
91 #define GW_NAME_COL "gw_name"
93 #define GRP_ID_COL "grp_id"
95 #define IP_ADDR_COL "ip_addr"
97 #define PORT_COL "port"
99 #define URI_SCHEME_COL "uri_scheme"
101 #define TRANSPORT_COL "transport"
103 #define STRIP_COL "strip"
105 #define TAG_COL "tag"
107 #define FLAGS_COL "flags"
109 #define LCR_TABLE "lcr"
111 #define PREFIX_COL "prefix"
113 #define FROM_URI_COL "from_uri"
115 #define PRIORITY_COL "priority"
117 #define MAX_NO_OF_GWS 32
118 #define MAX_NO_OF_LCRS 256
119 #define MAX_PREFIX_LEN 256
120 #define MAX_TAG_LEN 16
121 #define MAX_FROM_URI_LEN 256
123 /* Default module parameter values */
124 #define DEF_FR_INV_TIMER 90
125 #define DEF_FR_INV_TIMER_NEXT 30
126 #define DEF_PREFIX_MODE 0
128 /*
129 * Type definitions
130 */
132 typedef enum sip_protos uri_transport;
134 struct gw_info {
135 unsigned int ip_addr;
136 unsigned int port;
137 unsigned int grp_id;
138 uri_type scheme;
139 uri_transport transport;
140 unsigned int strip;
141 char tag[MAX_TAG_LEN + 1];
142 unsigned short tag_len;
143 unsigned int flags;
144 };
146 struct lcr_info {
147 char prefix[MAX_PREFIX_LEN + 1];
148 unsigned short prefix_len;
149 char from_uri[MAX_FROM_URI_LEN + 1];
150 unsigned short from_uri_len;
151 unsigned int grp_id;
152 unsigned short priority;
153 unsigned short end_record;
154 };
156 struct prefix_regex {
157 regex_t re;
158 short int valid;
159 };
161 struct from_uri_regex {
162 regex_t re;
163 short int valid;
164 };
166 struct mi {
167 int gw_index;
168 int route_index;
169 int randomizer;
170 };
173 /*
174 * Database variables
175 */
176 static db_con_t* db_handle = 0; /* Database connection handle */
177 static db_func_t lcr_dbf;
179 /*
180 * Module parameter variables
181 */
183 /* database */
184 static str db_url = str_init(DEFAULT_RODB_URL);
185 static str gw_table = str_init(GW_TABLE);
186 static str gw_name_col = str_init(GW_NAME_COL);
187 static str grp_id_col = str_init(GRP_ID_COL);
188 static str ip_addr_col = str_init(IP_ADDR_COL);
189 static str port_col = str_init(PORT_COL);
190 static str uri_scheme_col = str_init(URI_SCHEME_COL);
191 static str transport_col = str_init(TRANSPORT_COL);
192 static str strip_col = str_init(STRIP_COL);
193 static str tag_col = str_init(TAG_COL);
194 static str flags_col = str_init(FLAGS_COL);
195 static str lcr_table = str_init(LCR_TABLE);
196 static str prefix_col = str_init(PREFIX_COL);
197 static str from_uri_col = str_init(FROM_URI_COL);
198 static str priority_col = str_init(PRIORITY_COL);
200 /* timer */
201 int fr_inv_timer = DEF_FR_INV_TIMER;
202 int fr_inv_timer_next = DEF_FR_INV_TIMER_NEXT;
204 /* avps */
205 static char *fr_inv_timer_avp_param = NULL;
206 static char *gw_uri_avp_param = NULL;
207 static char *ruri_user_avp_param = NULL;
208 static char *contact_avp_param = NULL;
209 static char *rpid_avp_param = NULL;
210 static char *flags_avp_param = NULL;
212 /* prefix mode */
213 int prefix_mode_param = DEF_PREFIX_MODE;
215 /*
216 * Other module types and variables
217 */
219 struct contact {
220 str uri;
221 qvalue_t q;
222 str dst_uri;
223 str path;
224 unsigned int flags;
225 struct socket_info* sock;
226 unsigned short q_flag;
227 struct contact *next;
228 };
230 static int fr_inv_timer_avp_type;
231 static int_str fr_inv_timer_avp;
232 static int gw_uri_avp_type;
233 static int_str gw_uri_avp;
234 static int ruri_user_avp_type;
235 static int_str ruri_user_avp;
236 static int contact_avp_type;
237 static int_str contact_avp;
238 static int rpid_avp_type;
239 static int_str rpid_avp;
240 static int flags_avp_type;
241 static int_str flags_avp;
243 struct gw_info **gws; /* Pointer to current gw table pointer */
244 struct gw_info *gws_1; /* Pointer to gw table 1 */
245 struct gw_info *gws_2; /* Pointer to gw table 2 */
247 struct lcr_info **lcrs; /* Pointer to current lcr table pointer */
248 struct lcr_info *lcrs_1; /* Pointer to lcr table 1 */
249 struct lcr_info *lcrs_2; /* Pointer to lcr table 2 */
251 unsigned int *lcrs_ws_reload_counter;
252 unsigned int reload_counter;
254 struct prefix_regex prefix_reg[MAX_NO_OF_LCRS];
255 struct from_uri_regex from_uri_reg[MAX_NO_OF_LCRS];
257 /*
258 * Module functions that are defined later
259 */
260 static int load_gws_0(struct sip_msg* _m, char* _s1, char* _s2);
261 static int load_gws_1(struct sip_msg* _m, char* _s1, char* _s2);
262 static int load_gws_from_grp(struct sip_msg* _m, char* _s1, char* _s2);
263 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2);
264 static int from_gw_0(struct sip_msg* _m, char* _s1, char* _s2);
265 static int from_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
266 static int from_gw_grp(struct sip_msg* _m, char* _s1, char* _s2);
267 static int to_gw(struct sip_msg* _m, char* _s1, char* _s2);
268 static int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2);
269 static int load_contacts (struct sip_msg*, char*, char*);
270 static int next_contacts (struct sip_msg*, char*, char*);
273 /*
274 * Exported functions
275 */
276 static cmd_export_t cmds[] = {
277 {"load_gws", (cmd_function)load_gws_0, 0, 0, 0, REQUEST_ROUTE},
278 {"load_gws", (cmd_function)load_gws_1, 1, fixup_pvar_null,
279 fixup_free_pvar_null, REQUEST_ROUTE},
280 {"load_gws_from_grp", (cmd_function)load_gws_from_grp, 1,
281 fixstringloadgws, 0, REQUEST_ROUTE},
282 {"next_gw", (cmd_function)next_gw, 0, 0, 0,
283 REQUEST_ROUTE | FAILURE_ROUTE},
284 {"from_gw", (cmd_function)from_gw_0, 0, 0, 0,
285 REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
286 {"from_gw", (cmd_function)from_gw_1, 1, fixup_pvar_null,
287 fixup_free_pvar_null, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
288 {"from_gw_grp", (cmd_function)from_gw_grp, 1, fixup_uint_null, 0,
289 REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
290 {"to_gw", (cmd_function)to_gw, 0, 0, 0,
291 REQUEST_ROUTE | FAILURE_ROUTE},
292 {"to_gw", (cmd_function)to_gw_grp, 1, fixup_uint_null, 0,
293 REQUEST_ROUTE | FAILURE_ROUTE},
294 {"load_contacts", (cmd_function)load_contacts, 0, 0, 0,
295 REQUEST_ROUTE},
296 {"next_contacts", (cmd_function)next_contacts, 0, 0, 0,
297 REQUEST_ROUTE | FAILURE_ROUTE},
298 {0, 0, 0, 0, 0, 0}
299 };
302 /*
303 * Exported parameters
304 */
305 static param_export_t params[] = {
306 {"db_url", STR_PARAM, &db_url.s },
307 {"gw_table", STR_PARAM, &gw_table.s },
308 {"gw_name_column", STR_PARAM, &gw_name_col.s },
309 {"grp_id_column", STR_PARAM, &grp_id_col.s },
310 {"ip_addr_column", STR_PARAM, &ip_addr_col.s },
311 {"port_column", STR_PARAM, &port_col.s },
312 {"uri_scheme_column", STR_PARAM, &uri_scheme_col.s },
313 {"transport_column", STR_PARAM, &transport_col.s },
314 {"strip_column", STR_PARAM, &strip_col.s },
315 {"tag_column", STR_PARAM, &tag_col.s },
316 {"flags_column", STR_PARAM, &flags_col.s },
317 {"lcr_table", STR_PARAM, &lcr_table.s },
318 {"prefix_column", STR_PARAM, &prefix_col.s },
319 {"from_uri_column", STR_PARAM, &from_uri_col.s },
320 {"priority_column", STR_PARAM, &priority_col.s },
321 {"fr_inv_timer_avp", STR_PARAM, &fr_inv_timer_avp_param },
322 {"gw_uri_avp", STR_PARAM, &gw_uri_avp_param },
323 {"ruri_user_avp", STR_PARAM, &ruri_user_avp_param },
324 {"contact_avp", STR_PARAM, &contact_avp_param },
325 {"rpid_avp", STR_PARAM, &rpid_avp_param },
326 {"flags_avp", STR_PARAM, &flags_avp_param },
327 {"fr_inv_timer", INT_PARAM, &fr_inv_timer },
328 {"fr_inv_timer_next", INT_PARAM, &fr_inv_timer_next },
329 {"prefix_mode", INT_PARAM, &prefix_mode_param },
330 {0, 0, 0}
331 };
334 /*
335 * Exported MI functions
336 */
337 static mi_export_t mi_cmds[] = {
338 { MI_LCR_RELOAD, mi_lcr_reload, MI_NO_INPUT_FLAG, 0, mi_child_init },
339 { MI_LCR_DUMP, mi_lcr_dump, MI_NO_INPUT_FLAG, 0, 0 },
340 { 0, 0, 0, 0 ,0}
341 };
344 /*
345 * Module interface
346 */
347 struct module_exports exports = {
348 "lcr",
349 MODULE_VERSION,
350 DEFAULT_DLFLAGS, /* dlopen flags */
351 cmds, /* Exported functions */
352 params, /* Exported parameters */
353 0, /* exported statistics */
354 mi_cmds, /* exported MI functions */
355 0, /* exported pseudo-variables */
356 0, /* extra processes */
357 mod_init, /* module initialization function */
358 0, /* response function */
359 destroy, /* destroy function */
360 0 /* child initialization function */
361 };
364 static int lcr_db_init(const str* db_url)
365 {
366 if (lcr_dbf.init==0){
367 LM_CRIT("Null lcr_dbf\n");
368 goto error;
369 }
370 db_handle=lcr_dbf.init(db_url);
371 if (db_handle==0){
372 LM_ERR("Unable to connect to the database\n");
373 goto error;
374 }
375 return 0;
376 error:
377 return -1;
378 }
382 static int lcr_db_bind(const str* db_url)
383 {
384 if (db_bind_mod(db_url, &lcr_dbf)<0){
385 LM_ERR("Unable to bind to the database module\n");
386 return -1;
387 }
389 if (!DB_CAPABILITY(lcr_dbf, DB_CAP_QUERY)) {
390 LM_ERR("Database module does not implement 'query' function\n");
391 return -1;
392 }
394 return 0;
395 }
398 static void lcr_db_close(void)
399 {
400 if (db_handle && lcr_dbf.close){
401 lcr_dbf.close(db_handle);
402 db_handle=0;
403 }
404 }
407 static int mi_child_init(void)
408 {
409 return lcr_db_init(&db_url);
410 }
413 /*
414 * Module initialization function that is called before the main process forks
415 */
416 static int mod_init(void)
417 {
418 int i;
419 pv_spec_t avp_spec;
420 str s;
421 unsigned short avp_flags;
423 LM_DBG("Initializing\n");
425 /* Update length of module variables */
426 db_url.len = strlen(db_url.s);
427 gw_table.len = strlen(gw_table.s);
428 gw_name_col.len = strlen(gw_name_col.s);
429 grp_id_col.len = strlen(grp_id_col.s);
430 ip_addr_col.len = strlen(ip_addr_col.s);
431 port_col.len = strlen(port_col.s);
432 uri_scheme_col.len = strlen(uri_scheme_col.s);
433 transport_col.len = strlen(transport_col.s);
434 strip_col.len = strlen(strip_col.s);
435 tag_col.len = strlen(tag_col.s);
436 flags_col.len = strlen(flags_col.s);
437 lcr_table.len = strlen(lcr_table.s);
438 prefix_col.len = strlen(prefix_col.s);
439 from_uri_col.len = strlen(from_uri_col.s);
440 priority_col.len = strlen(priority_col.s);
442 /* Bind database */
443 if (lcr_db_bind(&db_url)) {
444 LM_ERR("No database module found\n");
445 return -1;
446 }
448 /* Check value of prefix_mode */
449 if ((prefix_mode_param != 0) && (prefix_mode_param != 1)) {
450 LM_ERR("Invalid prefix_mode value <%d>\n", prefix_mode_param);
451 return -1;
452 }
454 /* Process AVP params */
455 if (fr_inv_timer_avp_param && *fr_inv_timer_avp_param) {
456 s.s = fr_inv_timer_avp_param; s.len = strlen(s.s);
457 if (pv_parse_spec(&s, &avp_spec)==0
458 || avp_spec.type!=PVT_AVP) {
459 LM_ERR("Malformed or non AVP definition <%s>\n",
460 fr_inv_timer_avp_param);
461 return -1;
462 }
464 if(pv_get_avp_name(0, &(avp_spec.pvp), &fr_inv_timer_avp, &avp_flags)!=0) {
465 LM_ERR("Invalid AVP definition <%s>\n", fr_inv_timer_avp_param);
466 return -1;
467 }
468 fr_inv_timer_avp_type = avp_flags;
469 } else {
470 LM_ERR("AVP fr_inv_timer_avp has not been defined\n");
471 return -1;
472 }
474 if (gw_uri_avp_param && *gw_uri_avp_param) {
475 s.s = gw_uri_avp_param; s.len = strlen(s.s);
476 if (pv_parse_spec(&s, &avp_spec)==0
477 || avp_spec.type!=PVT_AVP) {
478 LM_ERR("Malformed or non AVP definition <%s>\n", gw_uri_avp_param);
479 return -1;
480 }
482 if(pv_get_avp_name(0, &(avp_spec.pvp), &gw_uri_avp, &avp_flags)!=0) {
483 LM_ERR("Invalid AVP definition <%s>\n", gw_uri_avp_param);
484 return -1;
485 }
486 gw_uri_avp_type = avp_flags;
487 } else {
488 LM_ERR("AVP gw_uri_avp has not been defined\n");
489 return -1;
490 }
492 if (ruri_user_avp_param && *ruri_user_avp_param) {
493 s.s = ruri_user_avp_param; s.len = strlen(s.s);
494 if (pv_parse_spec(&s, &avp_spec)==0
495 || avp_spec.type!=PVT_AVP) {
496 LM_ERR("Malformed or non AVP definition <%s>\n",
497 ruri_user_avp_param);
498 return -1;
499 }
501 if(pv_get_avp_name(0, &(avp_spec.pvp), &ruri_user_avp, &avp_flags)!=0) {
502 LM_ERR("Invalid AVP definition <%s>\n", ruri_user_avp_param);
503 return -1;
504 }
505 ruri_user_avp_type = avp_flags;
506 } else {
507 LM_ERR("AVP ruri_user_avp has not been defined\n");
508 return -1;
509 }
511 if (contact_avp_param && *contact_avp_param) {
512 s.s = contact_avp_param; s.len = strlen(s.s);
513 if (pv_parse_spec(&s, &avp_spec)==0
514 || avp_spec.type!=PVT_AVP) {
515 LM_ERR("Malformed or non AVP definition <%s>\n",
516 contact_avp_param);
517 return -1;
518 }
520 if(pv_get_avp_name(0, &(avp_spec.pvp), &contact_avp, &avp_flags)!=0) {
521 LM_ERR("Invalid AVP definition <%s>\n", contact_avp_param);
522 return -1;
523 }
524 contact_avp_type = avp_flags;
525 } else {
526 LM_ERR("AVP contact_avp has not been defined\n");
527 return -1;
528 }
530 if (rpid_avp_param && *rpid_avp_param) {
531 s.s = rpid_avp_param; s.len = strlen(s.s);
532 if (pv_parse_spec(&s, &avp_spec)==0
533 || avp_spec.type!=PVT_AVP) {
534 LM_ERR("Malformed or non AVP definition <%s>\n", rpid_avp_param);
535 return -1;
536 }
538 if(pv_get_avp_name(0, &(avp_spec.pvp), &rpid_avp, &avp_flags)!=0) {
539 LM_ERR("Invalid AVP definition <%s>\n", rpid_avp_param);
540 return -1;
541 }
542 rpid_avp_type = avp_flags;
543 } else {
544 LM_ERR("AVP rpid_avp has not been defined\n");
545 return -1;
546 }
548 if (flags_avp_param && *flags_avp_param) {
549 s.s = flags_avp_param; s.len = strlen(s.s);
550 if (pv_parse_spec(&s, &avp_spec)==0
551 || avp_spec.type!=PVT_AVP) {
552 LM_ERR("Malformed or non AVP definition <%s>\n", flags_avp_param);
553 return -1;
554 }
556 if(pv_get_avp_name(0, &(avp_spec.pvp), &flags_avp, &avp_flags)!=0) {
557 LM_ERR("Invalid AVP definition <%s>\n", flags_avp_param);
558 return -1;
559 }
560 flags_avp_type = avp_flags;
561 } else {
562 LM_ERR("AVP flags_avp has not been defined\n");
563 return -1;
564 }
566 /* Check table version */
567 db_con_t* dbh;
568 if (lcr_dbf.init==0){
569 LM_CRIT("Unbound database\n");
570 return -1;
571 }
572 dbh=lcr_dbf.init(&db_url);
573 if (dbh==0){
574 LM_ERR("Unable to open database connection\n");
575 return -1;
576 }
577 if((db_check_table_version(&lcr_dbf, dbh, &gw_table, GW_TABLE_VERSION) < 0) ||
578 (db_check_table_version(&lcr_dbf, dbh, &lcr_table, LCR_TABLE_VERSION) < 0)) {
579 LM_ERR("error during table version check.\n");
580 lcr_dbf.close(dbh);
581 goto err;
582 }
583 lcr_dbf.close(dbh);
585 /* Initializing gw tables and gw table pointer variable */
586 gws_1 = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
587 (MAX_NO_OF_GWS + 1));
588 if (gws_1 == 0) {
589 LM_ERR("No memory for gw table\n");
590 goto err;
591 }
592 gws_2 = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
593 (MAX_NO_OF_GWS + 1));
594 if (gws_2 == 0) {
595 LM_ERR("No memory for gw table\n");
596 goto err;
597 }
598 for (i = 0; i < MAX_NO_OF_GWS + 1; i++) {
599 gws_1[i].ip_addr = gws_2[i].ip_addr = 0;
600 }
601 gws = (struct gw_info **)shm_malloc(sizeof(struct gw_info *));
602 if (gws == 0) {
603 LM_ERR("No memory for gw table pointer\n");
604 }
605 *gws = gws_1;
607 /* Initializing lcr tables and lcr table pointer variable */
608 lcrs_1 = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info) *
609 (MAX_NO_OF_LCRS + 1));
610 if (lcrs_1 == 0) {
611 LM_ERR("No memory for lcr table\n");
612 goto err;
613 }
614 lcrs_2 = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info) *
615 (MAX_NO_OF_LCRS + 1));
616 if (lcrs_2 == 0) {
617 LM_ERR("No memory for lcr table\n");
618 goto err;
619 }
620 for (i = 0; i < MAX_NO_OF_LCRS + 1; i++) {
621 lcrs_1[i].end_record = lcrs_2[i].end_record = 0;
622 }
623 lcrs = (struct lcr_info **)shm_malloc(sizeof(struct lcr_info *));
624 if (lcrs == 0) {
625 LM_ERR("No memory for lcr table pointer\n");
626 goto err;
627 }
628 *lcrs = lcrs_1;
630 lcrs_ws_reload_counter = (unsigned int *)shm_malloc(sizeof(unsigned int));
631 if (lcrs_ws_reload_counter == 0) {
632 LM_ERR("No memory for reload counter\n");
633 goto err;
634 }
635 *lcrs_ws_reload_counter = reload_counter = 0;
637 memset(prefix_reg, 0, sizeof(struct prefix_regex) * MAX_NO_OF_LCRS);
638 memset(from_uri_reg, 0, sizeof(struct from_uri_regex) * MAX_NO_OF_LCRS);
640 /* First reload */
641 if (reload_gws() == -1) {
642 LM_CRIT("Failed to reload gateways and routes\n");
643 goto err;
644 }
646 return 0;
648 err:
649 return -1;
650 }
653 static void destroy(void)
654 {
655 lcr_db_close();
656 }
658 /*
659 * Sort lcr records by prefix_len and priority.
660 */
661 static int comp_lcrs(const void *m1, const void *m2)
662 {
663 int result = -1;
665 struct mi *mi1 = (struct mi *) m1;
666 struct mi *mi2 = (struct mi *) m2;
668 struct lcr_info lcr_record1 = (*lcrs)[mi1->route_index];
669 struct lcr_info lcr_record2 = (*lcrs)[mi2->route_index];
671 if (prefix_mode_param == 0) {
672 /* Sort by prefix. */
673 if (lcr_record1.prefix_len > lcr_record2.prefix_len) {
674 result = 1;
675 } else if (lcr_record1.prefix_len == lcr_record2.prefix_len) {
676 /* Sort by priority. */
677 if (lcr_record1.priority < lcr_record2.priority) {
678 result = 1;
679 } else if (lcr_record1.priority == lcr_record2.priority) {
680 /* Nothing to do. */
681 result = 0;
682 }
683 }
684 } else {
685 if (lcr_record1.priority < lcr_record2.priority) {
686 result = 1;
687 } else if (lcr_record1.priority == lcr_record2.priority) {
688 /* Nothing to do. */
689 result = 0;
690 }
691 }
693 return result;
694 }
696 /*
697 * Sort lcr records by rand table.
698 */
699 static int rand_lcrs(const void *m1, const void *m2)
700 {
701 int result = -1;
703 struct mi mi1 = *((struct mi *) m1);
704 struct mi mi2 = *((struct mi *) m2);
706 if (mi1.randomizer > mi2.randomizer) {
707 result = 1;
708 } else if (mi1.randomizer == mi2.randomizer) {
709 result = 0;
710 }
712 return result;
713 }
715 /*
716 * regcomp each prefix.
717 */
718 static int load_prefix_regex(void)
719 {
720 int i, status, result = 0;
722 for (i = 0; i < MAX_NO_OF_LCRS; i++) {
723 if ((*lcrs)[i].end_record != 0) {
724 break;
725 }
726 if (prefix_reg[i].valid) {
727 regfree(&(prefix_reg[i].re));
728 prefix_reg[i].valid = 0;
729 }
730 memset(&(prefix_reg[i].re), 0, sizeof(regex_t));
731 if ((status=regcomp(&(prefix_reg[i].re),(*lcrs)[i].prefix,0))!=0){
732 LM_ERR("bad prefix re <%s>, regcomp returned %d (check regex.h)\n",
733 (*lcrs)[i].prefix, status);
734 result = -1;
735 break;
736 }
737 prefix_reg[i].valid = 1;
738 }
740 return result;
741 }
743 /*
744 * regcomp each from_uri.
745 */
746 static int load_from_uri_regex(void)
747 {
748 int i, status, result = 0;
750 for (i = 0; i < MAX_NO_OF_LCRS; i++) {
751 if ((*lcrs)[i].end_record != 0) {
752 break;
753 }
754 if (from_uri_reg[i].valid) {
755 regfree(&(from_uri_reg[i].re));
756 from_uri_reg[i].valid = 0;
757 }
758 memset(&(from_uri_reg[i].re), 0, sizeof(regex_t));
759 if ((status=regcomp(&(from_uri_reg[i].re),(*lcrs)[i].from_uri,0))!=0){
760 LM_ERR("Bad from_uri re <%s>, regcomp returned %d (check regex.h)\n",
761 (*lcrs)[i].from_uri, status);
762 result = -1;
763 break;
764 }
765 from_uri_reg[i].valid = 1;
766 }
768 if (result != -1) {
769 reload_counter = *lcrs_ws_reload_counter;
770 }
771 return result;
772 }
774 static int load_all_regex(void)
775 {
776 int result =0;
778 if (prefix_mode_param != 0) {
779 result = load_prefix_regex();
780 }
782 if (result == 0) {
783 result = load_from_uri_regex();
784 } else {
785 LM_ERR("Unable to load prefix regex\n");
786 }
788 if (result == 0) {
789 reload_counter = *lcrs_ws_reload_counter;
790 } else {
791 LM_ERR("Unable to load from_uri regex\n");
792 }
794 return result;
795 }
797 /*
798 * Reload gws to unused gw table and lcrs to unused lcr table, and, when done
799 * make unused gw and lcr table the one in use.
800 */
801 int reload_gws(void)
802 {
803 unsigned int i, port, strip, tag_len, prefix_len, from_uri_len,
804 grp_id, priority;
805 struct in_addr ip_addr;
806 unsigned int flags;
807 uri_type scheme;
808 uri_transport transport;
809 db_con_t* dbh;
810 char *tag, *prefix, *from_uri;
811 db_res_t* res = NULL;
812 db_row_t* row;
813 db_key_t gw_cols[8];
814 db_key_t lcr_cols[4];
816 gw_cols[0] = &ip_addr_col;
817 gw_cols[1] = &port_col;
818 gw_cols[2] = &uri_scheme_col;
819 gw_cols[3] = &transport_col;
820 gw_cols[4] = &strip_col;
821 gw_cols[5] = &tag_col;
822 /* FIXME: is this ok if we have different names for grp_id
823 in the two tables? (ge vw lcr) */
824 gw_cols[6] = &grp_id_col;
825 gw_cols[7] = &flags_col;
827 lcr_cols[0] = &prefix_col;
828 lcr_cols[1] = &from_uri_col;
829 /* FIXME: is this ok if we have different names for grp_id
830 in the two tables? (ge vw lcr) */
831 lcr_cols[2] = &grp_id_col;
832 lcr_cols[3] = &priority_col;
834 if (lcr_dbf.init==0){
835 LM_CRIT("Unbound database\n");
836 return -1;
837 }
838 dbh=lcr_dbf.init(&db_url);
839 if (dbh==0){
840 LM_ERR("Unable to open database connection\n");
841 return -1;
842 }
844 if (lcr_dbf.use_table(dbh, &gw_table) < 0) {
845 LM_ERR("Error while trying to use gw table\n");
846 return -1;
847 }
849 if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 8, 0, &res) < 0) {
850 LM_ERR("Failed to query gw data\n");
851 lcr_dbf.close(dbh);
852 return -1;
853 }
855 if (RES_ROW_N(res) + 1 > MAX_NO_OF_GWS) {
856 LM_ERR("Too many gateways\n");
857 lcr_dbf.free_result(dbh, res);
858 lcr_dbf.close(dbh);
859 return -1;
860 }
862 for (i = 0; i < RES_ROW_N(res); i++) {
863 row = RES_ROWS(res) + i;
864 if (!((VAL_TYPE(ROW_VALUES(row)) == DB_STRING) &&
865 !VAL_NULL(ROW_VALUES(row)) &&
866 inet_aton((char *)VAL_STRING(ROW_VALUES(row)), &ip_addr) != 0)) {
867 LM_ERR("Invalid IP address of gw <%s>\n",
868 (char *)VAL_STRING(ROW_VALUES(row)));
869 lcr_dbf.free_result(dbh, res);
870 lcr_dbf.close(dbh);
871 return -1;
872 }
873 if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
874 port = 0;
875 } else {
876 port = (unsigned int)VAL_INT(ROW_VALUES(row) + 1);
877 }
878 if (port > 65536) {
879 LM_ERR("Port of gw is too large <%u>\n", port);
880 lcr_dbf.free_result(dbh, res);
881 lcr_dbf.close(dbh);
882 return -1;
883 }
884 if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {
885 scheme = SIP_URI_T;
886 } else {
887 scheme = (uri_type)VAL_INT(ROW_VALUES(row) + 2);
888 if ((scheme != SIP_URI_T) && (scheme != SIPS_URI_T)) {
889 LM_ERR("Unknown or unsupported URI scheme <%u>\n",
890 (unsigned int)scheme);
891 lcr_dbf.free_result(dbh, res);
892 lcr_dbf.close(dbh);
893 return -1;
894 }
895 }
896 if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {
897 transport = PROTO_NONE;
898 } else {
899 transport = (uri_transport)VAL_INT(ROW_VALUES(row) + 3);
900 if ((transport != PROTO_UDP) && (transport != PROTO_TCP) &&
901 (transport != PROTO_TLS)) {
902 LM_ERR("Unknown or unsupported transport <%u>\n",
903 (unsigned int)transport);
904 lcr_dbf.free_result(dbh, res);
905 lcr_dbf.close(dbh);
906 return -1;
907 }
908 }
909 if (VAL_NULL(ROW_VALUES(row) + 4) == 1) {
910 strip = 0;
911 } else {
912 strip = (unsigned int)VAL_INT(ROW_VALUES(row) + 4);
913 }
914 if (VAL_NULL(ROW_VALUES(row) + 5) == 1) {
915 tag_len = 0;
916 tag = (char *)0;
917 } else {
918 tag = (char *)VAL_STRING(ROW_VALUES(row) + 5);
919 tag_len = strlen(tag);
920 if (tag_len > MAX_TAG_LEN) {
921 LM_ERR("Too long gw tag <%u>\n", tag_len);
922 lcr_dbf.free_result(dbh, res);
923 lcr_dbf.close(dbh);
924 return -1;
925 }
926 }
927 if (VAL_NULL(ROW_VALUES(row) + 6) == 1) {
928 grp_id = 0;
929 } else {
930 grp_id = VAL_INT(ROW_VALUES(row) + 6);
931 }
932 if (!VAL_NULL(ROW_VALUES(row) + 7) &&
933 (VAL_TYPE(ROW_VALUES(row) + 7) == DB_INT)) {
934 flags = (unsigned int)VAL_INT(ROW_VALUES(row) + 7);
935 } else {
936 LM_ERR("Attribute flags is NULL or non-int\n");
937 lcr_dbf.free_result(dbh, res);
938 lcr_dbf.close(dbh);
939 return -1;
940 }
941 if (*gws == gws_1) {
942 gws_2[i].ip_addr = (unsigned int)ip_addr.s_addr;
943 gws_2[i].port = port;
944 gws_2[i].grp_id = grp_id;
945 gws_2[i].scheme = scheme;
946 gws_2[i].transport = transport;
947 gws_2[i].flags = flags;
948 gws_2[i].strip = strip;
949 gws_2[i].tag_len = tag_len;
950 if (tag_len)
951 memcpy(&(gws_2[i].tag[0]), tag, tag_len);
952 } else {
953 gws_1[i].ip_addr = (unsigned int)ip_addr.s_addr;
954 gws_1[i].port = port;
955 gws_1[i].grp_id = grp_id;
956 gws_1[i].scheme = scheme;
957 gws_1[i].transport = transport;
958 gws_1[i].flags = flags;
959 gws_1[i].strip = strip;
960 gws_1[i].tag_len = tag_len;
961 if (tag_len)
962 memcpy(&(gws_1[i].tag[0]), tag, tag_len);
963 }
964 }
966 lcr_dbf.free_result(dbh, res);
968 if (*gws == gws_1) {
969 gws_2[i].ip_addr = 0;
970 *gws = gws_2;
971 } else {
972 gws_1[i].ip_addr = 0;
973 *gws = gws_1;
974 }
977 if (lcr_dbf.use_table(dbh, &lcr_table) < 0) {
978 LM_ERR("Error while trying to use lcr table\n");
979 return -1;
980 }
982 if (lcr_dbf.query(dbh, NULL, 0, NULL, lcr_cols, 0, 4, 0, &res) < 0) {
983 LM_ERR("Failed to query lcr data\n");
984 lcr_dbf.close(dbh);
985 return -1;
986 }
988 if (RES_ROW_N(res) + 1 > MAX_NO_OF_LCRS) {
989 LM_ERR("Too many lcr entries <%d>\n", RES_ROW_N(res));
990 lcr_dbf.free_result(dbh, res);
991 lcr_dbf.close(dbh);
992 return -1;
993 }
994 for (i = 0; i < RES_ROW_N(res); i++) {
995 row = RES_ROWS(res) + i;
996 if (VAL_NULL(ROW_VALUES(row)) == 1) {
997 prefix_len = 0;
998 prefix = 0;
999 } else {
1000 prefix = (char *)VAL_STRING(ROW_VALUES(row));
1001 prefix_len = strlen(prefix);
1002 if (prefix_len > MAX_PREFIX_LEN) {
1003 LM_ERR("Too long lcr prefix <%u>\n", prefix_len);
1004 lcr_dbf.free_result(dbh, res);
1005 lcr_dbf.close(dbh);
1006 return -1;
1007 }
1008 }
1009 if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
1010 from_uri_len = 0;
1011 from_uri = 0;
1012 } else {
1013 from_uri = (char *)VAL_STRING(ROW_VALUES(row) + 1);
1014 from_uri_len = strlen(from_uri);
1015 if (from_uri_len > MAX_FROM_URI_LEN) {
1016 LM_ERR("Too long from_uri <%u>\n", from_uri_len);
1017 lcr_dbf.free_result(dbh, res);
1018 lcr_dbf.close(dbh);
1019 return -1;
1020 }
1021 }
1022 if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {
1023 LM_ERR("Route grp_id is NULL\n");
1024 lcr_dbf.free_result(dbh, res);
1025 lcr_dbf.close(dbh);
1026 return -1;
1027 }
1028 grp_id = (unsigned int)VAL_INT(ROW_VALUES(row) + 2);
1029 if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {
1030 LM_ERR("Route priority is NULL\n");
1031 lcr_dbf.free_result(dbh, res);
1032 lcr_dbf.close(dbh);
1033 return -1;
1034 }
1035 priority = (unsigned int)VAL_INT(ROW_VALUES(row) + 3);
1037 if (*lcrs == lcrs_1) {
1038 lcrs_2[i].prefix_len = prefix_len;
1039 if (prefix_len)
1040 memcpy(&(lcrs_2[i].prefix[0]), prefix, prefix_len);
1041 lcrs_2[i].from_uri_len = from_uri_len;
1042 if (from_uri_len) {
1043 memcpy(&(lcrs_2[i].from_uri[0]), from_uri, from_uri_len);
1044 lcrs_2[i].from_uri[from_uri_len] = '\0';
1045 }
1046 lcrs_2[i].grp_id = grp_id;
1047 lcrs_2[i].priority = priority;
1048 lcrs_2[i].end_record = 0;
1049 } else {
1050 lcrs_1[i].prefix_len = prefix_len;
1051 if (prefix_len)
1052 memcpy(&(lcrs_1[i].prefix[0]), prefix, prefix_len);
1053 lcrs_1[i].from_uri_len = from_uri_len;
1054 if (from_uri_len) {
1055 memcpy(&(lcrs_1[i].from_uri[0]), from_uri, from_uri_len);
1056 lcrs_1[i].from_uri[from_uri_len] = '\0';
1057 }
1058 lcrs_1[i].grp_id = grp_id;
1059 lcrs_1[i].priority = priority;
1060 lcrs_1[i].end_record = 0;
1061 }
1062 }
1064 lcr_dbf.free_result(dbh, res);
1065 lcr_dbf.close(dbh);
1067 if (*lcrs == lcrs_1) {
1068 lcrs_2[i].end_record = 1;
1069 *lcrs = lcrs_2;
1070 } else {
1071 lcrs_1[i].end_record = 1;
1072 *lcrs = lcrs_1;
1073 }
1075 (*lcrs_ws_reload_counter)++;
1076 if (0 != load_all_regex()) {
1078 return -1;
1079 }
1081 return 1;
1082 }
1085 int mi_print_gws(struct mi_node* rpl)
1086 {
1087 unsigned int i;
1088 struct mi_attr* attr;
1089 uri_transport transport;
1090 char *transp;
1091 struct mi_node* node;
1092 struct ip_addr address;
1093 char* p;
1094 int len;
1096 for (i = 0; i < MAX_NO_OF_GWS; i++) {
1098 if ((*gws)[i].ip_addr == 0)
1099 break;
1101 node= add_mi_node_child(rpl,0 ,"GW", 2, 0, 0);
1102 if(node == NULL)
1103 return -1;
1105 p = int2str((unsigned long)(*gws)[i].grp_id, &len );
1106 attr = add_mi_attr(node, MI_DUP_VALUE, "GRP_ID", 6, p, len );
1107 if(attr == NULL)
1108 return -1;
1110 transport = (*gws)[i].transport;
1111 if (transport == PROTO_UDP)
1112 transp= ";transport=udp";
1113 else if (transport == PROTO_TCP)
1114 transp= ";transport=tcp";
1115 else if (transport == PROTO_TLS)
1116 transp= ";transport=tls";
1117 else
1118 transp= "";
1120 address.af = AF_INET;
1121 address.len = 4;
1122 address.u.addr32[0] = (*gws)[i].ip_addr;
1123 attr= addf_mi_attr(node,0 ,"URI", 3,"%s:%s:%d%s",
1124 ((*gws)[i].scheme == SIP_URI_T)?"sip":"sips",
1125 ip_addr2a(&address),
1126 ((*gws)[i].port == 0)?5060:(*gws)[i].port,transp);
1127 if(attr == NULL)
1128 return -1;
1130 p = int2str((unsigned long)(*gws)[i].strip, &len );
1131 attr = add_mi_attr(node, MI_DUP_VALUE, "STRIP", 5, p, len);
1132 if(attr == NULL)
1133 return -1;
1135 attr = add_mi_attr(node, MI_DUP_VALUE, "TAG", 3,
1136 (*gws)[i].tag, (*gws)[i].tag_len );
1137 if(attr == NULL)
1138 return -1;
1140 p = int2str((unsigned long)(*gws)[i].flags, &len );
1141 attr = add_mi_attr(node, MI_DUP_VALUE, "FLAGS", 5, p, len);
1142 if(attr == NULL)
1143 return -1;
1144 }
1146 for (i = 0; i < MAX_NO_OF_LCRS; i++) {
1147 if ((*lcrs)[i].end_record != 0)
1148 break;
1150 node= add_mi_node_child(rpl, 0, "RULE", 4, 0, 0);
1151 attr = add_mi_attr(node, 0, "PREFIX", 6, (*lcrs)[i].prefix,
1152 (*lcrs)[i].prefix_len );
1153 if(attr== 0)
1154 return -1;
1156 attr = add_mi_attr(node, 0, "FROM_URI", 8, (*lcrs)[i].from_uri,
1157 (*lcrs)[i].from_uri_len );
1158 if(attr== 0)
1159 return -1;
1161 p = int2str((unsigned long)(*lcrs)[i].grp_id, &len );
1162 attr = add_mi_attr(node, MI_DUP_VALUE, "GRP_ID", 6, p, len );
1163 if(attr == NULL)
1164 return -1;
1166 p = int2str((unsigned long)(*lcrs)[i].priority, &len );
1167 attr = add_mi_attr(node, MI_DUP_VALUE, "PRIORITY", 8, p, len );
1168 if(attr == NULL)
1169 return -1;
1171 }
1173 return 0;
1174 }
1177 /*
1178 * Load info of matching GWs from database to gw_uri AVPs
1179 */
1180 static int do_load_gws(struct sip_msg* _m, str *_from_uri, int _grp_id)
1181 {
1182 str ruri_user, from_uri, value;
1183 char from_uri_str[MAX_FROM_URI_LEN + 1];
1184 char ruri[MAX_URI_SIZE];
1185 unsigned int i, j, k, index, addr, port, strip, gw_index,
1186 duplicated_gw, flags, have_rpid_avp;
1187 uri_type scheme;
1188 uri_transport transport;
1189 struct ip_addr address;
1190 str addr_str, port_str;
1191 char *at, *tag, *strip_string, *flags_string;
1192 struct usr_avp *avp;
1193 int_str val;
1194 struct mi matched_gws[MAX_NO_OF_GWS + 1];
1195 unsigned short tag_len, prefix_len, priority;
1196 int randomizer_start, randomizer_end, randomizer_flag,
1197 strip_len, flags_len;
1198 struct lcr_info lcr_rec;
1200 /* Find Request-URI user */
1201 if ((parse_sip_msg_uri(_m) < 0) || (!_m->parsed_uri.user.s)) {
1202 LM_ERR("Error while parsing R-URI\n");
1203 return -1;
1204 }
1205 ruri_user = _m->parsed_uri.user;
1207 if (_from_uri) {
1208 /* take caller uri from _from_uri argument */
1209 from_uri = *_from_uri;
1210 } else {
1211 /* take caller uri from RPID or From URI */
1212 have_rpid_avp = 0;
1213 avp = search_first_avp(rpid_avp_type, rpid_avp, &val, 0);
1214 if (avp != NULL) {
1215 /* Get URI user from RPID if not empty */
1216 if (avp->flags & AVP_VAL_STR) {
1217 if (val.s.s && val.s.len) {
1218 from_uri = val.s;
1219 have_rpid_avp = 1;
1220 }
1221 } else {
1222 from_uri.s = int2str(val.n, &from_uri.len);
1223 have_rpid_avp = 1;
1224 }
1225 }
1226 if (!have_rpid_avp) {
1227 /* Get URI from From URI */
1228 if ((!_m->from) && (parse_headers(_m, HDR_FROM_F, 0) == -1)) {
1229 LM_ERR("Error while parsing headers\n");
1230 return -1;
1231 }
1232 if (!_m->from) {
1233 LM_ERR("From header field not found\n");
1234 return -1;
1235 }
1236 if ((!(_m->from)->parsed) && (parse_from_header(_m) < 0)) {
1237 LM_ERR("Error while parsing From header\n");
1238 return -1;
1239 }
1240 from_uri = get_from(_m)->uri;
1241 }
1242 }
1243 if (from_uri.len <= MAX_FROM_URI_LEN) {
1244 strncpy(from_uri_str, from_uri.s, from_uri.len);
1245 from_uri_str[from_uri.len] = '\0';
1246 } else {
1247 LM_ERR("From URI is too long <%u>\n", from_uri.len);
1248 return -1;
1249 }
1251 /*
1252 * Check if the gws and lcrs were reloaded
1253 */
1254 if (reload_counter != *lcrs_ws_reload_counter) {
1255 if (load_all_regex() != 0) {
1256 return -1;
1257 }
1258 }
1260 /*
1261 * Let's match the gws:
1262 * 1. prefix matching
1263 * 2. from_uri matching
1264 * 3. _grp_id matching
1265 *
1266 * Note: A gateway must be in the list _only_ once.
1267 */
1268 gw_index = 0;
1269 duplicated_gw = 0;
1270 for (i = 0; i < MAX_NO_OF_LCRS; i++) {
1271 lcr_rec = (*lcrs)[i];
1272 if (lcr_rec.end_record != 0) {
1273 break;
1274 }
1275 if ( ((prefix_mode_param == 0) && (lcr_rec.prefix_len <= ruri_user.len) &&
1276 (strncmp(lcr_rec.prefix, ruri_user.s, lcr_rec.prefix_len)==0)) ||
1277 ( (prefix_mode_param != 0) && ( (lcr_rec.prefix_len == 0) ||
1278 (prefix_reg[i].valid &&
1279 (regexec(&(prefix_reg[i].re), ruri_user.s, 0,
1280 (regmatch_t *)NULL, 0) == 0)) ) ) ) {
1281 /* 1. Prefix matching is done */
1282 if ((lcr_rec.from_uri_len == 0) ||
1283 (from_uri_reg[i].valid &&
1284 (regexec(&(from_uri_reg[i].re), from_uri_str, 0,
1285 (regmatch_t *)NULL, 0) == 0))) {
1286 /* 2. from_uri matching is done */
1287 for (j = 0; j < MAX_NO_OF_GWS; j++) {
1288 if ((*gws)[j].ip_addr == 0) {
1289 break;
1290 }
1291 if (lcr_rec.grp_id == (*gws)[j].grp_id &&
1292 (_grp_id < 0 || (*gws)[j].grp_id == _grp_id)) {
1293 /* 3. _grp_id matching is done */
1294 for (k = 0; k < gw_index; k++) {
1295 if ((*gws)[j].ip_addr ==
1296 (*gws)[matched_gws[k].gw_index].ip_addr) {
1297 /* Found the same gw in the list */
1298 /* Let's keep the one with higher */
1299 /* match on prefix len */
1300 LM_DBG("Duplicate gw for index"
1301 " %d [%d,%d] and current [%d,%d] \n",
1302 k, matched_gws[k].route_index,
1303 matched_gws[k].route_index, i, j);
1304 duplicated_gw = 1;
1305 if (lcr_rec.prefix_len >
1306 (*lcrs)[matched_gws[k].route_index].prefix_len) {
1307 /* Replace the old entry with the new one */
1308 LM_DBG("Replace [%d,%d]"
1309 " with [%d,%d] on index %d:"
1310 " prefix reason %d>%d\n",
1311 matched_gws[k].route_index,
1312 matched_gws[k].gw_index, i, j, k,
1313 lcr_rec.prefix_len,
1314 (*lcrs)[matched_gws[k].route_index].prefix_len);
1315 matched_gws[k].route_index = i;
1316 matched_gws[k].gw_index = j;
1317 /* Stop searching in the matched_gws list */
1318 break;
1319 } else if (lcr_rec.prefix_len ==
1320 (*lcrs)[matched_gws[k].route_index].prefix_len) {
1321 if (lcr_rec.priority >
1322 (*lcrs)[matched_gws[k].route_index].priority) {
1323 /* Replace the old entry with the new one */
1324 LM_DBG("Replace [%d,%d] with"
1325 " [%d,%d] on index %d:"
1326 " priority reason %d>%d\n",
1327 matched_gws[k].route_index,
1328 matched_gws[k].gw_index,
1329 i, j, k, lcr_rec.priority,
1330 (*lcrs)[matched_gws[k].route_index].priority);
1331 matched_gws[k].route_index = i;
1332 matched_gws[k].gw_index = j;
1333 /* Stop searching in the matched_gws list */
1334 break;
1335 }
1336 }
1337 }
1338 }
1339 if (duplicated_gw == 0) {
1340 /* This is a new gw */
1341 matched_gws[gw_index].route_index = i;
1342 matched_gws[gw_index].gw_index = j;
1343 LM_DBG("Added matched_gws[%d]=[%d,%d]\n",
1344 gw_index, i, j);
1345 gw_index++;
1346 } else {
1347 duplicated_gw = 0;
1348 }
1349 }
1350 }
1351 }
1352 }
1353 }
1354 matched_gws[gw_index].route_index = -1;
1355 matched_gws[gw_index].gw_index = -1;
1357 /*
1358 * Sort the gateways based on:
1359 * 1. prefix len
1360 * 2. priority
1361 */
1362 qsort(matched_gws, gw_index, sizeof(struct mi), comp_lcrs);
1363 randomizer_start = 0;
1365 /* Randomizing the gateways with same prefix_len and same priority */
1366 randomizer_flag = 0;
1367 prefix_len = (*lcrs)[matched_gws[0].route_index].prefix_len;
1368 priority = (*lcrs)[matched_gws[0].route_index].priority;
1369 for (i = 1; i < gw_index; i++) {
1370 if ( prefix_len == (*lcrs)[matched_gws[i].route_index].prefix_len &&
1371 priority == (*lcrs)[matched_gws[i].route_index].priority) {
1372 /* we have a match */
1373 if (randomizer_flag == 0) {
1374 randomizer_flag = 1;
1375 randomizer_start = i - 1;
1376 }
1377 matched_gws[i - 1].randomizer = rand();
1378 }
1379 else {
1380 if (randomizer_flag == 1) {
1381 randomizer_end = i - 1;
1382 randomizer_flag = 0;
1383 qsort(&matched_gws[randomizer_start],
1384 randomizer_end - randomizer_start + 1,
1385 sizeof(struct mi), rand_lcrs);
1386 }
1387 prefix_len = (*lcrs)[matched_gws[i].route_index].prefix_len;
1388 priority = (*lcrs)[matched_gws[i].route_index].priority;
1389 }
1390 }
1391 if (randomizer_flag == 1) {
1392 randomizer_end = gw_index - 1;
1393 matched_gws[i - 1].randomizer = rand();
1394 qsort(&matched_gws[randomizer_start],
1395 randomizer_end - randomizer_start + 1,
1396 sizeof(struct mi), rand_lcrs);
1397 }
1399 for (i = 0; i < MAX_NO_OF_GWS; i++) {
1400 index = matched_gws[i].gw_index;
1401 if (index == -1) {
1402 break;
1403 }
1404 addr = (*gws)[index].ip_addr;
1405 port = (*gws)[index].port;
1406 scheme = (*gws)[index].scheme;
1407 transport = (*gws)[index].transport;
1408 flags = (*gws)[index].flags;
1409 strip = (*gws)[index].strip;
1410 if (strip > ruri_user.len) {
1411 LM_ERR("Strip count of gw is too large <%u>\n", strip);
1412 goto skip;
1413 }
1414 tag_len = (*gws)[index].tag_len;
1415 tag = (*gws)[index].tag;
1416 if (6 + tag_len + 40 /* flags + strip */ + 1 + 15 + 1 + 5 + 1 + 14 >
1417 MAX_URI_SIZE) {
1418 LM_ERR("Request URI would be too long\n");
1419 goto skip;
1420 }
1421 at = (char *)&(ruri[0]);
1422 flags_string = int2str(flags, &flags_len);
1423 memcpy(at, flags_string, flags_len);
1424 at = at + flags_len;
1425 if (scheme == SIP_URI_T) {
1426 memcpy(at, "sip:", 4); at = at + 4;
1427 } else if (scheme == SIPS_URI_T) {
1428 memcpy(at, "sips:", 5); at = at + 5;
1429 } else {
1430 LM_ERR("Unknown or unsupported URI scheme <%u>\n",
1431 (unsigned int)scheme);
1432 goto skip;
1433 }
1434 if (tag_len) {
1435 memcpy(at, tag, tag_len); at = at + tag_len;
1436 }
1437 /* Add strip in this form |number.
1438 * For example: |3 means strip first 3 characters.
1439 */
1440 *at = '|'; at = at + 1;
1441 strip_string = int2str(strip, &strip_len);
1442 memcpy(at, strip_string, strip_len);
1443 at = at + strip_len;
1444 *at = '@'; at = at + 1;
1445 address.af = AF_INET;
1446 address.len = 4;
1447 address.u.addr32[0] = addr;
1448 addr_str.s = ip_addr2a(&address);
1449 addr_str.len = strlen(addr_str.s);
1450 memcpy(at, addr_str.s, addr_str.len); at = at + addr_str.len;
1451 if (port != 0) {
1452 if (port > 65536) {
1453 LM_ERR("Port of GW is too large <%u>\n", port);
1454 goto skip;
1455 }
1456 *at = ':'; at = at + 1;
1457 port_str.s = int2str(port, &port_str.len);
1458 memcpy(at, port_str.s, port_str.len); at = at + port_str.len;
1459 }
1460 if (transport != PROTO_NONE) {
1461 memcpy(at, ";transport=", 11); at = at + 11;
1462 if (transport == PROTO_UDP) {
1463 memcpy(at, "udp", 3); at = at + 3;
1464 } else if (transport == PROTO_TCP) {
1465 memcpy(at, "tcp", 3); at = at + 3;
1466 } else if (transport == PROTO_TLS) {
1467 memcpy(at, "tls", 3); at = at + 3;
1468 } else {
1469 LM_ERR("Unknown or unsupported transport <%u>\n",
1470 (unsigned int)transport);
1471 goto skip;
1472 }
1473 }
1474 value.s = (char *)&(ruri[0]);
1475 value.len = at - value.s;
1476 val.s = value;
1477 add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val);
1478 LM_DBG("Added gw_uri_avp <%.*s>\n", value.len, value.s);
1479 skip:
1480 continue;
1481 }
1483 return 1;
1484 }
1486 /*
1487 * Load info of matching GWs from database to gw_uri AVPs
1488 * taking into account the given group id. Caller URI is taken
1489 * from request.
1490 */
1491 static int load_gws_from_grp(struct sip_msg* _m, char* _s1, char* _s2)
1492 {
1493 str grp_s;
1494 unsigned int grp_id;
1496 if(((pv_elem_p)_s1)->spec.getf!=NULL)
1497 {
1498 if(pv_printf_s(_m, (pv_elem_p)_s1, &grp_s)!=0)
1499 return -1;
1500 if(str2int(&grp_s, &grp_id)!=0)
1501 return -1;
1502 } else {
1503 grp_id = ((pv_elem_p)_s1)->spec.pvp.pvn.u.isname.name.n;
1504 }
1505 if (grp_id > 0) return do_load_gws(_m, (str *)0, (int)grp_id);
1506 else return -1;
1507 }
1510 /*
1511 * Load info of matching GWs from database to gw_uri AVPs.
1512 * Caller URI is taken from request.
1513 */
1514 static int load_gws_0(struct sip_msg* _m, char* _s1, char* _s2)
1515 {
1516 return do_load_gws(_m, (str *)0, -1);
1517 }
1520 /*
1521 * Load info of matching GWs from database to gw_uri AVPs.
1522 * Caller URI is taken from pseudo variable argument.
1523 */
1524 static int load_gws_1(struct sip_msg* _m, char* _sp, char* _s2)
1525 {
1526 pv_spec_t *sp;
1527 pv_value_t pv_val;
1528 sp = (pv_spec_t *)_sp;
1530 if (sp && (pv_get_spec_value(_m, sp, &pv_val) == 0)) {
1531 if (pv_val.flags & PV_VAL_STR) {
1532 if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
1533 LM_DBG("missing from uri\n");
1534 return -1;
1535 }
1536 return do_load_gws(_m, &(pv_val.rs), -1);
1537 } else {
1538 LM_DBG("pseudo variable value is not string\n");
1539 return -1;
1540 }
1541 } else {
1542 LM_DBG("cannot get pseudo variable value\n");
1543 return -1;
1544 }
1545 }
1548 /*
1549 * Rewrites scheme, host, port, and transport parts of R-URI based on first
1550 * gw_uri AVP value, which is then destroyed. Also saves R-URI user to
1551 * ruri_user AVP for later use in failure route block.
1552 * If called from failure route block, appends a new branch to request
1553 * where scheme, host, port, and transport of URI are taken from the first
1554 * gw_uri AVP value, which is then destroyed. URI user is taken from
1555 * ruri_user AVP value saved earlier.
1556 * Returns 1 upon success and -1 upon failure.
1557 */
1558 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2)
1559 {
1560 int_str gw_uri_val, ruri_user_val, val;
1561 struct usr_avp *gu_avp, *ru_avp;
1562 int rval;
1563 str new_ruri;
1564 char *at, *at_char, *strip_char, *endptr;
1565 unsigned int strip;
1567 gu_avp = search_first_avp(gw_uri_avp_type, gw_uri_avp, &gw_uri_val, 0);
1568 if (!gu_avp) return -1;
1570 /* Set flags_avp from integer at the beginning of of gw_uri */
1571 val.n = (int)strtoul(gw_uri_val.s.s, &at, 0);
1572 add_avp(flags_avp_type, flags_avp, val);
1573 LM_DBG("Added flags_avp <%u>\n", (unsigned int)val.n);
1575 gw_uri_val.s.len = gw_uri_val.s.len - (at - gw_uri_val.s.s);
1576 gw_uri_val.s.s = at;
1578 /* Create new Request-URI taking URI user from ruri_user AVP
1579 and other parts of from gateway URI AVP. */
1580 ru_avp = search_first_avp(ruri_user_avp_type, ruri_user_avp,
1581 &ruri_user_val, 0);
1582 if (!ru_avp) {
1583 LM_DBG("ruri_user AVP no yet set -> use RURI\n");
1584 /* parse RURI and ger username */
1585 if (parse_sip_msg_uri(_m) < 0) {
1586 LM_ERR("Parsing of R-URI failed\n");
1587 return -1;
1588 }
1589 ruri_user_val.s = _m->parsed_uri.user;
1590 /* Save Request-URI user for use in FAILURE_ROUTE */
1591 val.s = _m->parsed_uri.user;
1592 add_avp(ruri_user_avp_type|AVP_VAL_STR, ruri_user_avp, val);
1593 LM_DBG("Added ruri_user_avp <%.*s>\n", val.s.len, val.s.s);
1594 }
1596 new_ruri.s = pkg_malloc(gw_uri_val.s.len + ruri_user_val.s.len);
1597 if (!new_ruri.s) {
1598 LM_ERR("No memory for new R-URI.\n");
1599 return -1;
1600 }
1601 at_char = memchr(gw_uri_val.s.s, '@', gw_uri_val.s.len);
1602 if (!at_char) {
1603 pkg_free(new_ruri.s);
1604 LM_ERR("No @ in gateway URI <%.*s>\n",
1605 gw_uri_val.s.len, gw_uri_val.s.s);
1606 return -1;
1607 }
1608 strip_char = memchr(gw_uri_val.s.s, '|', gw_uri_val.s.len);
1609 if (!strip_char || strip_char + 1 >= at_char) {
1610 pkg_free(new_ruri.s);
1611 LM_ERR("No strip char | and at least one "
1612 "char before @ in gateway URI <%.*s>\n",
1613 gw_uri_val.s.len, gw_uri_val.s.s);
1614 return -1;
1615 }
1616 at = new_ruri.s;
1617 memcpy(at, gw_uri_val.s.s, strip_char - gw_uri_val.s.s);
1618 at = at + (strip_char - gw_uri_val.s.s);
1619 strip = strtol(strip_char + 1, &endptr, 10);
1620 if (endptr != at_char) {
1621 pkg_free(new_ruri.s);
1622 LM_ERR("Non-digit char between | and @ chars in gw URI <%.*s>\n",
1623 gw_uri_val.s.len, gw_uri_val.s.s);
1624 return -1;
1625 }
1626 if (ruri_user_val.s.len - strip > 0) {
1627 memcpy(at, ruri_user_val.s.s + strip,
1628 ruri_user_val.s.len - strip);
1629 at = at + ruri_user_val.s.len - strip;
1630 }
1631 if (*(at - 1) != ':') {
1632 memcpy(at, at_char, gw_uri_val.s.len - (at_char - gw_uri_val.s.s));
1633 at = at + gw_uri_val.s.len - (at_char - gw_uri_val.s.s);
1634 } else {
1635 memcpy(at, at_char + 1, gw_uri_val.s.len -
1636 (at_char + 1 - gw_uri_val.s.s));
1637 at = at + gw_uri_val.s.len - (at_char + 1 - gw_uri_val.s.s);
1638 }
1639 new_ruri.len = at - new_ruri.s;
1641 /* set new RURI */
1642 rval = set_ruri( _m, &new_ruri);
1643 pkg_free(new_ruri.s);
1644 destroy_avp(gu_avp);
1645 if (rval!=0) {
1646 LM_ERR("failed to set new RURI\n");
1647 return -1;
1648 }
1650 return 1;
1651 }
1654 /*
1655 * Checks if request comes from a gateway
1656 */
1657 static int do_from_gw(struct sip_msg* _m, pv_spec_t *addr_sp, int grp_id)
1658 {
1659 int i;
1660 unsigned int src_addr;
1661 pv_value_t pv_val;
1662 struct ip_addr *ip;
1663 int_str val;
1665 if (addr_sp && (pv_get_spec_value(_m, addr_sp, &pv_val) == 0)) {
1666 if (pv_val.flags & PV_VAL_INT) {
1667 src_addr = pv_val.ri;
1668 } else if (pv_val.flags & PV_VAL_STR) {
1669 if ( (ip=str2ip( &pv_val.rs)) == NULL) {
1670 LM_ERR("failed to convert IP address string to in_addr\n");
1671 return -1;
1672 } else {
1673 src_addr = ip->u.addr32[0];
1674 }
1675 } else {
1676 LM_ERR("IP address PV empty value\n");
1677 return -1;
1678 }
1679 } else {
1680 src_addr = _m->rcv.src_ip.u.addr32[0];
1681 }
1683 for (i = 0; i < MAX_NO_OF_GWS; i++) {
1684 if ((*gws)[i].ip_addr == 0) {
1685 return -1;
1686 }
1687 if ((*gws)[i].ip_addr == src_addr &&
1688 (grp_id < 0 || (*gws)[i].grp_id == grp_id)) {
1689 LM_DBG("Request came from gw\n");
1690 val.n = (int)(*gws)[i].flags;
1691 add_avp(flags_avp_type, flags_avp, val);
1692 LM_DBG("Added flags_avp <%u>\n", (unsigned int)val.n);
1693 return 1;
1694 }
1695 }
1697 LM_DBG("Request did not come from gw\n");
1698 return -1;
1699 }
1702 /*
1703 * Checks if request comes from a gateway, taking source address from request
1704 * and taking into account the group id.
1705 */
1706 static int from_gw_grp(struct sip_msg* _m, char* _grp_id, char* _s2)
1707 {
1708 return do_from_gw(_m, (pv_spec_t *)0, (int)(long)_grp_id);
1709 }
1712 /*
1713 * Checks if request comes from a gateway, taking src_address from request
1714 * and ignoring group id.
1715 */
1716 static int from_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
1717 {
1718 return do_from_gw(_m, (pv_spec_t *)0, -1);
1719 }
1722 /*
1723 * Checks if request comes from a gateway, taking source address from pw
1724 * and ignoring group id.
1725 */
1726 static int from_gw_1(struct sip_msg* _m, char* _addr_sp, char* _s2)
1727 {
1728 return do_from_gw(_m, (pv_spec_t *)_addr_sp, -1);
1729 }
1732 /*
1733 * Checks if in-dialog request goes to gateway
1734 */
1735 static int do_to_gw(struct sip_msg* _m, int grp_id)
1736 {
1737 char host[16];
1738 struct in_addr addr;
1739 unsigned int i;
1741 if((_m->parsed_uri_ok == 0) && (parse_sip_msg_uri(_m) < 0)) {
1742 LM_ERR("Error while parsing the R-URI\n");
1743 return -1;
1744 }
1746 if (_m->parsed_uri.host.len > 15) {
1747 return -1;
1748 }
1749 memcpy(host, _m->parsed_uri.host.s, _m->parsed_uri.host.len);
1750 host[_m->parsed_uri.host.len] = 0;
1752 if (!inet_aton(host, &addr)) {
1753 return -1;
1754 }
1756 for (i = 0; i < MAX_NO_OF_GWS; i++) {
1757 if ((*gws)[i].ip_addr == 0) {
1758 return -1;
1759 }
1760 if ((*gws)[i].ip_addr == addr.s_addr &&
1761 (grp_id < 0 || (*gws)[i].grp_id == grp_id)) {
1762 return 1;
1763 }
1764 }
1766 return -1;
1767 }
1770 /*
1771 * Checks if in-dialog request goes to gateway, taking
1772 * into account the group id.
1773 */
1774 static int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2)
1775 {
1776 int grp_id;
1778 grp_id = (int)(long)_s1;
1779 return do_to_gw(_m, grp_id);
1780 }
1783 /*
1784 * Checks if in-dialog request goes to gateway, ignoring
1785 * the group id.
1786 */
1787 static int to_gw(struct sip_msg* _m, char* _s1, char* _s2)
1788 {
1789 return do_to_gw(_m, -1);
1790 }
1793 /*
1794 * Frees contact list used by load_contacts function
1795 */
1796 static inline void free_contact_list(struct contact *curr) {
1797 struct contact *prev;
1798 while (curr) {
1799 prev = curr;
1800 curr = curr->next;
1801 pkg_free(prev);
1802 }
1803 }
1805 /* Encode branch info from contact struct to str */
1806 static inline int encode_branch_info(str *info, struct contact *con)
1807 {
1808 char *at, *s;
1809 int len;
1811 info->len = con->uri.len + con->dst_uri.len +
1812 con->path.len + MAX_SOCKET_STR + INT2STR_MAX_LEN + 5;
1813 info->s = pkg_malloc(info->len);
1814 if (!info->s) {
1815 LM_ERR("No memory left for branch info\n");
1816 return 0;
1817 }
1818 at = info->s;
1819 memcpy(at, con->uri.s, con->uri.len);
1820 at = at + con->uri.len;
1821 *at = '\n';
1822 at++;
1823 memcpy(at, con->dst_uri.s, con->dst_uri.len);
1824 at = at + con->dst_uri.len;
1825 *at = '\n';
1826 at++;
1827 memcpy(at, con->path.s, con->path.len);
1828 at = at + con->path.len;
1829 *at = '\n';
1830 at++;
1831 if (con->sock) {
1832 len = MAX_SOCKET_STR;
1833 if (!socket2str(con->sock, at, &len, 1)) {
1834 LM_ERR("Failed to convert socket to str\n");
1835 return 0;
1836 }
1837 } else {
1838 len = 0;
1839 }
1840 at = at + len;
1841 *at = '\n';
1842 at++;
1843 s = int2str(con->flags, &len);
1844 memcpy(at, s, len);
1845 at = at + len;
1846 *at = '\n';
1847 info->len = at - info->s + 1;
1849 return 1;
1850 }
1853 /* Encode branch info from str */
1854 static inline int decode_branch_info(char *info, str *uri, str *dst, str *path,
1855 struct socket_info **sock, unsigned int *flags)
1856 {
1857 str s, host;
1858 int port, proto;
1859 char *pos, *at;
1861 pos = strchr(info, '\n');
1862 uri->len = pos - info;
1863 if (uri->len) {
1864 uri->s = info;
1865 } else {
1866 uri->s = 0;
1867 }
1868 at = pos + 1;
1870 pos = strchr(at, '\n');
1871 dst->len = pos - at;
1872 if (dst->len) {
1873 dst->s = at;
1874 } else {
1875 dst->s = 0;
1876 }
1877 at = pos + 1;
1879 pos = strchr(at, '\n');
1880 path->len = pos - at;
1881 if (path->len) {
1882 path->s = at;
1883 } else {
1884 path->s = 0;
1885 }
1886 at = pos + 1;
1888 pos = strchr(at, '\n');
1889 s.len = pos - at;
1890 if (s.len) {
1891 s.s = at;
1892 if (parse_phostport(s.s, s.len, &host.s, &host.len,
1893 &port, &proto) != 0) {
1894 LM_ERR("Parsing of socket info <%.*s> failed\n", s.len, s.s);
1895 return 0;
1896 }
1897 *sock = grep_sock_info(&host, (unsigned short)port,
1898 (unsigned short)proto);
1899 if (*sock == 0) {
1900 LM_ERR("Invalid socket <%.*s>\n", s.len, s.s);
1901 return 0;
1902 }
1903 } else {
1904 *sock = 0;
1905 }
1906 at = pos + 1;
1908 pos = strchr(at, '\n');
1909 s.len = pos - at;
1910 if (s.len) {
1911 s.s = at;
1912 if (str2int(&s, flags) != 0) {
1913 LM_ERR("Failed to decode flags <%.*s>\n", s.len, s.s);
1914 return 0;
1915 }
1916 } else {
1917 *flags = 0;
1918 }
1920 return 1;
1921 }
1924 /*
1925 * Loads contacts in destination set into "lcr_contact" AVP in reverse
1926 * priority order and associated each contact with Q_FLAG telling if
1927 * contact is the last one in its priority class. Finally, removes
1928 * all branches from destination set.
1929 */
1930 static int load_contacts(struct sip_msg* msg, char* key, char* value)
1931 {
1932 str uri, dst_uri, path, branch_info, *ruri;
1933 qvalue_t q, ruri_q;
1934 struct contact *contacts, *next, *prev, *curr;
1935 int_str val;
1936 int idx;
1937 struct socket_info* sock;
1938 unsigned int flags;
1940 /* Check if anything needs to be done */
1941 if (nr_branches == 0) {
1942 LM_DBG("Nothing to do - no branches!\n");
1943 return 1;
1944 }
1946 ruri = GET_RURI(msg);
1947 if (!ruri) {
1948 LM_ERR("No Request-URI found\n");
1949 return -1;
1950 }
1951 ruri_q = get_ruri_q();
1953 for(idx = 0; (uri.s = get_branch(idx, &uri.len, &q, 0, 0, 0, 0)) != 0;
1954 idx++) {
1955 if (q != ruri_q) {
1956 goto rest;
1957 }
1958 }
1959 LM_DBG("Nothing to do - all contacts have same q!\n");
1960 return 1;
1962 rest:
1963 /* Insert Request-URI branch to contact list */
1964 contacts = (struct contact *)pkg_malloc(sizeof(struct contact));
1965 if (!contacts) {
1966 LM_ERR("No memory for contact info\n");
1967 return -1;
1968 }
1969 contacts->uri.s = ruri->s;
1970 contacts->uri.len = ruri->len;
1971 contacts->q = ruri_q;
1972 contacts->dst_uri = msg->dst_uri;
1973 contacts->sock = msg->force_send_socket;
1974 contacts->flags = getb0flags();
1975 contacts->path = msg->path_vec;
1976 contacts->next = (struct contact *)0;
1978 /* Insert branches to contact list in increasing q order */
1979 for(idx = 0;
1980 (uri.s = get_branch(idx,&uri.len,&q,&dst_uri,&path,&flags,&sock))
1981 != 0;
1982 idx++ ) {
1983 next = (struct contact *)pkg_malloc(sizeof(struct contact));
1984 if (!next) {
1985 LM_ERR("No memory for contact info\n");
1986 free_contact_list(contacts);
1987 return -1;
1988 }
1989 next->uri = uri;
1990 next->q = q;
1991 next->dst_uri = dst_uri;
1992 next->path = path;
1993 next->flags = flags;
1994 next->sock = sock;
1995 next->next = (struct contact *)0;
1996 prev = (struct contact *)0;
1997 curr = contacts;
1998 while (curr && (curr->q < q)) {
1999 prev = curr;
2000 curr = curr->next;
2001 }
2002 if (!curr) {
2003 next->next = (struct contact *)0;
2004 prev->next = next;
2005 } else {
2006 next->next = curr;
2007 if (prev) {
2008 prev->next = next;
2009 } else {
2010 contacts = next;
2011 }
2012 }
2013 }
2015 /* Assign values for q_flags */
2016 curr = contacts;
2017 curr->q_flag = 0;
2018 while (curr->next) {
2019 if (curr->q < curr->next->q) {
2020 curr->next->q_flag = Q_FLAG;
2021 } else {
2022 curr->next->q_flag = 0;
2023 }
2024 curr = curr->next;
2025 }
2027 /* Add contacts to "contacts" AVP */
2028 curr = contacts;
2029 while (curr) {
2030 if (encode_branch_info(&branch_info, curr) == 0) {
2031 LM_ERR("Encoding of branch info failed\n");
2032 free_contact_list(contacts);
2033 if (branch_info.s) pkg_free(branch_info.s);
2034 return -1;
2035 }
2036 val.s = branch_info;
2037 add_avp(contact_avp_type|AVP_VAL_STR|(curr->q_flag),
2038 contact_avp, val);
2039 pkg_free(branch_info.s);
2040 LM_DBG("Loaded contact <%.*s> with q_flag <%d>\n",
2041 val.s.len, val.s.s, curr->q_flag);
2042 curr = curr->next;
2043 }
2045 /* Clear all branches */
2046 clear_branches();
2048 /* Free contact list */
2049 free_contact_list(contacts);
2051 return 1;
2052 }
2055 /*
2056 * Adds to request a destination set that includes all highest priority
2057 * class contacts in "lcr_contact" AVP. If called from a route block,
2058 * rewrites the request uri with first contact and adds the remaining
2059 * contacts as branches. If called from failure route block, adds all
2060 * contacts as branches. Removes added contacts from "lcr_contact" AVP.
2061 */
2062 static int next_contacts(struct sip_msg* msg, char* key, char* value)
2063 {
2064 struct usr_avp *avp, *prev;
2065 int_str val;
2066 str uri, dst, path;
2067 struct socket_info *sock;
2068 unsigned int flags;
2070 /* Find first lcr_contact_avp value */
2071 avp = search_first_avp(contact_avp_type, contact_avp, &val, 0);
2072 if (!avp) {
2073 LM_DBG("No AVPs -- we are done!\n");
2074 return -1;
2075 }
2077 LM_DBG("Next contact is <%s>\n", val.s.s);
2079 if (decode_branch_info(val.s.s, &uri, &dst, &path, &sock, &flags)== 0) {
2080 LM_ERR("Decoding of branch info <%.*s> failed\n",
2081 val.s.len, val.s.s);
2082 destroy_avp(avp);
2083 return -1;
2084 }
2086 set_ruri(msg, &uri);
2087 set_dst_uri(msg, &dst);
2088 set_path_vector(msg, &path);
2089 msg->force_send_socket = sock;
2090 setb0flags(flags);
2092 if (avp->flags & Q_FLAG) {
2093 destroy_avp(avp);
2094 if (route_type == REQUEST_ROUTE) {
2095 /* Set fr_inv_timer */
2096 val.n = fr_inv_timer_next;
2097 if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val) != 0) {
2098 LM_ERR("Setting of fr_inv_timer_avp failed\n");
2099 return -1;
2100 }
2101 }
2102 return 1;
2103 }
2105 /* Append branches until out of branches or Q_FLAG is set */
2106 prev = avp;
2107 while ((avp = search_next_avp(avp, &val))) {
2108 destroy_avp(prev);
2110 LM_DBG("Next contact is <%s>\n", val.s.s);
2112 if (decode_branch_info(val.s.s, &uri, &dst, &path, &sock, &flags)== 0){
2113 LM_ERR("Decoding of branch info <%.*s> failed\n",
2114 val.s.len, val.s.s);
2115 destroy_avp(avp);
2116 return -1;
2117 }
2119 if (append_branch(msg, &uri, &dst, &path, 0, flags, sock) != 1) {
2120 LM_ERR("Appending branch failed\n");
2121 destroy_avp(avp);
2122 return -1;
2123 }
2125 if (avp->flags & Q_FLAG) {
2126 destroy_avp(avp);
2127 if (route_type == REQUEST_ROUTE) {
2128 val.n = fr_inv_timer_next;
2129 if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val)!= 0){
2130 LM_ERR("Setting of fr_inv_timer_avp failed\n");
2131 return -1;
2132 }
2133 }
2134 return 1;
2135 }
2136 prev = avp;
2137 }
2139 /* Restore fr_inv_timer */
2140 val.n = fr_inv_timer;
2141 if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val) != 0) {
2142 LM_ERR("Setting of fr_inv_timer_avp failed\n");
2143 return -1;
2144 }
2146 return 1;
2147 }
2150 /*
2151 * Convert string parameter to integer for functions that expect an integer.
2152 * Taken from sl module.
2153 */
2154 static int fixstringloadgws(void **param, int param_count)
2155 {
2156 pv_elem_t *model=NULL;
2157 str s;
2159 /* convert to str */
2160 s.s = (char*)*param;
2161 s.len = strlen(s.s);
2163 model=NULL;
2164 if (param_count==1) {
2165 if(s.len==0) {
2166 LM_ERR("No param <%d>!\n", param_count);
2167 return -1;
2168 }
2170 if(pv_parse_format(&s,&model)<0 || model==NULL) {
2171 LM_ERR("Wrong format <%s> for param <%d>!\n", s.s, param_count);
2172 return -1;
2173 }
2174 if(model->spec.getf==NULL) {
2175 if(param_count==1) {
2176 if(str2int(&s, (unsigned int*)&model->spec.pvp.pvn.u.isname.name.n)!=0) {
2177 LM_ERR("Wrong value <%s> for param <%d>!\n",
2178 s.s, param_count);
2179 return -1;
2180 }
2181 }
2182 }
2183 *param = (void*)model;
2184 }
2186 return 0;
2187 }