opensips/modules/lcr/lcr_mod.c

Mon, 16 Jan 2012 22:56:52 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 16 Jan 2012 22:56:52 +0100
changeset 21
6bb708a2265f
parent 16
c5c55937e44c
permissions
-rw-r--r--

Import original vendor code 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 USER_COL "user"
   119 #define REALM_COL "realm"
   121 #define PASSWD_COL "passwd"
   123 #define MAX_NO_OF_GWS 32
   124 #define MAX_NO_OF_LCRS 256
   125 #define MAX_PREFIX_LEN 256
   126 #define MAX_USER_LEN 64
   127 #define MAX_REALM_LEN 64
   128 #define MAX_PASSWD_LEN 64
   129 #define MAX_TAG_LEN 16
   130 #define MAX_FROM_URI_LEN 256
   132 /* Default module parameter values */
   133 #define DEF_FR_INV_TIMER 90
   134 #define DEF_FR_INV_TIMER_NEXT 30
   135 #define DEF_PREFIX_MODE 0
   137 /*
   138  * Type definitions
   139  */
   141 typedef enum sip_protos uri_transport;
   143 struct gw_info {
   144     unsigned int ip_addr;
   145     unsigned int port;
   146     unsigned int grp_id;
   147     uri_type scheme;
   148     uri_transport transport;
   149     unsigned int strip;
   150     char tag[MAX_TAG_LEN + 1];
   151     unsigned short tag_len;
   152     unsigned int flags;
   153     char user[MAX_USER_LEN];
   154     unsigned short user_len;
   155     char realm[MAX_REALM_LEN];
   156     unsigned short realm_len;
   157     char passwd[MAX_PASSWD_LEN];
   158     unsigned short passwd_len;
   159 };
   161 struct lcr_info {
   162     char prefix[MAX_PREFIX_LEN + 1];
   163     unsigned short prefix_len;
   164     char from_uri[MAX_FROM_URI_LEN + 1];
   165     unsigned short from_uri_len;
   166     unsigned int grp_id;
   167     unsigned short priority;
   168     unsigned short end_record;
   169 };
   171 struct prefix_regex {
   172 	regex_t re;
   173 	short int valid;
   174 };
   176 struct from_uri_regex {
   177     regex_t re;
   178     short int valid;
   179 };
   181 struct mi {
   182     int gw_index;
   183     int route_index;
   184     int randomizer;
   185 };
   188 /*
   189  * Database variables
   190  */
   191 static db_con_t* db_handle = 0;   /* Database connection handle */
   192 static db_func_t lcr_dbf;
   194 /*
   195  * Module parameter variables
   196  */
   198 /* database */
   199 static str db_url           = str_init(DEFAULT_RODB_URL);
   200 static str gw_table         = str_init(GW_TABLE);
   201 static str gw_name_col      = str_init(GW_NAME_COL);
   202 static str grp_id_col       = str_init(GRP_ID_COL);
   203 static str ip_addr_col      = str_init(IP_ADDR_COL);
   204 static str port_col         = str_init(PORT_COL);
   205 static str uri_scheme_col   = str_init(URI_SCHEME_COL);
   206 static str transport_col    = str_init(TRANSPORT_COL);
   207 static str strip_col        = str_init(STRIP_COL);
   208 static str tag_col          = str_init(TAG_COL);
   209 static str flags_col        = str_init(FLAGS_COL);
   210 static str lcr_table        = str_init(LCR_TABLE);
   211 static str prefix_col       = str_init(PREFIX_COL);
   212 static str from_uri_col     = str_init(FROM_URI_COL);
   213 static str priority_col     = str_init(PRIORITY_COL);
   214 static str user_col         = str_init(USER_COL);
   215 static str realm_col        = str_init(REALM_COL);
   216 static str passwd_col       = str_init(PASSWD_COL);
   218 /* timer */
   219 int fr_inv_timer      = DEF_FR_INV_TIMER;
   220 int fr_inv_timer_next = DEF_FR_INV_TIMER_NEXT;
   222 /* avps */
   223 static char *fr_inv_timer_avp_param = NULL;
   224 static char *gw_uri_avp_param = NULL;
   225 static char *ruri_user_avp_param = NULL;
   226 static char *contact_avp_param = NULL;
   227 static char *rpid_avp_param = NULL;
   228 static char *flags_avp_param = NULL;
   229 static char *user_avp_param = NULL;
   230 static char *realm_avp_param = NULL;
   231 static char *passwd_avp_param = NULL;
   233 /* prefix mode */
   234 int prefix_mode_param = DEF_PREFIX_MODE;
   236 /*
   237  * Other module types and variables
   238  */
   240 struct contact {
   241     str uri;
   242     qvalue_t q;
   243     str dst_uri;
   244     str path;
   245     unsigned int flags;
   246     struct socket_info* sock;
   247     unsigned short q_flag;
   248     struct contact *next;
   249 };
   251 static int     fr_inv_timer_avp_type;
   252 static int_str fr_inv_timer_avp;
   253 static int     gw_uri_avp_type;
   254 static int_str gw_uri_avp;
   255 static int     ruri_user_avp_type;
   256 static int_str ruri_user_avp;
   257 static int     contact_avp_type;
   258 static int_str contact_avp;
   259 static int     rpid_avp_type;
   260 static int_str rpid_avp;
   261 static int     flags_avp_type;
   262 static int_str flags_avp;
   263 static int     user_avp_type;
   264 static int_str user_avp;
   265 static int     realm_avp_type;
   266 static int_str realm_avp;
   267 static int     passwd_avp_type;
   268 static int_str passwd_avp;
   270 struct gw_info **gws;	/* Pointer to current gw table pointer */
   271 struct gw_info *gws_1;	/* Pointer to gw table 1 */
   272 struct gw_info *gws_2;	/* Pointer to gw table 2 */
   274 struct lcr_info **lcrs;  /* Pointer to current lcr table pointer */
   275 struct lcr_info *lcrs_1; /* Pointer to lcr table 1 */
   276 struct lcr_info *lcrs_2; /* Pointer to lcr table 2 */
   278 unsigned int *lcrs_ws_reload_counter;
   279 unsigned int reload_counter;
   281 struct prefix_regex prefix_reg[MAX_NO_OF_LCRS];
   282 struct from_uri_regex from_uri_reg[MAX_NO_OF_LCRS];
   284 /*
   285  * Module functions that are defined later
   286  */
   287 static int load_gws_0(struct sip_msg* _m, char* _s1, char* _s2);
   288 static int load_gws_1(struct sip_msg* _m, char* _s1, char* _s2);
   289 static int load_gws_from_grp(struct sip_msg* _m, char* _s1, char* _s2);
   290 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2);
   291 static int from_gw_0(struct sip_msg* _m, char* _s1, char* _s2);
   292 static int from_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
   293 static int from_gw_grp(struct sip_msg* _m, char* _s1, char* _s2);
   294 static int to_gw(struct sip_msg* _m, char* _s1, char* _s2);
   295 static int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2);
   296 static int load_contacts (struct sip_msg*, char*, char*);
   297 static int next_contacts (struct sip_msg*, char*, char*);
   300 /*
   301  * Exported functions
   302  */
   303 static cmd_export_t cmds[] = {
   304 	{"load_gws", (cmd_function)load_gws_0, 0, 0, 0, REQUEST_ROUTE},
   305 	{"load_gws", (cmd_function)load_gws_1, 1, fixup_pvar_null,
   306 		fixup_free_pvar_null, REQUEST_ROUTE},
   307 	{"load_gws_from_grp", (cmd_function)load_gws_from_grp, 1,
   308 	 fixstringloadgws, 0, REQUEST_ROUTE},
   309 	{"next_gw", (cmd_function)next_gw, 0, 0, 0,
   310 	 REQUEST_ROUTE | FAILURE_ROUTE},
   311 	{"from_gw", (cmd_function)from_gw_0, 0, 0, 0,
   312 	 REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
   313 	{"from_gw", (cmd_function)from_gw_1, 1, fixup_pvar_null,
   314 	 fixup_free_pvar_null, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
   315 	{"from_gw_grp", (cmd_function)from_gw_grp, 1, fixup_uint_null, 0,
   316 	 REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
   317 	{"to_gw", (cmd_function)to_gw, 0, 0, 0,
   318 	 REQUEST_ROUTE | FAILURE_ROUTE},
   319 	{"to_gw", (cmd_function)to_gw_grp, 1, fixup_uint_null, 0,
   320 	 REQUEST_ROUTE | FAILURE_ROUTE},
   321 	{"load_contacts", (cmd_function)load_contacts, 0, 0, 0,
   322 	 REQUEST_ROUTE},
   323 	{"next_contacts", (cmd_function)next_contacts, 0, 0, 0,
   324 	 REQUEST_ROUTE | FAILURE_ROUTE},
   325 	{0, 0, 0, 0, 0, 0}
   326 };
   329 /*
   330  * Exported parameters
   331  */
   332 static param_export_t params[] = {
   333 	{"db_url",                   STR_PARAM, &db_url.s       },
   334 	{"gw_table",                 STR_PARAM, &gw_table.s     },
   335 	{"gw_name_column",           STR_PARAM, &gw_name_col.s  },
   336 	{"grp_id_column",            STR_PARAM, &grp_id_col.s   },
   337 	{"ip_addr_column",           STR_PARAM, &ip_addr_col.s  },
   338 	{"port_column",              STR_PARAM, &port_col.s     },
   339 	{"uri_scheme_column",        STR_PARAM, &uri_scheme_col.s },
   340 	{"transport_column",         STR_PARAM, &transport_col.s },
   341 	{"strip_column",             STR_PARAM, &strip_col.s    },
   342 	{"tag_column",               STR_PARAM, &tag_col.s      },
   343 	{"flags_column",             STR_PARAM, &flags_col.s    },
   344 	{"lcr_table",                STR_PARAM, &lcr_table.s    },
   345 	{"prefix_column",            STR_PARAM, &prefix_col.s   },
   346 	{"from_uri_column",          STR_PARAM, &from_uri_col.s },
   347 	{"priority_column",          STR_PARAM, &priority_col.s },
   348 	{"fr_inv_timer_avp",         STR_PARAM,	&fr_inv_timer_avp_param },
   349 	{"gw_uri_avp",               STR_PARAM, &gw_uri_avp_param },
   350 	{"ruri_user_avp",            STR_PARAM, &ruri_user_avp_param },
   351 	{"contact_avp",              STR_PARAM, &contact_avp_param },
   352 	{"rpid_avp",                 STR_PARAM, &rpid_avp_param },
   353 	{"flags_avp",                STR_PARAM, &flags_avp_param },
   354 	{"fr_inv_timer",             INT_PARAM, &fr_inv_timer },
   355 	{"fr_inv_timer_next",        INT_PARAM,	&fr_inv_timer_next },
   356 	{"prefix_mode",              INT_PARAM, &prefix_mode_param },
   357 	{"user_column",              STR_PARAM, &user_col.s },
   358 	{"realm_column",             STR_PARAM, &realm_col.s },
   359 	{"passwd_column",            STR_PARAM, &passwd_col.s },
   360 	{"auth_username_avp",        STR_PARAM, &user_avp_param },
   361 	{"auth_realm_avp",           STR_PARAM, &realm_avp_param },
   362 	{"auth_password_avp",        STR_PARAM, &passwd_avp_param },
   363 	{0, 0, 0}
   364 };
   367 /*
   368  * Exported MI functions
   369  */
   370 static mi_export_t mi_cmds[] = {
   371 	{ MI_LCR_RELOAD,  mi_lcr_reload,   MI_NO_INPUT_FLAG,  0,  mi_child_init },
   372 	{ MI_LCR_DUMP,    mi_lcr_dump,     MI_NO_INPUT_FLAG,  0,  0 },
   373 	{ 0, 0, 0, 0 ,0}
   374 };
   377 /*
   378  * Module interface
   379  */
   380 struct module_exports exports = {
   381 	"lcr", 
   382 	MODULE_VERSION,
   383 	DEFAULT_DLFLAGS, /* dlopen flags */
   384 	cmds,      /* Exported functions */
   385 	params,    /* Exported parameters */
   386 	0,         /* exported statistics */
   387 	mi_cmds,   /* exported MI functions */
   388 	0,         /* exported pseudo-variables */
   389 	0,         /* extra processes */
   390 	mod_init,  /* module initialization function */
   391 	0,         /* response function */
   392 	destroy,   /* destroy function */
   393 	0          /* child initialization function */
   394 };
   397 static int lcr_db_init(const str* db_url)
   398 {	
   399 	if (lcr_dbf.init==0){
   400 		LM_CRIT("Null lcr_dbf\n");
   401 		goto error;
   402 	}
   403 	db_handle=lcr_dbf.init(db_url);
   404 	if (db_handle==0){
   405 		LM_ERR("Unable to connect to the database\n");
   406 		goto error;
   407 	}
   408 	return 0;
   409 error:
   410 	return -1;
   411 }
   415 static int lcr_db_bind(const str* db_url)
   416 {
   417     if (db_bind_mod(db_url, &lcr_dbf)<0){
   418 	LM_ERR("Unable to bind to the database module\n");
   419 	return -1;
   420     }
   422     if (!DB_CAPABILITY(lcr_dbf, DB_CAP_QUERY)) {
   423 	LM_ERR("Database module does not implement 'query' function\n");
   424 	return -1;
   425     }
   427     return 0;
   428 }
   431 static void lcr_db_close(void)
   432 {
   433 	if (db_handle && lcr_dbf.close){
   434 		lcr_dbf.close(db_handle);
   435 		db_handle=0;
   436 	}
   437 }
   440 static int mi_child_init(void)
   441 {
   442 	return lcr_db_init(&db_url);
   443 }
   446 /*
   447  * Module initialization function that is called before the main process forks
   448  */
   449 static int mod_init(void)
   450 {
   451 	int i;
   452     pv_spec_t avp_spec;
   453     str s;
   454     unsigned short avp_flags;
   456     LM_DBG("Initializing\n");
   458     /* Update length of module variables */
   459     db_url.len = strlen(db_url.s);
   460     gw_table.len = strlen(gw_table.s);
   461     gw_name_col.len = strlen(gw_name_col.s);
   462     grp_id_col.len = strlen(grp_id_col.s);
   463     ip_addr_col.len = strlen(ip_addr_col.s);
   464     port_col.len = strlen(port_col.s);
   465     uri_scheme_col.len = strlen(uri_scheme_col.s);
   466     transport_col.len = strlen(transport_col.s);
   467     strip_col.len = strlen(strip_col.s);
   468     tag_col.len = strlen(tag_col.s);
   469     flags_col.len = strlen(flags_col.s);
   470     lcr_table.len = strlen(lcr_table.s);
   471     prefix_col.len = strlen(prefix_col.s);
   472     from_uri_col.len = strlen(from_uri_col.s);
   473     priority_col.len = strlen(priority_col.s);
   474     user_col.len = strlen(user_col.s);
   475     realm_col.len = strlen(realm_col.s);
   476     passwd_col.len = strlen(passwd_col.s);
   478     /* Bind database */
   479     if (lcr_db_bind(&db_url)) {
   480 	LM_ERR("No database module found\n");
   481 	return -1;
   482     }
   484     /* Check value of prefix_mode */
   485     if ((prefix_mode_param != 0) && (prefix_mode_param != 1)) {
   486 	LM_ERR("Invalid prefix_mode value <%d>\n", prefix_mode_param);
   487 	return -1;
   488     }
   490     /* Process AVP params */
   491     if (fr_inv_timer_avp_param && *fr_inv_timer_avp_param) {
   492 	s.s = fr_inv_timer_avp_param; s.len = strlen(s.s);
   493 	if (pv_parse_spec(&s, &avp_spec)==0
   494 	    || avp_spec.type!=PVT_AVP) {
   495 	    LM_ERR("Malformed or non AVP definition <%s>\n",
   496 		   fr_inv_timer_avp_param);
   497 	    return -1;
   498 	}
   500 	if(pv_get_avp_name(0, &(avp_spec.pvp), &fr_inv_timer_avp, &avp_flags)!=0) {
   501 	    LM_ERR("Invalid AVP definition <%s>\n", fr_inv_timer_avp_param);
   502 	    return -1;
   503 	}
   504 	fr_inv_timer_avp_type = avp_flags;
   505     } else {
   506 	LM_ERR("AVP fr_inv_timer_avp has not been defined\n");
   507 	return -1;
   508     }
   510     if (gw_uri_avp_param && *gw_uri_avp_param) {
   511 	s.s = gw_uri_avp_param; s.len = strlen(s.s);
   512 	if (pv_parse_spec(&s, &avp_spec)==0
   513 	    || avp_spec.type!=PVT_AVP) {
   514 	    LM_ERR("Malformed or non AVP definition <%s>\n", gw_uri_avp_param);
   515 	    return -1;
   516 	}
   518 	if(pv_get_avp_name(0, &(avp_spec.pvp), &gw_uri_avp, &avp_flags)!=0) {
   519 	    LM_ERR("Invalid AVP definition <%s>\n", gw_uri_avp_param);
   520 	    return -1;
   521 	}
   522 	gw_uri_avp_type = avp_flags;
   523     } else {
   524 	LM_ERR("AVP gw_uri_avp has not been defined\n");
   525 	return -1;
   526     }
   528     if (ruri_user_avp_param && *ruri_user_avp_param) {
   529 	s.s = ruri_user_avp_param; s.len = strlen(s.s);
   530 	if (pv_parse_spec(&s, &avp_spec)==0
   531 	    || avp_spec.type!=PVT_AVP) {
   532 	    LM_ERR("Malformed or non AVP definition <%s>\n",
   533 		   ruri_user_avp_param);
   534 	    return -1;
   535 	}
   537 	if(pv_get_avp_name(0, &(avp_spec.pvp), &ruri_user_avp, &avp_flags)!=0) {
   538 	    LM_ERR("Invalid AVP definition <%s>\n", ruri_user_avp_param);
   539 	    return -1;
   540 	}
   541 	ruri_user_avp_type = avp_flags;
   542     } else {
   543 	LM_ERR("AVP ruri_user_avp has not been defined\n");
   544 	return -1;
   545     }
   547     if (contact_avp_param && *contact_avp_param) {
   548 	s.s = contact_avp_param; s.len = strlen(s.s);
   549 	if (pv_parse_spec(&s, &avp_spec)==0
   550 	    || avp_spec.type!=PVT_AVP) {
   551 	    LM_ERR("Malformed or non AVP definition <%s>\n",
   552 		   contact_avp_param);
   553 	    return -1;
   554 	}
   556 	if(pv_get_avp_name(0, &(avp_spec.pvp), &contact_avp, &avp_flags)!=0) {
   557 	    LM_ERR("Invalid AVP definition <%s>\n", contact_avp_param);
   558 	    return -1;
   559 	}
   560 	contact_avp_type = avp_flags;
   561     } else {
   562 	LM_ERR("AVP contact_avp has not been defined\n");
   563 	return -1;
   564     }
   566     if (rpid_avp_param && *rpid_avp_param) {
   567 	s.s = rpid_avp_param; s.len = strlen(s.s);
   568 	if (pv_parse_spec(&s, &avp_spec)==0
   569 	    || avp_spec.type!=PVT_AVP) {
   570 	    LM_ERR("Malformed or non AVP definition <%s>\n", rpid_avp_param);
   571 	    return -1;
   572 	}
   574 	if(pv_get_avp_name(0, &(avp_spec.pvp), &rpid_avp, &avp_flags)!=0) {
   575 	    LM_ERR("Invalid AVP definition <%s>\n", rpid_avp_param);
   576 	    return -1;
   577 	}
   578 	rpid_avp_type = avp_flags;
   579     } else {
   580 	LM_ERR("AVP rpid_avp has not been defined\n");
   581 	return -1;
   582     }
   584     if (flags_avp_param && *flags_avp_param) {
   585 	s.s = flags_avp_param; s.len = strlen(s.s);
   586 	if (pv_parse_spec(&s, &avp_spec)==0
   587 	    || avp_spec.type!=PVT_AVP) {
   588 	    LM_ERR("Malformed or non AVP definition <%s>\n", flags_avp_param);
   589 	    return -1;
   590 	}
   592 	if(pv_get_avp_name(0, &(avp_spec.pvp), &flags_avp, &avp_flags)!=0) {
   593 	    LM_ERR("Invalid AVP definition <%s>\n", flags_avp_param);
   594 	    return -1;
   595 	}
   596 	flags_avp_type = avp_flags;
   597     } else {
   598 	LM_ERR("AVP flags_avp has not been defined\n");
   599 	return -1;
   600     }
   602 	if (user_avp_param && *user_avp_param) {
   603 	s.s = user_avp_param; s.len = strlen(s.s);
   604 	if (pv_parse_spec(&s, &avp_spec)==0
   605 	    || avp_spec.type!=PVT_AVP) {
   606 	    LM_ERR("Malformed or non AVP definition <%s>\n", user_avp_param);
   607 	    return -1;
   608 	}
   610 	if(pv_get_avp_name(0, &(avp_spec.pvp), &user_avp, &avp_flags)!=0) {
   611 	    LM_ERR("Invalid AVP definition <%s>\n", user_avp_param);
   612 	    return -1;
   613 	}
   614 	user_avp_type = avp_flags;
   615     } else {
   616 	LM_ERR("AVP user_avp has not been defined\n");
   617 	return -1;
   618     }
   620 	if (realm_avp_param && *realm_avp_param) {
   621 	s.s = realm_avp_param; s.len = strlen(s.s);
   622 	if (pv_parse_spec(&s, &avp_spec)==0
   623 	    || avp_spec.type!=PVT_AVP) {
   624 	    LM_ERR("Malformed or non AVP definition <%s>\n", realm_avp_param);
   625 	    return -1;
   626 	}
   628 	if(pv_get_avp_name(0, &(avp_spec.pvp), &realm_avp, &avp_flags)!=0) {
   629 	    LM_ERR("Invalid AVP definition <%s>\n", realm_avp_param);
   630 	    return -1;
   631 	}
   632 	realm_avp_type = avp_flags;
   633     } else {
   634 	LM_ERR("AVP realm_avp has not been defined\n");
   635 	return -1;
   636     }
   638 	if (passwd_avp_param && *passwd_avp_param) {
   639 	s.s = passwd_avp_param; s.len = strlen(s.s);
   640 	if (pv_parse_spec(&s, &avp_spec)==0
   641 	    || avp_spec.type!=PVT_AVP) {
   642 	    LM_ERR("Malformed or non AVP definition <%s>\n", passwd_avp_param);
   643 	    return -1;
   644 	}
   646 	if(pv_get_avp_name(0, &(avp_spec.pvp), &passwd_avp, &avp_flags)!=0) {
   647 	    LM_ERR("Invalid AVP definition <%s>\n", passwd_avp_param);
   648 	    return -1;
   649 	}
   650 	passwd_avp_type = avp_flags;
   651     } else {
   652 	LM_ERR("AVP passwd_avp has not been defined\n");
   653 	return -1;
   654     }
   656     /* Check table version */
   657 	db_con_t* dbh;
   658 	if (lcr_dbf.init==0){
   659 		LM_CRIT("Unbound database\n");
   660 		return -1;
   661 	}
   662 	dbh=lcr_dbf.init(&db_url);
   663 	if (dbh==0){
   664 		LM_ERR("Unable to open database connection\n");
   665 		return -1;
   666 	}
   667 	if((db_check_table_version(&lcr_dbf, dbh, &gw_table, GW_TABLE_VERSION) < 0) ||
   668 		(db_check_table_version(&lcr_dbf, dbh, &lcr_table, LCR_TABLE_VERSION) < 0)) {
   669 			LM_ERR("error during table version check.\n");
   670 			lcr_dbf.close(dbh);
   671 			goto err;
   672     }
   673 	lcr_dbf.close(dbh);
   675     /* Initializing gw tables and gw table pointer variable */
   676     gws_1 = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
   677 					 (MAX_NO_OF_GWS + 1));
   678     if (gws_1 == 0) {
   679 	LM_ERR("No memory for gw table\n");
   680 	goto err;
   681     }
   682     gws_2 = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
   683 					 (MAX_NO_OF_GWS + 1));
   684     if (gws_2 == 0) {
   685 	LM_ERR("No memory for gw table\n");
   686 	goto err;
   687     }
   688     for (i = 0; i < MAX_NO_OF_GWS + 1; i++) {
   689 	gws_1[i].ip_addr = gws_2[i].ip_addr = 0;
   690     }
   691     gws = (struct gw_info **)shm_malloc(sizeof(struct gw_info *));
   692     if (gws == 0) {
   693 	LM_ERR("No memory for gw table pointer\n");
   694     }
   695     *gws = gws_1;
   697     /* Initializing lcr tables and lcr table pointer variable */
   698     lcrs_1 = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info) *
   699 					   (MAX_NO_OF_LCRS + 1));
   700     if (lcrs_1 == 0) {
   701 	LM_ERR("No memory for lcr table\n");
   702 	goto err;
   703     }
   704     lcrs_2 = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info) *
   705 					   (MAX_NO_OF_LCRS + 1));
   706     if (lcrs_2 == 0) {
   707 	LM_ERR("No memory for lcr table\n");
   708 	goto err;
   709     }
   710     for (i = 0; i < MAX_NO_OF_LCRS + 1; i++) {
   711 	lcrs_1[i].end_record = lcrs_2[i].end_record = 0;
   712     }
   713     lcrs = (struct lcr_info **)shm_malloc(sizeof(struct lcr_info *));
   714     if (lcrs == 0) {
   715 	LM_ERR("No memory for lcr table pointer\n");
   716 	goto err;
   717     }
   718     *lcrs = lcrs_1;
   720     lcrs_ws_reload_counter = (unsigned int *)shm_malloc(sizeof(unsigned int));
   721     if (lcrs_ws_reload_counter == 0) {
   722 	LM_ERR("No memory for reload counter\n");
   723 	goto err;
   724     }
   725     *lcrs_ws_reload_counter = reload_counter = 0;
   727     memset(prefix_reg, 0, sizeof(struct prefix_regex) * MAX_NO_OF_LCRS);
   728     memset(from_uri_reg, 0, sizeof(struct from_uri_regex) * MAX_NO_OF_LCRS);
   730     /* First reload */
   731     if (reload_gws() == -1) {
   732 	LM_CRIT("Failed to reload gateways and routes\n");
   733 	goto err;
   734     }
   736     return 0;
   738 err:
   739     return -1;
   740 }
   743 static void destroy(void)
   744 {
   745 	lcr_db_close();
   746 }
   748 /*
   749  * Sort lcr records by prefix_len and priority.
   750  */
   751 static int comp_lcrs(const void *m1, const void *m2)
   752 {
   753     int result = -1;
   755     struct mi *mi1 = (struct mi *) m1;
   756     struct mi *mi2 = (struct mi *) m2;
   758     struct lcr_info lcr_record1 = (*lcrs)[mi1->route_index];
   759     struct lcr_info lcr_record2 = (*lcrs)[mi2->route_index];
   761     if (prefix_mode_param == 0) {
   762         /* Sort by prefix. */
   763         if (lcr_record1.prefix_len > lcr_record2.prefix_len) {
   764 	    result = 1;
   765         } else if (lcr_record1.prefix_len == lcr_record2.prefix_len) {
   766 	    /* Sort by priority. */
   767 	    if (lcr_record1.priority < lcr_record2.priority) {
   768 	        result = 1;
   769 	    } else if (lcr_record1.priority == lcr_record2.priority) {
   770 	        /* Nothing to do. */
   771 	        result = 0;
   772 	    }
   773         }
   774     } else {
   775         if (lcr_record1.priority < lcr_record2.priority) {
   776 	    result = 1;
   777 	} else if (lcr_record1.priority == lcr_record2.priority) {
   778 	    /* Nothing to do. */
   779 	    result = 0;
   780 	}
   781     }
   783     return result;
   784 }
   786 /*
   787  * Sort lcr records by rand table.
   788  */
   789 static int rand_lcrs(const void *m1, const void *m2)
   790 {
   791     int result = -1;
   793     struct mi mi1 = *((struct mi *) m1);
   794     struct mi mi2 = *((struct mi *) m2);
   796     if (mi1.randomizer > mi2.randomizer) {
   797 	result = 1;
   798     } else if (mi1.randomizer == mi2.randomizer) {
   799 	result = 0;
   800     }
   802     return result;
   803 }
   805 /*
   806  * regcomp each prefix.
   807  */
   808 static int load_prefix_regex(void)
   809 {
   810     int i, status, result = 0;
   812     for (i = 0; i < MAX_NO_OF_LCRS; i++) {
   813 	if ((*lcrs)[i].end_record != 0) {
   814 	    break;
   815 	}
   816 	if (prefix_reg[i].valid) {
   817 	    regfree(&(prefix_reg[i].re));
   818 	    prefix_reg[i].valid = 0;
   819 	}
   820 	memset(&(prefix_reg[i].re), 0, sizeof(regex_t));
   821 	if ((status=regcomp(&(prefix_reg[i].re),(*lcrs)[i].prefix,0))!=0){
   822 	    LM_ERR("bad prefix re <%s>, regcomp returned %d (check regex.h)\n",
   823 		(*lcrs)[i].prefix, status);
   824 	    result = -1;
   825 	    break;
   826 	}
   827 	prefix_reg[i].valid = 1;
   828     }
   830     return result;
   831 }
   833 /*
   834  * regcomp each from_uri.
   835  */
   836 static int load_from_uri_regex(void)
   837 {
   838     int i, status, result = 0;
   840     for (i = 0; i < MAX_NO_OF_LCRS; i++) {
   841 	if ((*lcrs)[i].end_record != 0) {
   842 	    break;
   843 	}
   844 	if (from_uri_reg[i].valid) {
   845 	    regfree(&(from_uri_reg[i].re));
   846 	    from_uri_reg[i].valid = 0;
   847 	}
   848 	memset(&(from_uri_reg[i].re), 0, sizeof(regex_t));
   849 	if ((status=regcomp(&(from_uri_reg[i].re),(*lcrs)[i].from_uri,0))!=0){
   850 	    LM_ERR("Bad from_uri re <%s>, regcomp returned %d (check regex.h)\n",
   851 	    	(*lcrs)[i].from_uri, status);
   852 	    result = -1;
   853 	    break;
   854 	}
   855 	from_uri_reg[i].valid = 1;
   856     }
   858     if (result != -1) {
   859 	reload_counter = *lcrs_ws_reload_counter;
   860     }
   861     return result;
   862 }
   864 static int load_all_regex(void)
   865 {
   866 	int result =0;
   868 	if (prefix_mode_param != 0) {
   869 		result = load_prefix_regex();
   870 	}
   872 	if (result == 0) {
   873 		result = load_from_uri_regex();
   874 	} else {
   875 		LM_ERR("Unable to load prefix regex\n");
   876 	}
   878 	if (result == 0) {
   879 		reload_counter = *lcrs_ws_reload_counter;
   880 	} else {
   881 		LM_ERR("Unable to load from_uri regex\n");
   882 	}
   884 	return result;
   885 }
   887 /*
   888  * Reload gws to unused gw table and lcrs to unused lcr table, and, when done
   889  * make unused gw and lcr table the one in use.
   890  */
   891 int reload_gws(void)
   892 {
   893     unsigned int i, port, strip, tag_len, prefix_len, from_uri_len,
   894     user_len, realm_len, passwd_len, grp_id, priority;
   895     struct in_addr ip_addr;
   896     unsigned int flags;
   897     uri_type scheme;
   898     uri_transport transport;
   899     db_con_t* dbh;
   900     char *tag, *prefix, *from_uri;
   901     char *user, *realm, *passwd;
   902     db_res_t* res = NULL;
   903     db_row_t* row;
   904     db_key_t gw_cols[11];
   905     db_key_t lcr_cols[4];
   907     gw_cols[0] = &ip_addr_col;
   908     gw_cols[1] = &port_col;
   909     gw_cols[2] = &uri_scheme_col;
   910     gw_cols[3] = &transport_col;
   911     gw_cols[4] = &strip_col;
   912     gw_cols[5] = &tag_col;
   913     /* FIXME: is this ok if we have different names for grp_id
   914        in the two tables? (ge vw lcr) */
   915     gw_cols[6] = &grp_id_col;
   916     gw_cols[7] = &flags_col;
   917     gw_cols[8] = &user_col;
   918     gw_cols[9] = &realm_col;
   919     gw_cols[10] = &passwd_col;
   921     lcr_cols[0] = &prefix_col;
   922     lcr_cols[1] = &from_uri_col;
   923     /* FIXME: is this ok if we have different names for grp_id
   924        in the two tables? (ge vw lcr) */
   925     lcr_cols[2] = &grp_id_col;
   926     lcr_cols[3] = &priority_col;
   928     if (lcr_dbf.init==0){
   929 	LM_CRIT("Unbound database\n");
   930 	return -1;
   931     }
   932     dbh=lcr_dbf.init(&db_url);
   933     if (dbh==0){
   934 	LM_ERR("Unable to open database connection\n");
   935 	return -1;
   936     }
   938     if (lcr_dbf.use_table(dbh, &gw_table) < 0) {
   939 	LM_ERR("Error while trying to use gw table\n");
   940 	return -1;
   941     }
   943     if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 11, 0, &res) < 0) {
   944 	    LM_ERR("Failed to query gw data\n");
   945 	    lcr_dbf.close(dbh);
   946 	    return -1;
   947     }
   949     if (RES_ROW_N(res) + 1 > MAX_NO_OF_GWS) {
   950 	    LM_ERR("Too many gateways\n");
   951 	    lcr_dbf.free_result(dbh, res);
   952 	    lcr_dbf.close(dbh);
   953 	    return -1;
   954     }
   956     for (i = 0; i < RES_ROW_N(res); i++) {
   957 	row = RES_ROWS(res) + i;
   958 	if (!((VAL_TYPE(ROW_VALUES(row)) == DB_STRING) &&
   959 	      !VAL_NULL(ROW_VALUES(row)) &&
   960 	      inet_aton((char *)VAL_STRING(ROW_VALUES(row)), &ip_addr) != 0)) {
   961 	    LM_ERR("Invalid IP address of gw <%s>\n",
   962 		   (char *)VAL_STRING(ROW_VALUES(row)));
   963 	    lcr_dbf.free_result(dbh, res);
   964 	    lcr_dbf.close(dbh);
   965 	    return -1;
   966 	}
   967 	if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
   968 	    port = 0;
   969 	} else {
   970 	    port = (unsigned int)VAL_INT(ROW_VALUES(row) + 1);
   971 	}
   972 	if (port > 65536) {
   973 	    LM_ERR("Port of gw is too large <%u>\n", port);
   974 	    lcr_dbf.free_result(dbh, res);
   975 	    lcr_dbf.close(dbh);
   976 	    return -1;
   977 	}
   978 	if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {
   979 	    scheme = SIP_URI_T;
   980 	} else {
   981 	    scheme = (uri_type)VAL_INT(ROW_VALUES(row) + 2);
   982 	    if ((scheme != SIP_URI_T) && (scheme != SIPS_URI_T)) {
   983 		LM_ERR("Unknown or unsupported URI scheme <%u>\n",
   984 		       (unsigned int)scheme);
   985 		lcr_dbf.free_result(dbh, res);
   986 		lcr_dbf.close(dbh);
   987 		return -1;
   988 	    }
   989 	}
   990 	if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {
   991 	    transport = PROTO_NONE;
   992 	} else {
   993 	    transport = (uri_transport)VAL_INT(ROW_VALUES(row) + 3);
   994 	    if ((transport != PROTO_UDP) && (transport != PROTO_TCP) &&
   995 		(transport != PROTO_TLS)) {
   996 		LM_ERR("Unknown or unsupported transport <%u>\n",
   997 		       (unsigned int)transport);
   998 		lcr_dbf.free_result(dbh, res);
   999 		lcr_dbf.close(dbh);
  1000 		return -1;
  1003 	if (VAL_NULL(ROW_VALUES(row) + 4) == 1) {
  1004 	    strip = 0;
  1005 	} else {
  1006 	    strip = (unsigned int)VAL_INT(ROW_VALUES(row) + 4);
  1008 	if (VAL_NULL(ROW_VALUES(row) + 5) == 1) {
  1009 	    tag_len = 0;
  1010 	    tag = (char *)0;
  1011 	} else {
  1012 	    tag = (char *)VAL_STRING(ROW_VALUES(row) + 5);
  1013 	    tag_len = strlen(tag);
  1014 	    if (tag_len > MAX_TAG_LEN) {
  1015 		LM_ERR("Too long gw tag <%u>\n", tag_len);
  1016 		lcr_dbf.free_result(dbh, res);
  1017 		lcr_dbf.close(dbh);
  1018 		return -1;
  1021 	if (VAL_NULL(ROW_VALUES(row) + 6) == 1) {
  1022 	    grp_id = 0;
  1023 	} else {
  1024 	    grp_id = VAL_INT(ROW_VALUES(row) + 6);
  1026 	if (!VAL_NULL(ROW_VALUES(row) + 7) &&
  1027 	    (VAL_TYPE(ROW_VALUES(row) + 7) == DB_INT)) {
  1028 	    flags = (unsigned int)VAL_INT(ROW_VALUES(row) + 7);
  1029 	} else {
  1030 	    LM_ERR("Attribute flags is NULL or non-int\n");
  1031 	    lcr_dbf.free_result(dbh, res);
  1032 	    lcr_dbf.close(dbh);
  1033 	    return -1;
  1035 	if (VAL_NULL(ROW_VALUES(row) + 8) == 1) {
  1036 	    user_len = 0;
  1037 	    user = (char *)0;
  1038 	} else {
  1039 	    user = (char *)VAL_STRING(ROW_VALUES(row) + 8);
  1040 	    user_len = strlen(user);
  1041 	    if (user_len > MAX_USER_LEN) {
  1042 		LM_ERR("Too long gw user <%u>\n", user_len);
  1043 		lcr_dbf.free_result(dbh, res);
  1044 		lcr_dbf.close(dbh);
  1045 		return -1;
  1048 	if (VAL_NULL(ROW_VALUES(row) + 9) == 1) {
  1049 	    realm_len = 0;
  1050 	    realm = (char *)0;
  1051 	} else {
  1052 	    realm = (char *)VAL_STRING(ROW_VALUES(row) + 9);
  1053 	    realm_len = strlen(realm);
  1054 	    if (realm_len > MAX_REALM_LEN) {
  1055 		LM_ERR("Too long gw realm <%u>\n", realm_len);
  1056 		lcr_dbf.free_result(dbh, res);
  1057 		lcr_dbf.close(dbh);
  1058 		return -1;
  1061 	if (VAL_NULL(ROW_VALUES(row) + 10) == 1) {
  1062 	    passwd_len = 0;
  1063 	    passwd = (char *)0;
  1064 	} else {
  1065 	    passwd = (char *)VAL_STRING(ROW_VALUES(row) + 10);
  1066 	    passwd_len = strlen(passwd);
  1067 	    if (passwd_len > MAX_PASSWD_LEN) {
  1068 		LM_ERR("Too long gw passwd <%u>\n", passwd_len);
  1069 		lcr_dbf.free_result(dbh, res);
  1070 		lcr_dbf.close(dbh);
  1071 		return -1;
  1074 	if (*gws == gws_1) {
  1075 	    gws_2[i].ip_addr = (unsigned int)ip_addr.s_addr;
  1076 	    gws_2[i].port = port;
  1077 	    gws_2[i].grp_id = grp_id;
  1078 	    gws_2[i].scheme = scheme;
  1079 	    gws_2[i].transport = transport;
  1080 	    gws_2[i].flags = flags;
  1081 	    gws_2[i].strip = strip;
  1082 	    gws_2[i].tag_len = tag_len;
  1083 	    if (tag_len)
  1084 		memcpy(&(gws_2[i].tag[0]), tag, tag_len);
  1085 	    gws_2[i].user_len = user_len;
  1086 	    if (user_len)
  1087 	    memcpy(&(gws_2[i].user[0]), user, user_len);
  1088 	    gws_2[i].realm_len = realm_len;
  1089 	    if (realm_len)
  1090 	    memcpy(&(gws_2[i].realm[0]), realm, realm_len);
  1091 	    gws_2[i].passwd_len = passwd_len;
  1092 	    if (passwd_len)
  1093 	    memcpy(&(gws_2[i].passwd[0]), passwd, passwd_len);
  1094 	} else {
  1095 	    gws_1[i].ip_addr = (unsigned int)ip_addr.s_addr;
  1096 	    gws_1[i].port = port;
  1097 	    gws_1[i].grp_id = grp_id;
  1098 	    gws_1[i].scheme = scheme;
  1099 	    gws_1[i].transport = transport;
  1100 	    gws_1[i].flags = flags;
  1101 	    gws_1[i].strip = strip;
  1102 	    gws_1[i].tag_len = tag_len;
  1103 	    if (tag_len)
  1104 		memcpy(&(gws_1[i].tag[0]), tag, tag_len);
  1105 	    gws_1[i].user_len = user_len;
  1106 	    if (user_len)
  1107 	    memcpy(&(gws_1[i].user[0]), user, user_len);
  1108 	    gws_1[i].realm_len = realm_len;
  1109 	    if (realm_len)
  1110 	    memcpy(&(gws_1[i].realm[0]), realm, realm_len);
  1111 	    gws_1[i].passwd_len = passwd_len;
  1112 	    if (passwd_len)
  1113 	    memcpy(&(gws_1[i].passwd[0]), passwd, passwd_len);
  1117     lcr_dbf.free_result(dbh, res);
  1119     if (*gws == gws_1) {
  1120 	gws_2[i].ip_addr = 0;
  1121 	*gws = gws_2;
  1122     } else {
  1123 	gws_1[i].ip_addr = 0;
  1124 	*gws = gws_1;
  1128     if (lcr_dbf.use_table(dbh, &lcr_table) < 0) {
  1129 	LM_ERR("Error while trying to use lcr table\n");
  1130 	return -1;
  1133     if (lcr_dbf.query(dbh, NULL, 0, NULL, lcr_cols, 0, 4, 0, &res) < 0) {
  1134 	LM_ERR("Failed to query lcr data\n");
  1135 	lcr_dbf.close(dbh);
  1136 	return -1;
  1139     if (RES_ROW_N(res) + 1 > MAX_NO_OF_LCRS) {
  1140 	LM_ERR("Too many lcr entries <%d>\n", RES_ROW_N(res));
  1141 	lcr_dbf.free_result(dbh, res);
  1142 	lcr_dbf.close(dbh);
  1143 	return -1;
  1145     for (i = 0; i < RES_ROW_N(res); i++) {
  1146 	row = RES_ROWS(res) + i;
  1147 	if (VAL_NULL(ROW_VALUES(row)) == 1) {
  1148 	    prefix_len = 0;
  1149 	    prefix = 0;
  1150 	} else {
  1151 	    prefix = (char *)VAL_STRING(ROW_VALUES(row));
  1152 	    prefix_len = strlen(prefix);
  1153 	    if (prefix_len > MAX_PREFIX_LEN) {
  1154 		LM_ERR("Too long lcr prefix <%u>\n", prefix_len);
  1155 		lcr_dbf.free_result(dbh, res);
  1156 		lcr_dbf.close(dbh);
  1157 		return -1;
  1160 	if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
  1161 	    from_uri_len = 0;
  1162 	    from_uri = 0;
  1163 	} else {
  1164 	    from_uri = (char *)VAL_STRING(ROW_VALUES(row) + 1);
  1165 	    from_uri_len = strlen(from_uri);
  1166 	    if (from_uri_len > MAX_FROM_URI_LEN) {
  1167 		LM_ERR("Too long from_uri <%u>\n", from_uri_len);
  1168 		lcr_dbf.free_result(dbh, res);
  1169 		lcr_dbf.close(dbh);
  1170 		return -1;
  1173 	if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {
  1174 	    LM_ERR("Route grp_id is NULL\n");
  1175 	    lcr_dbf.free_result(dbh, res);
  1176 	    lcr_dbf.close(dbh);
  1177 	    return -1;
  1179 	grp_id = (unsigned int)VAL_INT(ROW_VALUES(row) + 2);
  1180 	if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {
  1181 	    LM_ERR("Route priority is NULL\n");
  1182 	    lcr_dbf.free_result(dbh, res);
  1183 	    lcr_dbf.close(dbh);
  1184 	    return -1;
  1186 	priority = (unsigned int)VAL_INT(ROW_VALUES(row) + 3);
  1188 	if (*lcrs == lcrs_1) {
  1189 	    lcrs_2[i].prefix_len = prefix_len;
  1190 	    if (prefix_len)
  1191 		memcpy(&(lcrs_2[i].prefix[0]), prefix, prefix_len);
  1192 	    lcrs_2[i].from_uri_len = from_uri_len;
  1193 	    if (from_uri_len) {
  1194 		memcpy(&(lcrs_2[i].from_uri[0]), from_uri, from_uri_len);
  1195 		lcrs_2[i].from_uri[from_uri_len] = '\0';
  1197 	    lcrs_2[i].grp_id = grp_id;
  1198 	    lcrs_2[i].priority = priority;
  1199 	    lcrs_2[i].end_record = 0;
  1200 	} else {
  1201 	    lcrs_1[i].prefix_len = prefix_len;
  1202 	    if (prefix_len)
  1203 		memcpy(&(lcrs_1[i].prefix[0]), prefix, prefix_len);
  1204 	    lcrs_1[i].from_uri_len = from_uri_len;
  1205 	    if (from_uri_len) {
  1206 		memcpy(&(lcrs_1[i].from_uri[0]), from_uri, from_uri_len);
  1207 		lcrs_1[i].from_uri[from_uri_len] = '\0';
  1209 	    lcrs_1[i].grp_id = grp_id;
  1210 	    lcrs_1[i].priority = priority;
  1211 	    lcrs_1[i].end_record = 0;
  1215     lcr_dbf.free_result(dbh, res);
  1216     lcr_dbf.close(dbh);
  1218     if (*lcrs == lcrs_1) {
  1219 	lcrs_2[i].end_record = 1;
  1220 	*lcrs = lcrs_2;
  1221     } else {
  1222 	lcrs_1[i].end_record = 1;
  1223 	*lcrs = lcrs_1;
  1226     (*lcrs_ws_reload_counter)++;
  1227     if (0 != load_all_regex()) {
  1229 	return -1;
  1232     return 1;
  1236 int mi_print_gws(struct mi_node* rpl)
  1238     unsigned int i;
  1239     struct mi_attr* attr;
  1240     uri_transport transport;
  1241     char *transp;
  1242     struct mi_node* node;
  1243     struct ip_addr address;
  1244     char* p;
  1245     int len;
  1247     for (i = 0; i < MAX_NO_OF_GWS; i++) {
  1249 	if ((*gws)[i].ip_addr == 0) 
  1250 	    break;
  1252 	node= add_mi_node_child(rpl,0 ,"GW", 2, 0, 0);
  1253 	if(node == NULL)
  1254 	    return -1;
  1256 	p = int2str((unsigned long)(*gws)[i].grp_id, &len );
  1257 	attr = add_mi_attr(node, MI_DUP_VALUE, "GRP_ID", 6, p, len );
  1258 	if(attr == NULL)
  1259 	    return -1;
  1261 	transport = (*gws)[i].transport;
  1262 	if (transport == PROTO_UDP)
  1263 	    transp= ";transport=udp";
  1264 	else  if (transport == PROTO_TCP)
  1265 	    transp= ";transport=tcp";
  1266 	else  if (transport == PROTO_TLS)
  1267 	    transp= ";transport=tls";
  1268 	else
  1269 	    transp= "";
  1271 	address.af = AF_INET;
  1272 	address.len = 4;
  1273 	address.u.addr32[0] = (*gws)[i].ip_addr;
  1274 	attr= addf_mi_attr(node,0 ,"URI", 3,"%s:%s:%d%s",
  1275 			   ((*gws)[i].scheme == SIP_URI_T)?"sip":"sips",
  1276 			   ip_addr2a(&address),
  1277 			   ((*gws)[i].port == 0)?5060:(*gws)[i].port,transp);
  1278 	if(attr == NULL)
  1279 	    return -1;
  1281 	p = int2str((unsigned long)(*gws)[i].strip, &len );
  1282 	attr = add_mi_attr(node, MI_DUP_VALUE, "STRIP", 5, p, len);
  1283 	if(attr == NULL)
  1284 	    return -1;
  1286 	attr = add_mi_attr(node, MI_DUP_VALUE, "TAG", 3,
  1287 			   (*gws)[i].tag, (*gws)[i].tag_len );
  1288 	if(attr == NULL)
  1289 	    return -1;
  1291 	p = int2str((unsigned long)(*gws)[i].flags, &len );
  1292 	attr = add_mi_attr(node, MI_DUP_VALUE, "FLAGS", 5, p, len);
  1293 	if(attr == NULL)
  1294 	    return -1;
  1296 	attr = add_mi_attr(node, MI_DUP_VALUE, "USER", 6,
  1297 			   (*gws)[i].user, (*gws)[i].user_len );
  1298 	if(attr == NULL)
  1299 	    return -1;
  1301 	attr = add_mi_attr(node, MI_DUP_VALUE, "REALM", 6,
  1302 			   (*gws)[i].realm, (*gws)[i].realm_len );
  1303 	if(attr == NULL)
  1304 	    return -1;
  1306 	attr = add_mi_attr(node, MI_DUP_VALUE, "PASSWD", 6,
  1307 			   (*gws)[i].passwd, (*gws)[i].passwd_len );
  1308 	if(attr == NULL)
  1309 	    return -1;
  1312     for (i = 0; i < MAX_NO_OF_LCRS; i++) {
  1313 	if ((*lcrs)[i].end_record != 0)
  1314 	    break;
  1316 	node= add_mi_node_child(rpl, 0, "RULE", 4, 0, 0);
  1317 	attr = add_mi_attr(node, 0, "PREFIX", 6, (*lcrs)[i].prefix,
  1318 			   (*lcrs)[i].prefix_len );
  1319 	if(attr== 0)
  1320 	    return -1;
  1322 	attr = add_mi_attr(node, 0, "FROM_URI", 8, (*lcrs)[i].from_uri,
  1323 			   (*lcrs)[i].from_uri_len );
  1324 	if(attr== 0)
  1325 	    return -1;
  1327 	p = int2str((unsigned long)(*lcrs)[i].grp_id, &len );
  1328 	attr = add_mi_attr(node, MI_DUP_VALUE, "GRP_ID", 6, p, len );
  1329 	if(attr == NULL)
  1330 	    return -1;
  1332 	p = int2str((unsigned long)(*lcrs)[i].priority, &len );
  1333 	attr = add_mi_attr(node, MI_DUP_VALUE, "PRIORITY", 8, p, len );
  1334 	if(attr == NULL)
  1335 	    return -1;
  1339     return 0;
  1343 /*
  1344  * Load info of matching GWs from database to gw_uri AVPs
  1345  */
  1346 static int do_load_gws(struct sip_msg* _m, str *_from_uri, int _grp_id)
  1348     str ruri_user, from_uri, value;
  1349     char from_uri_str[MAX_FROM_URI_LEN + 1];
  1350     char ruri[MAX_URI_SIZE];
  1351     unsigned int i, j, k, index, addr, port, strip, gw_index,
  1352 	duplicated_gw, flags, have_rpid_avp;
  1353     char *user;
  1354     char *realm;
  1355     char *passwd;
  1356     uri_type scheme;
  1357     uri_transport transport;
  1358     struct ip_addr address;
  1359     str addr_str, port_str;
  1360     char *at, *tag, *strip_string, *flags_string;
  1361     struct usr_avp *avp;
  1362     int_str val;
  1363     struct mi matched_gws[MAX_NO_OF_GWS + 1];
  1364     unsigned short tag_len, prefix_len, priority;
  1365     int randomizer_start, randomizer_end, randomizer_flag,
  1366 	strip_len, flags_len;
  1367     struct lcr_info lcr_rec;
  1369 	/* Find Request-URI user */
  1370 	if ((parse_sip_msg_uri(_m) < 0) || (!_m->parsed_uri.user.s)) {
  1371 		LM_ERR("Error while parsing R-URI\n");
  1372 		return -1;
  1374 	ruri_user = _m->parsed_uri.user;
  1376     if (_from_uri) {
  1377 	/* take caller uri from _from_uri argument */
  1378 	from_uri = *_from_uri;
  1379     } else {
  1380 	/* take caller uri from RPID or From URI */
  1381 	have_rpid_avp = 0;
  1382 	avp = search_first_avp(rpid_avp_type, rpid_avp, &val, 0);
  1383 	if (avp != NULL) {
  1384 	    /* Get URI user from RPID if not empty */
  1385 	    if (avp->flags & AVP_VAL_STR) {
  1386 		if (val.s.s && val.s.len) {
  1387 		    from_uri = val.s;
  1388 		    have_rpid_avp = 1;
  1390 	    } else {
  1391 		from_uri.s = int2str(val.n, &from_uri.len);
  1392 		have_rpid_avp = 1;
  1395 	if (!have_rpid_avp) {
  1396 	    /* Get URI from From URI */
  1397 	    if ((!_m->from) && (parse_headers(_m, HDR_FROM_F, 0) == -1)) {
  1398 		LM_ERR("Error while parsing headers\n");
  1399 		return -1;
  1401 	    if (!_m->from) {
  1402 		LM_ERR("From header field not found\n");
  1403 		return -1;
  1405 	    if ((!(_m->from)->parsed) && (parse_from_header(_m) < 0)) {
  1406 		LM_ERR("Error while parsing From header\n");
  1407 		return -1;
  1409 	    from_uri = get_from(_m)->uri;
  1412     if (from_uri.len <= MAX_FROM_URI_LEN) {
  1413 	strncpy(from_uri_str, from_uri.s, from_uri.len);
  1414 	from_uri_str[from_uri.len] = '\0';
  1415     } else {
  1416 	LM_ERR("From URI is too long <%u>\n", from_uri.len);
  1417 	return -1;
  1420     /*
  1421      * Check if the gws and lcrs were reloaded
  1422      */
  1423 	if (reload_counter != *lcrs_ws_reload_counter) {
  1424 		if (load_all_regex() != 0) {
  1425 		    return -1;
  1429     /*
  1430      * Let's match the gws:
  1431      *  1. prefix matching
  1432      *  2. from_uri matching
  1433      *  3. _grp_id matching
  1435      * Note: A gateway must be in the list _only_ once.
  1436      */
  1437     gw_index = 0;
  1438     duplicated_gw = 0;
  1439     for (i = 0; i < MAX_NO_OF_LCRS; i++) {
  1440 	lcr_rec = (*lcrs)[i];
  1441 	if (lcr_rec.end_record != 0) {
  1442 	    break;
  1444 	if ( ((prefix_mode_param == 0) && (lcr_rec.prefix_len <= ruri_user.len) &&
  1445 	      (strncmp(lcr_rec.prefix, ruri_user.s, lcr_rec.prefix_len)==0)) ||
  1446 	     ( (prefix_mode_param != 0) && ( (lcr_rec.prefix_len == 0) ||
  1447 					(prefix_reg[i].valid &&
  1448 					 (regexec(&(prefix_reg[i].re), ruri_user.s, 0,
  1449 						  (regmatch_t *)NULL, 0) == 0)) ) ) ) {
  1450 	    /* 1. Prefix matching is done */
  1451 	    if ((lcr_rec.from_uri_len == 0) ||
  1452 		(from_uri_reg[i].valid &&
  1453 		 (regexec(&(from_uri_reg[i].re), from_uri_str, 0,
  1454 			  (regmatch_t *)NULL, 0) == 0))) {
  1455 		/* 2. from_uri matching is done */
  1456 		for (j = 0; j < MAX_NO_OF_GWS; j++) {
  1457 		    if ((*gws)[j].ip_addr == 0) {
  1458 			break;
  1460 		    if (lcr_rec.grp_id == (*gws)[j].grp_id &&
  1461 			(_grp_id < 0 || (*gws)[j].grp_id == _grp_id)) {
  1462 			/* 3. _grp_id matching is done */
  1463 			for (k = 0; k < gw_index; k++) {
  1464 			    if ((*gws)[j].ip_addr ==
  1465 				(*gws)[matched_gws[k].gw_index].ip_addr) {
  1466 				/* Found the same gw in the list  */
  1467 				/* Let's keep the one with higher */
  1468 				/* match on prefix len            */
  1469 				LM_DBG("Duplicate gw for index"
  1470 				       " %d [%d,%d] and current [%d,%d] \n",
  1471 				       k, matched_gws[k].route_index,
  1472 				       matched_gws[k].route_index, i, j);
  1473 				duplicated_gw = 1;
  1474 				if (lcr_rec.prefix_len >
  1475 				    (*lcrs)[matched_gws[k].route_index].prefix_len) {
  1476 				    /* Replace the old entry with the new one */
  1477 				    LM_DBG("Replace [%d,%d]"
  1478 					   " with [%d,%d] on index %d:"
  1479 					   " prefix reason %d>%d\n",
  1480 					   matched_gws[k].route_index,
  1481 					   matched_gws[k].gw_index, i, j, k,
  1482 					   lcr_rec.prefix_len,
  1483 					   (*lcrs)[matched_gws[k].route_index].prefix_len);
  1484 				    matched_gws[k].route_index = i;
  1485 				    matched_gws[k].gw_index = j;
  1486 				    /* Stop searching in the matched_gws list */
  1487 				    break;
  1488 				} else if (lcr_rec.prefix_len ==
  1489 					   (*lcrs)[matched_gws[k].route_index].prefix_len) {
  1490 				    if (lcr_rec.priority >
  1491 					(*lcrs)[matched_gws[k].route_index].priority) {
  1492 					/* Replace the old entry with the new one */
  1493 					LM_DBG("Replace [%d,%d] with"
  1494 					       " [%d,%d] on index %d:"
  1495 					       " priority reason %d>%d\n",
  1496 					       matched_gws[k].route_index,
  1497 					       matched_gws[k].gw_index,
  1498 					       i, j, k, lcr_rec.priority,
  1499 					       (*lcrs)[matched_gws[k].route_index].priority);
  1500 					matched_gws[k].route_index = i;
  1501 					matched_gws[k].gw_index = j;
  1502 					/* Stop searching in the matched_gws list */
  1503 					break;
  1508 			if (duplicated_gw == 0) {
  1509 			    /* This is a new gw */
  1510 			    matched_gws[gw_index].route_index = i;
  1511 			    matched_gws[gw_index].gw_index = j;
  1512 			    LM_DBG("Added matched_gws[%d]=[%d,%d]\n",
  1513 				   gw_index, i, j);
  1514 			    gw_index++;
  1515 			} else {
  1516 			    duplicated_gw = 0;
  1523     matched_gws[gw_index].route_index = -1;
  1524     matched_gws[gw_index].gw_index = -1;
  1526     /*
  1527      * Sort the gateways based on:
  1528      *  1. prefix len
  1529      *  2. priority
  1530      */
  1531     qsort(matched_gws, gw_index, sizeof(struct mi), comp_lcrs);
  1532 	randomizer_start = 0;
  1534     /* Randomizing the gateways with same prefix_len and same priority */
  1535     randomizer_flag = 0;
  1536     prefix_len = (*lcrs)[matched_gws[0].route_index].prefix_len;
  1537     priority = (*lcrs)[matched_gws[0].route_index].priority;
  1538     for (i = 1; i < gw_index; i++) {
  1539  	if ( prefix_len == (*lcrs)[matched_gws[i].route_index].prefix_len &&
  1540  	     priority == (*lcrs)[matched_gws[i].route_index].priority) {
  1541 	    /* we have a match */
  1542 	    if (randomizer_flag == 0) {
  1543 		randomizer_flag = 1;
  1544 		randomizer_start = i - 1;
  1546 	    matched_gws[i - 1].randomizer = rand();
  1548 	else {
  1549 	    if (randomizer_flag == 1) {
  1550 		randomizer_end = i - 1;
  1551 		randomizer_flag = 0;
  1552 		qsort(&matched_gws[randomizer_start],
  1553 		      randomizer_end - randomizer_start + 1,
  1554 		      sizeof(struct mi), rand_lcrs);
  1556 	    prefix_len = (*lcrs)[matched_gws[i].route_index].prefix_len;
  1557 	    priority = (*lcrs)[matched_gws[i].route_index].priority;
  1560     if (randomizer_flag == 1) {
  1561 	randomizer_end = gw_index - 1;
  1562 	matched_gws[i - 1].randomizer = rand();
  1563 	qsort(&matched_gws[randomizer_start],
  1564 	      randomizer_end - randomizer_start + 1,
  1565 	      sizeof(struct mi), rand_lcrs);
  1568     for (i = 0; i < MAX_NO_OF_GWS; i++) {
  1569 	index = matched_gws[i].gw_index;
  1570 	if (index == -1) {
  1571 	    break;
  1573       	addr = (*gws)[index].ip_addr;
  1574 	port = (*gws)[index].port;
  1575 	scheme = (*gws)[index].scheme;
  1576 	transport = (*gws)[index].transport;
  1577 	flags = (*gws)[index].flags;
  1578 	strip = (*gws)[index].strip;
  1579 	user = (*gws)[index].user;
  1580 	realm = (*gws)[index].realm;
  1581 	passwd = (*gws)[index].passwd;
  1582 	if (strip > ruri_user.len) {
  1583 	    LM_ERR("Strip count of gw is too large <%u>\n", strip);
  1584 	    goto skip;
  1586 	tag_len = (*gws)[index].tag_len;
  1587 	tag = (*gws)[index].tag;
  1588 	if (6 + tag_len + 40 /* flags + strip */ + 1 + 15 + 1 + 5 + 1 + 14 >
  1589 	    MAX_URI_SIZE) {
  1590 	    LM_ERR("Request URI would be too long\n");
  1591 	    goto skip;
  1593 	at = (char *)&(ruri[0]);
  1594 	flags_string = int2str(flags, &flags_len);
  1595 	memcpy(at, flags_string, flags_len);
  1596 	at = at + flags_len;
  1597 	if (scheme == SIP_URI_T) {
  1598 	    memcpy(at, "sip:", 4); at = at + 4;
  1599 	} else if (scheme == SIPS_URI_T) {
  1600 	    memcpy(at, "sips:", 5); at = at + 5;
  1601 	} else {
  1602 	    LM_ERR("Unknown or unsupported URI scheme <%u>\n",
  1603 		   (unsigned int)scheme);
  1604 	    goto skip;
  1606 	if (tag_len) {
  1607 	    memcpy(at, tag, tag_len); at = at + tag_len;
  1609 	/* Add strip in this form |number.
  1610 	 * For example: |3 means strip first 3 characters.
  1611          */
  1612 	*at = '|'; at = at + 1;
  1613 	strip_string = int2str(strip, &strip_len);
  1614 	memcpy(at, strip_string, strip_len);
  1615 	at = at + strip_len;
  1616 	*at = '@'; at = at + 1;
  1617 	address.af = AF_INET;
  1618 	address.len = 4;
  1619 	address.u.addr32[0] = addr;
  1620 	addr_str.s = ip_addr2a(&address);
  1621 	addr_str.len = strlen(addr_str.s);
  1622 	memcpy(at, addr_str.s, addr_str.len); at = at + addr_str.len;
  1623 	if (port != 0) {
  1624 	    if (port > 65536) {
  1625 		LM_ERR("Port of GW is too large <%u>\n", port);
  1626 		goto skip;
  1628 	    *at = ':'; at = at + 1;
  1629 	    port_str.s = int2str(port, &port_str.len);
  1630 	    memcpy(at, port_str.s, port_str.len); at = at + port_str.len;
  1632 	if (transport != PROTO_NONE) {
  1633 	    memcpy(at, ";transport=", 11); at = at + 11;
  1634 	    if (transport == PROTO_UDP) {
  1635 		memcpy(at, "udp", 3); at = at + 3;
  1636 	    } else if (transport == PROTO_TCP) {
  1637 		memcpy(at, "tcp", 3); at = at + 3;
  1638 	    } else if (transport == PROTO_TLS) {
  1639 		memcpy(at, "tls", 3); at = at + 3;
  1640 	    } else {
  1641 		LM_ERR("Unknown or unsupported transport <%u>\n",
  1642 		       (unsigned int)transport);
  1643 		goto skip;
  1646 	value.s = (char *)&(ruri[0]);
  1647 	value.len = at - value.s;
  1648 	val.s = value;
  1649 	add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val);
  1650 	LM_DBG("Added gw_uri_avp <%.*s>\n", value.len, value.s);
  1652 	value.s = user;
  1653 	value.len = strlen(value.s);
  1654 	val.s = value;
  1655 	add_avp(user_avp_type|AVP_VAL_STR, user_avp, val);
  1656 	LM_DBG("Added user_avp <%.*s>\n", value.len, value.s);
  1658 	value.s = realm;
  1659 	value.len = strlen(value.s);
  1660 	val.s = value;
  1661 	add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, val);
  1662 	LM_DBG("Added realm_avp <%.*s>\n", value.len, value.s);
  1664 	value.s = passwd;
  1665 	value.len = strlen(value.s);
  1666 	val.s = value;
  1667 	add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, val);
  1668 	LM_DBG("Added passwd_avp <%.*s>\n", value.len, value.s);
  1670     skip:
  1671 	continue;
  1674     return 1;
  1677 /*
  1678  * Load info of matching GWs from database to gw_uri AVPs
  1679  * taking into account the given group id.  Caller URI is taken
  1680  * from request.
  1681  */
  1682 static int load_gws_from_grp(struct sip_msg* _m, char* _s1, char* _s2)
  1684 	str grp_s;
  1685 	unsigned int grp_id;
  1687 	if(((pv_elem_p)_s1)->spec.getf!=NULL)
  1689 		if(pv_printf_s(_m, (pv_elem_p)_s1, &grp_s)!=0)
  1690 			return -1;
  1691 		if(str2int(&grp_s, &grp_id)!=0)
  1692 			return -1;
  1693 	} else {
  1694 		grp_id = ((pv_elem_p)_s1)->spec.pvp.pvn.u.isname.name.n;
  1696 	if (grp_id > 0) return do_load_gws(_m, (str *)0, (int)grp_id);
  1697 	else return -1;
  1701 /*
  1702  * Load info of matching GWs from database to gw_uri AVPs.
  1703  * Caller URI is taken from request.
  1704  */
  1705 static int load_gws_0(struct sip_msg* _m, char* _s1, char* _s2)
  1707     return do_load_gws(_m, (str *)0, -1);
  1711 /*
  1712  * Load info of matching GWs from database to gw_uri AVPs.
  1713  * Caller URI is taken from pseudo variable argument.
  1714  */
  1715 static int load_gws_1(struct sip_msg* _m, char* _sp, char* _s2)
  1717     pv_spec_t *sp;
  1718     pv_value_t pv_val;
  1719     sp = (pv_spec_t *)_sp;
  1721     if (sp && (pv_get_spec_value(_m, sp, &pv_val) == 0)) {
  1722 	if (pv_val.flags & PV_VAL_STR) {
  1723 	    if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
  1724 		LM_DBG("missing from uri\n");
  1725 		return -1;
  1727  	    return do_load_gws(_m, &(pv_val.rs), -1);
  1728 	} else {
  1729 	   LM_DBG("pseudo variable value is not string\n");
  1730 	   return -1;
  1732     } else {
  1733 	LM_DBG("cannot get pseudo variable value\n");
  1734 	return -1;
  1739 /*
  1740  * Rewrites scheme, host, port, and transport parts of R-URI based on first 
  1741  * gw_uri AVP value, which is then destroyed.  Also saves R-URI user to 
  1742  * ruri_user AVP for later use in failure route block.
  1743  * If called from failure route block, appends a new branch to request
  1744  * where scheme, host, port, and transport of URI are taken from the first
  1745  * gw_uri AVP value, which is then destroyed.  URI user is taken from
  1746  * ruri_user AVP value saved earlier.
  1747  * Returns 1 upon success and -1 upon failure.
  1748  */
  1749 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2)
  1751     int_str gw_uri_val, ruri_user_val, val;
  1752     int_str user_val, realm_val, passwd_val;
  1753     struct usr_avp *gu_avp, *ru_avp, *usr_avp, *rlm_avp, *pwd_avp;
  1754     int rval;
  1755     str new_ruri;
  1756     char *at, *at_char, *strip_char, *endptr;
  1757     unsigned int strip;
  1759     gu_avp = search_first_avp(gw_uri_avp_type, gw_uri_avp, &gw_uri_val, 0);
  1760     if (!gu_avp) return -1;
  1762     /* Set flags_avp from integer at the beginning of of gw_uri */
  1763     val.n = (int)strtoul(gw_uri_val.s.s, &at, 0);
  1764     add_avp(flags_avp_type, flags_avp, val);
  1765     LM_DBG("Added flags_avp <%u>\n", (unsigned int)val.n);
  1767     gw_uri_val.s.len = gw_uri_val.s.len - (at - gw_uri_val.s.s);
  1768     gw_uri_val.s.s = at;
  1770 	/* Save gateway AVPs for use in script */
  1771 	usr_avp = search_first_avp(user_avp_type, user_avp, &user_val, 0);
  1772 	rlm_avp = search_first_avp(realm_avp_type, realm_avp, &realm_val, 0);
  1773 	pwd_avp = search_first_avp(passwd_avp_type, passwd_avp, &passwd_val, 0);
  1774 	if (!usr_avp) {
  1775 		LM_DBG("User AVP no set\n");
  1776 		return -1;
  1778 	else {
  1779 		add_avp(user_avp_type|AVP_VAL_STR, user_avp, user_val);
  1780 		LM_DBG("Added user_avp <%.*s>\n", user_val.s.len, user_val.s.s);
  1782 	if (!rlm_avp) {
  1783 		LM_DBG("Realm AVP no set\n");
  1784 		return -1;
  1786 	else {
  1787 		add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, realm_val);
  1788 		LM_DBG("Added realm_avp <%.*s>\n", realm_val.s.len, realm_val.s.s);
  1790 	if (!pwd_avp) {
  1791 		LM_DBG("Passwd AVP no set\n");
  1792 		return -1;
  1794 	else {
  1795 		add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, passwd_val);
  1796 		LM_DBG("Added passwd_avp <%.*s>\n", passwd_val.s.len, passwd_val.s.s);
  1799 	/* Create new Request-URI taking URI user from ruri_user AVP
  1800 	   and other parts of from gateway URI AVP. */
  1801 	ru_avp = search_first_avp(ruri_user_avp_type, ruri_user_avp,
  1802 		&ruri_user_val, 0);
  1803 	if (!ru_avp) {
  1804 		LM_DBG("ruri_user AVP no yet set -> use RURI\n");
  1805 		/* parse RURI and ger username */
  1806 		if (parse_sip_msg_uri(_m) < 0) {
  1807 			LM_ERR("Parsing of R-URI failed\n");
  1808 			return -1;
  1810 		ruri_user_val.s = _m->parsed_uri.user;
  1811 		/* Save Request-URI user for use in FAILURE_ROUTE */
  1812 		val.s = _m->parsed_uri.user;
  1813 		add_avp(ruri_user_avp_type|AVP_VAL_STR, ruri_user_avp, val);
  1814 		LM_DBG("Added ruri_user_avp <%.*s>\n", val.s.len, val.s.s);
  1817 	new_ruri.s = pkg_malloc(gw_uri_val.s.len + ruri_user_val.s.len);
  1818 	if (!new_ruri.s) {
  1819 	    LM_ERR("No memory for new R-URI.\n");
  1820 	    return -1;
  1822 	at_char = memchr(gw_uri_val.s.s, '@', gw_uri_val.s.len);
  1823 	if (!at_char) {
  1824 	    pkg_free(new_ruri.s);
  1825 	    LM_ERR("No @ in gateway URI <%.*s>\n",
  1826 		   gw_uri_val.s.len, gw_uri_val.s.s);
  1827 	    return -1;
  1829 	strip_char = memchr(gw_uri_val.s.s, '|', gw_uri_val.s.len);
  1830 	if (!strip_char || strip_char + 1 >= at_char) {
  1831 	    pkg_free(new_ruri.s);
  1832 	    LM_ERR("No strip char | and at least one "
  1833 		   "char before @ in gateway URI <%.*s>\n",
  1834 		   gw_uri_val.s.len, gw_uri_val.s.s);
  1835 	    return -1;
  1837 	at = new_ruri.s;
  1838 	memcpy(at, gw_uri_val.s.s, strip_char - gw_uri_val.s.s);
  1839 	at = at + (strip_char - gw_uri_val.s.s);
  1840 	strip = strtol(strip_char + 1, &endptr, 10);
  1841 	if (endptr != at_char) {
  1842 	    pkg_free(new_ruri.s);
  1843 	    LM_ERR("Non-digit char between | and @ chars in gw URI <%.*s>\n",
  1844 		   gw_uri_val.s.len, gw_uri_val.s.s);
  1845 	    return -1;
  1847 	if (ruri_user_val.s.len - strip > 0) {
  1848 	    memcpy(at, ruri_user_val.s.s + strip,
  1849 		   ruri_user_val.s.len - strip);
  1850 	    at = at + ruri_user_val.s.len - strip;
  1852 	if (*(at - 1) != ':') {
  1853 	    memcpy(at, at_char, gw_uri_val.s.len - (at_char - gw_uri_val.s.s));
  1854 	    at = at + gw_uri_val.s.len - (at_char - gw_uri_val.s.s);
  1855 	} else {
  1856 	    memcpy(at, at_char + 1, gw_uri_val.s.len -
  1857 		   (at_char + 1 - gw_uri_val.s.s));
  1858 	    at = at + gw_uri_val.s.len - (at_char + 1 - gw_uri_val.s.s);
  1860 	new_ruri.len = at - new_ruri.s;
  1862 	/* set new RURI */
  1863 	rval = set_ruri( _m, &new_ruri);
  1864 	pkg_free(new_ruri.s);
  1865 	destroy_avp(gu_avp);
  1866 	if (rval!=0) {
  1867 		LM_ERR("failed to set new RURI\n");
  1868 		return -1;
  1871 	return 1;
  1875 /*
  1876  * Checks if request comes from a gateway
  1877  */
  1878 static int do_from_gw(struct sip_msg* _m, pv_spec_t *addr_sp, int grp_id)
  1880     int i;
  1881     unsigned int src_addr;
  1882     pv_value_t pv_val;
  1883     struct ip_addr *ip;
  1884     int_str val;
  1886 	if (addr_sp && (pv_get_spec_value(_m, addr_sp, &pv_val) == 0)) {
  1887 		if (pv_val.flags & PV_VAL_INT) {
  1888 			src_addr = pv_val.ri;
  1889 		} else if (pv_val.flags & PV_VAL_STR) {
  1890 			if ( (ip=str2ip( &pv_val.rs)) == NULL) {
  1891 				LM_ERR("failed to convert IP address string to in_addr\n");
  1892 				return -1;
  1893 			} else {
  1894 				src_addr = ip->u.addr32[0];
  1896 		} else {
  1897 			LM_ERR("IP address PV empty value\n");
  1898 			return -1;
  1900 	} else {
  1901 		src_addr = _m->rcv.src_ip.u.addr32[0];
  1904     for (i = 0; i < MAX_NO_OF_GWS; i++) {
  1905 	if ((*gws)[i].ip_addr == 0) {
  1906 	    return -1;
  1908 	if ((*gws)[i].ip_addr == src_addr && 
  1909 	    (grp_id < 0 || (*gws)[i].grp_id == grp_id)) {
  1910 	    LM_DBG("Request came from gw\n");
  1911 	    val.n = (int)(*gws)[i].flags;
  1912 	    add_avp(flags_avp_type, flags_avp, val);
  1913 	    LM_DBG("Added flags_avp <%u>\n", (unsigned int)val.n);
  1914 	    return 1;
  1918     LM_DBG("Request did not come from gw\n");
  1919     return -1;
  1923 /*
  1924  * Checks if request comes from a gateway, taking source address from request
  1925  * and taking into account the group id.
  1926  */
  1927 static int from_gw_grp(struct sip_msg* _m, char* _grp_id, char* _s2)
  1929     return do_from_gw(_m, (pv_spec_t *)0, (int)(long)_grp_id);
  1933 /*
  1934  * Checks if request comes from a gateway, taking src_address from request
  1935  * and ignoring group id.
  1936  */
  1937 static int from_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
  1939     return do_from_gw(_m, (pv_spec_t *)0, -1);
  1943 /*
  1944  * Checks if request comes from a gateway, taking source address from pw
  1945  * and ignoring group id.
  1946  */
  1947 static int from_gw_1(struct sip_msg* _m, char* _addr_sp, char* _s2)
  1949     return do_from_gw(_m, (pv_spec_t *)_addr_sp, -1);
  1953 /*
  1954  * Checks if in-dialog request goes to gateway
  1955  */
  1956 static int do_to_gw(struct sip_msg* _m, int grp_id)
  1958     char host[16];
  1959     struct in_addr addr;
  1960     unsigned int i;
  1962     if((_m->parsed_uri_ok == 0) && (parse_sip_msg_uri(_m) < 0)) {
  1963 	LM_ERR("Error while parsing the R-URI\n");
  1964 	return -1;
  1967     if (_m->parsed_uri.host.len > 15) {
  1968 	return -1;
  1970     memcpy(host, _m->parsed_uri.host.s, _m->parsed_uri.host.len);
  1971     host[_m->parsed_uri.host.len] = 0;
  1973     if (!inet_aton(host, &addr)) {
  1974 	return -1;
  1977     for (i = 0; i < MAX_NO_OF_GWS; i++) {
  1978 	if ((*gws)[i].ip_addr == 0) {
  1979 	    return -1;
  1981 	if ((*gws)[i].ip_addr == addr.s_addr && 
  1982 		(grp_id < 0 || (*gws)[i].grp_id == grp_id)) {
  1983 	    return 1;
  1987     return -1;
  1991 /*
  1992  * Checks if in-dialog request goes to gateway, taking
  1993  * into account the group id.
  1994  */
  1995 static int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2)
  1997     int grp_id;
  1999     grp_id = (int)(long)_s1;
  2000     return do_to_gw(_m, grp_id);
  2004 /*
  2005  * Checks if in-dialog request goes to gateway, ignoring
  2006  * the group id.
  2007  */
  2008 static int to_gw(struct sip_msg* _m, char* _s1, char* _s2)
  2010     return do_to_gw(_m, -1);
  2014 /* 
  2015  * Frees contact list used by load_contacts function
  2016  */
  2017 static inline void free_contact_list(struct contact *curr) {
  2018     struct contact *prev;
  2019     while (curr) {
  2020 	prev = curr;
  2021 	curr = curr->next;
  2022 	pkg_free(prev);
  2026 /* Encode branch info from contact struct to str */
  2027 static inline int encode_branch_info(str *info, struct contact *con)
  2029     char *at, *s;
  2030     int len;
  2032     info->len = con->uri.len + con->dst_uri.len +
  2033 	con->path.len + MAX_SOCKET_STR + INT2STR_MAX_LEN + 5;
  2034     info->s = pkg_malloc(info->len);
  2035     if (!info->s) {
  2036 	LM_ERR("No memory left for branch info\n");
  2037 	return 0;
  2039     at = info->s;
  2040     memcpy(at, con->uri.s, con->uri.len);
  2041     at = at + con->uri.len;
  2042     *at = '\n';
  2043     at++;
  2044     memcpy(at, con->dst_uri.s, con->dst_uri.len);
  2045     at = at + con->dst_uri.len;
  2046     *at = '\n';
  2047     at++;
  2048     memcpy(at, con->path.s, con->path.len);
  2049     at = at + con->path.len;
  2050     *at = '\n';
  2051     at++;
  2052     if (con->sock) {
  2053 	len = MAX_SOCKET_STR;
  2054 	if (!socket2str(con->sock, at, &len, 1)) {
  2055 	    LM_ERR("Failed to convert socket to str\n");
  2056 	    return 0;
  2058     } else {
  2059 	len = 0;
  2061     at = at + len;
  2062     *at = '\n';
  2063     at++;
  2064     s = int2str(con->flags, &len);
  2065     memcpy(at, s, len);
  2066     at = at + len;
  2067     *at = '\n';
  2068     info->len = at - info->s + 1;
  2070     return 1;
  2074 /* Encode branch info from str */
  2075 static inline int decode_branch_info(char *info, str *uri, str *dst, str *path,
  2076 			      struct socket_info **sock, unsigned int *flags)
  2078     str s, host;
  2079     int port, proto;
  2080     char *pos, *at;
  2082     pos = strchr(info, '\n');
  2083     uri->len = pos - info;
  2084     if (uri->len) {
  2085 	uri->s = info;
  2086     } else {
  2087 	uri->s = 0;
  2089     at = pos + 1;
  2091     pos = strchr(at, '\n');
  2092     dst->len = pos - at;
  2093     if (dst->len) {
  2094 	dst->s = at;
  2095     } else {
  2096 	dst->s = 0;
  2098     at = pos + 1;
  2100     pos = strchr(at, '\n');
  2101     path->len = pos - at;
  2102     if (path->len) {
  2103 	path->s = at;
  2104     } else {
  2105 	path->s = 0;
  2107     at = pos + 1;
  2109     pos = strchr(at, '\n');
  2110     s.len = pos - at;
  2111     if (s.len) {
  2112 	s.s = at;
  2113 	if (parse_phostport(s.s, s.len, &host.s, &host.len,
  2114 			    &port, &proto) != 0) {
  2115 	    LM_ERR("Parsing of socket info <%.*s> failed\n",  s.len, s.s);
  2116 	    return 0;
  2118 	*sock = grep_sock_info(&host, (unsigned short)port,
  2119 			       (unsigned short)proto);
  2120 	if (*sock == 0) {
  2121 	    LM_ERR("Invalid socket <%.*s>\n", s.len, s.s);
  2122 	    return 0;
  2124     } else {
  2125 	*sock = 0;
  2127     at = pos + 1;
  2129     pos = strchr(at, '\n');
  2130     s.len = pos - at;
  2131     if (s.len) {
  2132 	s.s = at;
  2133 	if (str2int(&s, flags) != 0) {
  2134 	    LM_ERR("Failed to decode flags <%.*s>\n", s.len, s.s);
  2135 	    return 0;
  2137     } else {
  2138 	*flags = 0;
  2141     return 1;
  2145 /* 
  2146  * Loads contacts in destination set into "lcr_contact" AVP in reverse
  2147  * priority order and associated each contact with Q_FLAG telling if
  2148  * contact is the last one in its priority class.  Finally, removes
  2149  * all branches from destination set.
  2150  */
  2151 static int load_contacts(struct sip_msg* msg, char* key, char* value)
  2153     str uri, dst_uri, path, branch_info, *ruri;
  2154     qvalue_t q, ruri_q;
  2155     struct contact *contacts, *next, *prev, *curr;
  2156     int_str val;
  2157     int idx;
  2158     struct socket_info* sock;
  2159     unsigned int flags;
  2161     /* Check if anything needs to be done */
  2162     if (nr_branches == 0) {
  2163 	LM_DBG("Nothing to do - no branches!\n");
  2164 	return 1;
  2167     ruri = GET_RURI(msg);
  2168     if (!ruri) {
  2169 	LM_ERR("No Request-URI found\n");
  2170 	return -1;
  2172     ruri_q = get_ruri_q();
  2174     for(idx = 0; (uri.s = get_branch(idx, &uri.len, &q, 0, 0, 0, 0)) != 0;
  2175 	idx++) {
  2176 	if (q != ruri_q) {
  2177 	    goto rest;
  2180     LM_DBG("Nothing to do - all contacts have same q!\n");
  2181     return 1;
  2183 rest:
  2184     /* Insert Request-URI branch to contact list */
  2185     contacts = (struct contact *)pkg_malloc(sizeof(struct contact));
  2186     if (!contacts) {
  2187 	LM_ERR("No memory for contact info\n");
  2188 	return -1;
  2190     contacts->uri.s = ruri->s;
  2191     contacts->uri.len = ruri->len;
  2192     contacts->q = ruri_q;
  2193     contacts->dst_uri = msg->dst_uri;
  2194     contacts->sock = msg->force_send_socket;
  2195     contacts->flags = getb0flags();
  2196     contacts->path = msg->path_vec;
  2197     contacts->next = (struct contact *)0;
  2199     /* Insert branches to contact list in increasing q order */
  2200     for(idx = 0;
  2201 	(uri.s = get_branch(idx,&uri.len,&q,&dst_uri,&path,&flags,&sock))
  2202 	    != 0;
  2203 	idx++ ) {
  2204 	next = (struct contact *)pkg_malloc(sizeof(struct contact));
  2205 	if (!next) {
  2206 	    LM_ERR("No memory for contact info\n");
  2207 	    free_contact_list(contacts);
  2208 	    return -1;
  2210 	next->uri = uri;
  2211 	next->q = q;
  2212 	next->dst_uri = dst_uri;
  2213 	next->path = path;
  2214 	next->flags = flags;
  2215 	next->sock = sock;
  2216 	next->next = (struct contact *)0;
  2217 	prev = (struct contact *)0;
  2218 	curr = contacts;
  2219 	while (curr && (curr->q < q)) {
  2220 	    prev = curr;
  2221 	    curr = curr->next;
  2223 	if (!curr) {
  2224 	    next->next = (struct contact *)0;
  2225 	    prev->next = next;
  2226 	} else {
  2227 	    next->next = curr;
  2228 	    if (prev) {
  2229 		prev->next = next;
  2230 	    } else {
  2231 		contacts = next;
  2236     /* Assign values for q_flags */
  2237     curr = contacts;
  2238     curr->q_flag = 0;
  2239     while (curr->next) {
  2240 	if (curr->q < curr->next->q) {
  2241 	    curr->next->q_flag = Q_FLAG;
  2242 	} else {
  2243 	    curr->next->q_flag = 0;
  2245 	curr = curr->next;
  2248     /* Add contacts to "contacts" AVP */
  2249     curr = contacts;
  2250     while (curr) {
  2251 	if (encode_branch_info(&branch_info, curr) == 0) {
  2252 	    LM_ERR("Encoding of branch info failed\n");
  2253 	    free_contact_list(contacts);
  2254 	    if (branch_info.s) pkg_free(branch_info.s);
  2255 	    return -1;
  2257 	val.s = branch_info;
  2258 	add_avp(contact_avp_type|AVP_VAL_STR|(curr->q_flag),
  2259 		contact_avp, val);
  2260 	pkg_free(branch_info.s);
  2261 	LM_DBG("Loaded contact <%.*s> with q_flag <%d>\n",
  2262 	       val.s.len, val.s.s, curr->q_flag);
  2263 	curr = curr->next;
  2266     /* Clear all branches */
  2267     clear_branches();
  2269     /* Free contact list */
  2270     free_contact_list(contacts);
  2272     return 1;
  2276 /*
  2277  * Adds to request a destination set that includes all highest priority
  2278  * class contacts in "lcr_contact" AVP.   If called from a route block,
  2279  * rewrites the request uri with first contact and adds the remaining
  2280  * contacts as branches.  If called from failure route block, adds all
  2281  * contacts as branches.  Removes added contacts from "lcr_contact" AVP.
  2282  */
  2283 static int next_contacts(struct sip_msg* msg, char* key, char* value)
  2285     struct usr_avp *avp, *prev;
  2286     int_str val;
  2287     str uri, dst, path;
  2288     struct socket_info *sock;
  2289     unsigned int flags;
  2291 	/* Find first lcr_contact_avp value */
  2292 	avp = search_first_avp(contact_avp_type, contact_avp, &val, 0);
  2293 	if (!avp) {
  2294 	    LM_DBG("No AVPs -- we are done!\n");
  2295 	    return -1;
  2298 	LM_DBG("Next contact is <%s>\n", val.s.s);
  2300 	if (decode_branch_info(val.s.s, &uri, &dst, &path, &sock, &flags)== 0) {
  2301 	    LM_ERR("Decoding of branch info <%.*s> failed\n",
  2302 		   val.s.len, val.s.s);
  2303 	    destroy_avp(avp);
  2304 	    return -1;
  2307 	set_ruri(msg, &uri);
  2308 	set_dst_uri(msg, &dst);
  2309 	set_path_vector(msg, &path);
  2310 	msg->force_send_socket = sock;
  2311 	setb0flags(flags);
  2313 	if (avp->flags & Q_FLAG) {
  2314 		destroy_avp(avp);
  2315 		if (route_type == REQUEST_ROUTE) {
  2316 			/* Set fr_inv_timer */
  2317 			val.n = fr_inv_timer_next;
  2318 			if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val) != 0) {
  2319 				LM_ERR("Setting of fr_inv_timer_avp failed\n");
  2320 				return -1;
  2323 		return 1;
  2326 	/* Append branches until out of branches or Q_FLAG is set */
  2327 	prev = avp;
  2328 	while ((avp = search_next_avp(avp, &val))) {
  2329 		destroy_avp(prev);
  2331 		LM_DBG("Next contact is <%s>\n", val.s.s);
  2333 		if (decode_branch_info(val.s.s, &uri, &dst, &path, &sock, &flags)== 0){
  2334 			LM_ERR("Decoding of branch info <%.*s> failed\n",
  2335 				val.s.len, val.s.s);
  2336 			destroy_avp(avp);
  2337 			return -1;
  2340 		if (append_branch(msg, &uri, &dst, &path, 0, flags, sock) != 1) {
  2341 			LM_ERR("Appending branch failed\n");
  2342 			destroy_avp(avp);
  2343 			return -1;
  2346 		if (avp->flags & Q_FLAG) {
  2347 			destroy_avp(avp);
  2348 			if (route_type == REQUEST_ROUTE) {
  2349 				val.n = fr_inv_timer_next;
  2350 				if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val)!= 0){
  2351 					LM_ERR("Setting of fr_inv_timer_avp failed\n");
  2352 					return -1;
  2355 			return 1;
  2357 		prev = avp;
  2360 	/* Restore fr_inv_timer */
  2361 	val.n = fr_inv_timer;
  2362 	if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val) != 0) {
  2363 		LM_ERR("Setting of fr_inv_timer_avp failed\n");
  2364 		return -1;
  2367 	return 1;
  2371 /* 
  2372  * Convert string parameter to integer for functions that expect an integer.
  2373  * Taken from sl module.
  2374  */
  2375 static int fixstringloadgws(void **param, int param_count)
  2377     pv_elem_t *model=NULL;
  2378     str s;
  2380     /* convert to str */
  2381     s.s = (char*)*param;
  2382     s.len = strlen(s.s);
  2384     model=NULL;
  2385     if (param_count==1) {
  2386 	if(s.len==0) {
  2387 	    LM_ERR("No param <%d>!\n", param_count);
  2388 	    return -1;
  2391 	if(pv_parse_format(&s,&model)<0 || model==NULL) {
  2392 	    LM_ERR("Wrong format <%s> for param <%d>!\n", s.s, param_count);
  2393 	    return -1;
  2395 	if(model->spec.getf==NULL) {
  2396 	    if(param_count==1) {
  2397 		if(str2int(&s, (unsigned int*)&model->spec.pvp.pvn.u.isname.name.n)!=0) {
  2398 		    LM_ERR("Wrong value <%s> for param <%d>!\n",
  2399 			   s.s, param_count);
  2400 		    return -1;
  2404 	*param = (void*)model;
  2407     return 0;

mercurial