opensips/modules/lcr/lcr_mod.c

Wed, 10 Feb 2010 21:25:01 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 10 Feb 2010 21:25:01 +0100
changeset 18
8ec65b8f6e2c
parent 16
c5c55937e44c
permissions
-rw-r--r--

Extend uac_auth() of the UAC module to workaround CSEQ problems.
This logic is meant to complement that of changeset 17, which
added rich authentication credentials to the gw table and its
associated logic in the LCR module.

     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