opensips/modules/lcr/lcr_mod.c

Wed, 10 Feb 2010 21:14:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 10 Feb 2010 21:14:04 +0100
changeset 16
c5c55937e44c
child 17
733187d496d0
permissions
-rw-r--r--

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;
  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;
  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;
  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;
  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';
  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';
  1058 	    lcrs_1[i].grp_id = grp_id;
  1059 	    lcrs_1[i].priority = priority;
  1060 	    lcrs_1[i].end_record = 0;
  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;
  1075     (*lcrs_ws_reload_counter)++;
  1076     if (0 != load_all_regex()) {
  1078 	return -1;
  1081     return 1;
  1085 int mi_print_gws(struct mi_node* rpl)
  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;
  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;
  1173     return 0;
  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)
  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;
  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;
  1221 	    } else {
  1222 		from_uri.s = int2str(val.n, &from_uri.len);
  1223 		have_rpid_avp = 1;
  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;
  1232 	    if (!_m->from) {
  1233 		LM_ERR("From header field not found\n");
  1234 		return -1;
  1236 	    if ((!(_m->from)->parsed) && (parse_from_header(_m) < 0)) {
  1237 		LM_ERR("Error while parsing From header\n");
  1238 		return -1;
  1240 	    from_uri = get_from(_m)->uri;
  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;
  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;
  1260     /*
  1261      * Let's match the gws:
  1262      *  1. prefix matching
  1263      *  2. from_uri matching
  1264      *  3. _grp_id matching
  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;
  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;
  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;
  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;
  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;
  1377 	    matched_gws[i - 1].randomizer = rand();
  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);
  1387 	    prefix_len = (*lcrs)[matched_gws[i].route_index].prefix_len;
  1388 	    priority = (*lcrs)[matched_gws[i].route_index].priority;
  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);
  1399     for (i = 0; i < MAX_NO_OF_GWS; i++) {
  1400 	index = matched_gws[i].gw_index;
  1401 	if (index == -1) {
  1402 	    break;
  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;
  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;
  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;
  1434 	if (tag_len) {
  1435 	    memcpy(at, tag, tag_len); at = at + tag_len;
  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;
  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;
  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;
  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;
  1483     return 1;
  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)
  1493 	str grp_s;
  1494 	unsigned int grp_id;
  1496 	if(((pv_elem_p)_s1)->spec.getf!=NULL)
  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;
  1505 	if (grp_id > 0) return do_load_gws(_m, (str *)0, (int)grp_id);
  1506 	else return -1;
  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)
  1516     return do_load_gws(_m, (str *)0, -1);
  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)
  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;
  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;
  1541     } else {
  1542 	LM_DBG("cannot get pseudo variable value\n");
  1543 	return -1;
  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)
  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;
  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);
  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;
  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;
  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;
  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;
  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;
  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);
  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;
  1650 	return 1;
  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)
  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];
  1675 		} else {
  1676 			LM_ERR("IP address PV empty value\n");
  1677 			return -1;
  1679 	} else {
  1680 		src_addr = _m->rcv.src_ip.u.addr32[0];
  1683     for (i = 0; i < MAX_NO_OF_GWS; i++) {
  1684 	if ((*gws)[i].ip_addr == 0) {
  1685 	    return -1;
  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;
  1697     LM_DBG("Request did not come from gw\n");
  1698     return -1;
  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)
  1708     return do_from_gw(_m, (pv_spec_t *)0, (int)(long)_grp_id);
  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)
  1718     return do_from_gw(_m, (pv_spec_t *)0, -1);
  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)
  1728     return do_from_gw(_m, (pv_spec_t *)_addr_sp, -1);
  1732 /*
  1733  * Checks if in-dialog request goes to gateway
  1734  */
  1735 static int do_to_gw(struct sip_msg* _m, int grp_id)
  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;
  1746     if (_m->parsed_uri.host.len > 15) {
  1747 	return -1;
  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;
  1756     for (i = 0; i < MAX_NO_OF_GWS; i++) {
  1757 	if ((*gws)[i].ip_addr == 0) {
  1758 	    return -1;
  1760 	if ((*gws)[i].ip_addr == addr.s_addr && 
  1761 		(grp_id < 0 || (*gws)[i].grp_id == grp_id)) {
  1762 	    return 1;
  1766     return -1;
  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)
  1776     int grp_id;
  1778     grp_id = (int)(long)_s1;
  1779     return do_to_gw(_m, grp_id);
  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)
  1789     return do_to_gw(_m, -1);
  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);
  1805 /* Encode branch info from contact struct to str */
  1806 static inline int encode_branch_info(str *info, struct contact *con)
  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;
  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;
  1837     } else {
  1838 	len = 0;
  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;
  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)
  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;
  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;
  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;
  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;
  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;
  1903     } else {
  1904 	*sock = 0;
  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;
  1916     } else {
  1917 	*flags = 0;
  1920     return 1;
  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)
  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;
  1946     ruri = GET_RURI(msg);
  1947     if (!ruri) {
  1948 	LM_ERR("No Request-URI found\n");
  1949 	return -1;
  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;
  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;
  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;
  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;
  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;
  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;
  2024 	curr = curr->next;
  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;
  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;
  2045     /* Clear all branches */
  2046     clear_branches();
  2048     /* Free contact list */
  2049     free_contact_list(contacts);
  2051     return 1;
  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)
  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;
  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;
  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;
  2102 		return 1;
  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;
  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;
  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;
  2134 			return 1;
  2136 		prev = avp;
  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;
  2146 	return 1;
  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)
  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;
  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;
  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;
  2183 	*param = (void*)model;
  2186     return 0;

mercurial