modules/lcr: use append_branch instead of do_action for appending branch
[sip-router] / modules / lcr / lcr_mod.c
1 /*
2  *
3  * Least Cost Routing module
4  *
5  * Copyright (C) 2005-2009 Juha Heinanen
6  * Copyright (C) 2006 Voice Sistem SRL
7  *
8  * This file is part of Kamailio, a free SIP server.
9  *
10  * Kamailio is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * Kamailio is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License 
21  * along with this program; if not, write to the Free Software 
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  * History:
25  * -------
26  *  2005-02-14: Introduced lcr module (jh)
27  *  2005-02-20: Added sequential forking functions (jh)
28  *  2005-02-25: Added support for int AVP names, combined addr and port
29  *              AVPs (jh)
30  *  2005-07-28: Added support for gw URI scheme and transport, 
31  *              backport from ser (kd)
32  *  2005-08-20: Added support for gw prefixes (jh)
33  *  2005-09-03: Request-URI user part can be modified between load_gws()
34  *              and first next_gw() calls.
35  *  2008-10-10: Database values are now checked and from/to_gw functions
36  *              execute in O(logN) time.
37  *  2008-11-26: Added timer based check of gateways (shurik)
38  *  2009-05-12  added RPC support (andrei)
39  *  2009-06-21  Added support for more than one lcr instance and
40                 gw defunct capability (jh)
41  */
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <arpa/inet.h>
47 #include <pcre.h>
48 #include "../../locking.h"
49 #include "../../sr_module.h"
50 #include "../../dprint.h"
51 #include "../../ut.h"
52 #include "../../error.h"
53 #include "../../mem/mem.h"
54 #include "../../mem/shm_mem.h"
55 #include "../../lib/srdb1/db.h"
56 #include "../../lib/kcore/km_ut.h"
57 #include "../../usr_avp.h"
58 #include "../../parser/parse_from.h"
59 #include "../../parser/msg_parser.h"
60 #include "../../action.h"
61 #include "../../qvalue.h"
62 #include "../../dset.h"
63 #include "../../ip_addr.h"
64 #include "../../resolve.h"
65 #include "../../lib/kmi/mi.h"
66 #include "../../mod_fix.h"
67 #include "../../socket_info.h"
68 #include "../../modules/tm/tm_load.h"
69 #include "../../pvar.h"
70 #include "../../mod_fix.h"
71 #include "hash.h"
72 #include "mi.h"
73 #include "lcr_rpc.h" /* defines RPC_SUPPORT */
74 #ifdef RPC_SUPPORT
75 #include "../../rpc_lookup.h"
76 #endif /* RPC_SUPPORT */
77
78
79
80 MODULE_VERSION
81
82 /*
83  * Version of gw and lcr tables required by the module,
84  * increment this value if you change the table in
85  * an backwards incompatible way
86  */
87 #define GW_TABLE_VERSION 10
88 #define LCR_TABLE_VERSION 3
89
90 static void destroy(void);       /* Module destroy function */
91 static int mi_child_init(void);
92 static int mod_init(void);       /* Module initialization function */
93 static int child_init(int rank); /* Per-child initialization function */
94 static void free_shared_memory(void);
95
96 #define GW_TABLE "gw"
97
98 #define LCR_ID_COL "lcr_id"
99
100 #define GW_NAME_COL "gw_name"
101
102 #define GRP_ID_COL "grp_id"
103
104 #define IP_ADDR_COL "ip_addr"
105
106 #define HOSTNAME_COL "hostname"
107
108 #define PORT_COL "port"
109
110 #define URI_SCHEME_COL "uri_scheme"
111
112 #define TRANSPORT_COL "transport"
113
114 #define STRIP_COL "strip"
115
116 #define TAG_COL "tag"
117
118 #define WEIGHT_COL "weight"
119
120 #define FLAGS_COL "flags"
121
122 #define DEFUNCT_COL "defunct"
123
124 #define LCR_TABLE "lcr"
125
126 #define PREFIX_COL "prefix"
127
128 #define FROM_URI_COL "from_uri"
129
130 #define PRIORITY_COL "priority"
131
132
133 /* Default module parameter values */
134 #define DEF_LCR_HASH_SIZE 128
135 #define DEF_FETCH_ROWS 1024
136
137 /*
138  * Type definitions
139  */
140
141 /* TMB Structure */
142 struct tm_binds tmb;
143
144 struct gw_grp {
145     unsigned int grp_id;
146     unsigned int first;   /* index to first gw of group in gw table */
147 };
148
149 struct matched_gw_info {
150     unsigned short gw_index;
151     unsigned short prefix_len;
152     unsigned short priority;
153     unsigned int weight;
154     unsigned short duplicate;
155 };
156
157 /*
158  * Database variables
159  */
160 static db1_con_t* dbh = 0;   /* Database connection handle */
161 static db_func_t lcr_dbf;
162
163 /*
164  * Locking variables
165  */
166 gen_lock_t *reload_lock;
167
168 /*
169  * Module parameter variables
170  */
171
172 /* database tables */
173 static str db_url           = str_init(DEFAULT_RODB_URL);
174 static str gw_table         = str_init(GW_TABLE);
175 static str lcr_id_col       = str_init(LCR_ID_COL);
176 static str gw_name_col      = str_init(GW_NAME_COL);
177 static str grp_id_col       = str_init(GRP_ID_COL);
178 static str ip_addr_col      = str_init(IP_ADDR_COL);
179 static str hostname_col     = str_init(HOSTNAME_COL);
180 static str port_col         = str_init(PORT_COL);
181 static str uri_scheme_col   = str_init(URI_SCHEME_COL);
182 static str transport_col    = str_init(TRANSPORT_COL);
183 static str strip_col        = str_init(STRIP_COL);
184 static str tag_col          = str_init(TAG_COL);
185 static str weight_col       = str_init(WEIGHT_COL);
186 static str flags_col        = str_init(FLAGS_COL);
187 static str defunct_col      = str_init(DEFUNCT_COL);
188 static str lcr_table        = str_init(LCR_TABLE);
189 static str prefix_col       = str_init(PREFIX_COL);
190 static str from_uri_col     = str_init(FROM_URI_COL);
191 static str priority_col     = str_init(PRIORITY_COL);
192
193 /* number of rows to fetch at a shot */
194 static int fetch_rows_param = DEF_FETCH_ROWS;
195
196 /* avps */
197 static char *gw_uri_avp_param = NULL;
198 static char *ruri_user_avp_param = NULL;
199 static char *flags_avp_param = NULL;
200 static char *defunct_gw_avp_param = NULL;
201 static char *lcr_id_avp_param = NULL;
202
203 /* size of prefix hash table */
204 unsigned int lcr_hash_size_param = DEF_LCR_HASH_SIZE;
205
206 /* number of lcr instances */
207 unsigned int lcr_count = 1;
208
209 /* can gws be defuncted */
210 static unsigned int defunct_capability = 0;
211
212 /*
213  * Other module types and variables
214  */
215
216 static int     gw_uri_avp_type;
217 static int_str gw_uri_avp;
218 static int     ruri_user_avp_type;
219 static int_str ruri_user_avp;
220 static int     flags_avp_type;
221 static int_str flags_avp;
222 static int     defunct_gw_avp_type;
223 static int_str defunct_gw_avp;
224 static int     lcr_id_avp_type;
225 static int_str lcr_id_avp;
226
227 /* Pointer to gw table pointer table */
228 struct gw_info **gwtp = (struct gw_info **)NULL;
229
230 /* Pointer to lcr hash table pointer table */
231 struct lcr_info ***lcrtp = (struct lcr_info ***)NULL;
232
233
234 /*
235  * Functions that are defined later
236  */
237 static int load_gws(struct sip_msg* _m, char* _s1, char* _s2);
238 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2);
239 static int defunct_gw(struct sip_msg* _m, char* _s1, char* _s2);
240 static int from_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
241 static int from_gw_2(struct sip_msg* _m, char* _s1, char* _s2);
242 static int from_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2);
243 static int from_any_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
244 static int to_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
245 static int to_gw_2(struct sip_msg* _m, char* _s1, char* _s2);
246 static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2);
247 static int to_any_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
248
249 /*
250  * Exported functions
251  */
252 static cmd_export_t cmds[] = {
253     {"load_gws", (cmd_function)load_gws, 2, fixup_igp_pvar,
254      fixup_free_igp_pvar, REQUEST_ROUTE | FAILURE_ROUTE},
255     {"next_gw", (cmd_function)next_gw, 0, 0, 0,
256      REQUEST_ROUTE | FAILURE_ROUTE},
257     {"defunct_gw", (cmd_function)defunct_gw, 1, fixup_igp_null, 0,
258      REQUEST_ROUTE | FAILURE_ROUTE},
259     {"from_gw", (cmd_function)from_gw_1, 1, fixup_igp_null, 0,
260      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
261     {"from_gw", (cmd_function)from_gw_2, 2, fixup_igp_pvar,
262      fixup_free_igp_pvar, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
263     {"from_any_gw", (cmd_function)from_any_gw_0, 0, 0, 0,
264      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
265     {"from_any_gw", (cmd_function)from_any_gw_1, 1, fixup_pvar_null,
266      fixup_free_pvar_null, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
267     {"to_gw", (cmd_function)to_gw_1, 1, fixup_igp_null, 0,
268      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
269     {"to_gw", (cmd_function)to_gw_2, 2, fixup_igp_pvar,
270      fixup_free_igp_pvar, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
271     {"to_any_gw", (cmd_function)to_any_gw_0, 0, 0, 0,
272      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
273     {"to_any_gw", (cmd_function)to_any_gw_1, 1, fixup_pvar_null,
274      fixup_free_pvar_null, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
275     {0, 0, 0, 0, 0, 0}
276 };
277
278
279 /*
280  * Exported parameters
281  */
282 static param_export_t params[] = {
283     {"db_url",                   STR_PARAM, &db_url.s       },
284     {"gw_table",                 STR_PARAM, &gw_table.s     },
285     {"lcr_id_column",            STR_PARAM, &lcr_id_col.s   },
286     {"gw_name_column",           STR_PARAM, &gw_name_col.s  },
287     {"grp_id_column",            STR_PARAM, &grp_id_col.s   },
288     {"ip_addr_column",           STR_PARAM, &ip_addr_col.s  },
289     {"hostname_column",          STR_PARAM, &hostname_col.s },
290     {"port_column",              STR_PARAM, &port_col.s     },
291     {"uri_scheme_column",        STR_PARAM, &uri_scheme_col.s },
292     {"transport_column",         STR_PARAM, &transport_col.s },
293     {"strip_column",             STR_PARAM, &strip_col.s    },
294     {"tag_column",               STR_PARAM, &tag_col.s      },
295     {"weight_column",            STR_PARAM, &weight_col.s   },
296     {"flags_column",             STR_PARAM, &flags_col.s    },
297     {"lcr_table",                STR_PARAM, &lcr_table.s    },
298     {"prefix_column",            STR_PARAM, &prefix_col.s   },
299     {"from_uri_column",          STR_PARAM, &from_uri_col.s },
300     {"priority_column",          STR_PARAM, &priority_col.s },
301     {"gw_uri_avp",               STR_PARAM, &gw_uri_avp_param },
302     {"ruri_user_avp",            STR_PARAM, &ruri_user_avp_param },
303     {"flags_avp",                STR_PARAM, &flags_avp_param },
304     {"lcr_hash_size",            INT_PARAM, &lcr_hash_size_param },
305     {"lcr_count",                INT_PARAM, &lcr_count },
306     {"fetch_rows",               INT_PARAM, &fetch_rows_param },
307     {"defunct_capability",       INT_PARAM, &defunct_capability },
308     {"defunct_gw_avp",           STR_PARAM, &defunct_gw_avp_param },
309     {"lcr_id_avp",               STR_PARAM, &lcr_id_avp_param },
310     {0, 0, 0}
311 };
312
313
314 /*
315  * Exported MI functions
316  */
317 static mi_export_t mi_cmds[] = {
318     { MI_LCR_RELOAD, mi_lcr_reload, MI_NO_INPUT_FLAG, 0, mi_child_init },
319     { MI_LCR_GW_DUMP, mi_lcr_gw_dump, MI_NO_INPUT_FLAG, 0, 0 },
320     { MI_LCR_LCR_DUMP, mi_lcr_lcr_dump, MI_NO_INPUT_FLAG, 0, 0 },
321     { 0, 0, 0, 0 ,0}
322 };
323
324
325 /*
326  * Module interface
327  */
328 struct module_exports exports = {
329         "lcr", 
330         DEFAULT_DLFLAGS, /* dlopen flags */
331         cmds,      /* Exported functions */
332         params,    /* Exported parameters */
333         0,         /* exported statistics */
334         mi_cmds,   /* exported MI functions */
335         0,         /* exported pseudo-variables */
336         0,         /* extra processes */
337         mod_init,  /* module initialization function */
338         0,         /* response function */
339         destroy,   /* destroy function */
340         child_init /* child initialization function */
341 };
342
343
344 static int lcr_db_init(const str* db_url)
345 {       
346         if (lcr_dbf.init==0){
347                 LM_CRIT("null lcr_dbf\n");
348                 goto error;
349         }
350         dbh=lcr_dbf.init(db_url);
351         if (dbh==0){
352                 LM_ERR("unable to connect to the database\n");
353                 goto error;
354         }
355         return 0;
356 error:
357         return -1;
358 }
359
360
361
362 static int lcr_db_bind(const str* db_url)
363 {
364     if (db_bind_mod(db_url, &lcr_dbf)<0){
365         LM_ERR("unable to bind to the database module\n");
366         return -1;
367     }
368
369     if (!DB_CAPABILITY(lcr_dbf, DB_CAP_QUERY)) {
370         LM_ERR("database module does not implement 'query' function\n");
371         return -1;
372     }
373
374     return 0;
375 }
376
377
378 static void lcr_db_close(void)
379 {
380         if (dbh && lcr_dbf.close){
381                 lcr_dbf.close(dbh);
382                 dbh=0;
383         }
384 }
385
386
387 static int mi_child_init(void)
388 {
389         return lcr_db_init(&db_url);
390 }
391
392
393 /*
394  * Module initialization function that is called before the main process forks
395  */
396 static int mod_init(void)
397 {
398     pv_spec_t avp_spec;
399     str s;
400     unsigned short avp_flags;
401     unsigned int i;
402     db1_con_t* dbh;
403
404         if(register_mi_mod(exports.name, mi_cmds)!=0)
405         {
406                 LM_ERR("failed to register MI commands\n");
407                 return -1;
408         }
409 #ifdef RPC_SUPPORT
410         if (rpc_register_array(lcr_rpc)!=0)
411         {
412                 LM_ERR("failed to register RPC commands\n");
413                 return -1;
414         }
415 #endif /* RPC_SUPPORT */
416
417
418     /* Update length of module variables */
419     db_url.len = strlen(db_url.s);
420     gw_table.len = strlen(gw_table.s);
421     lcr_id_col.len = strlen(lcr_id_col.s);
422     gw_name_col.len = strlen(gw_name_col.s);
423     grp_id_col.len = strlen(grp_id_col.s);
424     ip_addr_col.len = strlen(ip_addr_col.s);
425     hostname_col.len = strlen(hostname_col.s);
426     port_col.len = strlen(port_col.s);
427     uri_scheme_col.len = strlen(uri_scheme_col.s);
428     transport_col.len = strlen(transport_col.s);
429     strip_col.len = strlen(strip_col.s);
430     tag_col.len = strlen(tag_col.s);
431     weight_col.len = strlen(weight_col.s);
432     flags_col.len = strlen(flags_col.s);
433     lcr_table.len = strlen(lcr_table.s);
434     prefix_col.len = strlen(prefix_col.s);
435     from_uri_col.len = strlen(from_uri_col.s);
436     priority_col.len = strlen(priority_col.s);
437
438     /* Bind database */
439     if (lcr_db_bind(&db_url)) {
440         LM_ERR("no database module found\n");
441         return -1;
442     }
443
444     /* Check value of prefix_hash_size */
445     if (lcr_hash_size_param <= 0) {
446         LM_ERR("invalid prefix_hash_size value <%d>\n", lcr_hash_size_param);
447         return -1;
448     }
449
450     /* Check value of lcr_count */
451     if (lcr_count < 1) {
452         LM_ERR("invalid lcr_count module parameter value <%d>\n", lcr_count);
453         return -1;
454     }
455
456     /* Process AVP params */
457
458     if (gw_uri_avp_param && *gw_uri_avp_param) {
459         s.s = gw_uri_avp_param; s.len = strlen(s.s);
460         if (pv_parse_spec(&s, &avp_spec)==0
461             || avp_spec.type!=PVT_AVP) {
462             LM_ERR("malformed or non AVP definition <%s>\n", gw_uri_avp_param);
463             return -1;
464         }
465         
466         if (pv_get_avp_name(0, &(avp_spec.pvp), &gw_uri_avp, &avp_flags) != 0) {
467             LM_ERR("invalid AVP definition <%s>\n", gw_uri_avp_param);
468             return -1;
469         }
470         gw_uri_avp_type = avp_flags;
471     } else {
472         LM_ERR("AVP gw_uri_avp has not been defined\n");
473         return -1;
474     }
475
476     if (ruri_user_avp_param && *ruri_user_avp_param) {
477         s.s = ruri_user_avp_param; s.len = strlen(s.s);
478         if (pv_parse_spec(&s, &avp_spec)==0
479             || avp_spec.type!=PVT_AVP) {
480             LM_ERR("malformed or non AVP definition <%s>\n",
481                    ruri_user_avp_param);
482             return -1;
483         }
484         
485         if (pv_get_avp_name(0, &(avp_spec.pvp), &ruri_user_avp, &avp_flags)
486             != 0) {
487             LM_ERR("invalid AVP definition <%s>\n", ruri_user_avp_param);
488             return -1;
489         }
490         ruri_user_avp_type = avp_flags;
491     } else {
492         LM_ERR("AVP ruri_user_avp has not been defined\n");
493         return -1;
494     }
495
496     if (flags_avp_param && *flags_avp_param) {
497         s.s = flags_avp_param; s.len = strlen(s.s);
498         if (pv_parse_spec(&s, &avp_spec)==0
499             || avp_spec.type!=PVT_AVP) {
500             LM_ERR("malformed or non AVP definition <%s>\n", flags_avp_param);
501             return -1;
502         }
503         
504         if (pv_get_avp_name(0, &(avp_spec.pvp), &flags_avp, &avp_flags) != 0) {
505             LM_ERR("invalid AVP definition <%s>\n", flags_avp_param);
506             return -1;
507         }
508         flags_avp_type = avp_flags;
509     } else {
510         LM_ERR("AVP flags_avp has not been defined\n");
511         return -1;
512     }
513
514     if (defunct_capability > 0) {
515         if (defunct_gw_avp_param && *defunct_gw_avp_param) {
516             s.s = defunct_gw_avp_param; s.len = strlen(s.s);
517             if ((pv_parse_spec(&s, &avp_spec) == 0) ||
518                 (avp_spec.type != PVT_AVP)) {
519                 LM_ERR("malformed or non AVP definition <%s>\n",
520                        defunct_gw_avp_param);
521                 return -1;
522             }
523             if (pv_get_avp_name(0, &(avp_spec.pvp), &defunct_gw_avp,
524                                 &avp_flags) != 0) {
525                 LM_ERR("invalid AVP definition <%s>\n", defunct_gw_avp_param);
526                 return -1;
527             }
528             defunct_gw_avp_type = avp_flags;
529         } else {
530             LM_ERR("AVP defunct_gw_avp has not been defined\n");
531             return -1;
532         }
533         if (lcr_id_avp_param && *lcr_id_avp_param) {
534             s.s = lcr_id_avp_param; s.len = strlen(s.s);
535             if ((pv_parse_spec(&s, &avp_spec) == 0) ||
536                 (avp_spec.type != PVT_AVP)) {
537                 LM_ERR("malformed or non AVP definition <%s>\n",
538                        lcr_id_avp_param);
539                 return -1;
540             }
541             if (pv_get_avp_name(0, &(avp_spec.pvp), &lcr_id_avp,
542                                 &avp_flags) != 0) {
543                 LM_ERR("invalid AVP definition <%s>\n", lcr_id_avp_param);
544                 return -1;
545             }
546             lcr_id_avp_type = avp_flags;
547         } else {
548             LM_ERR("AVP lcr_id_avp has not been defined\n");
549             return -1;
550         }
551     }
552
553     if (fetch_rows_param < 1) {
554         LM_ERR("invalid fetch_rows module parameter value <%d>\n",
555                fetch_rows_param);
556         return -1;
557     }
558
559     /* Check table version */
560     if (lcr_dbf.init==0){
561         LM_CRIT("unbound database\n");
562         return -1;
563     }
564     dbh=lcr_dbf.init(&db_url);
565     if (dbh == NULL){
566         LM_ERR("unable to open database connection\n");
567         return -1;
568     }
569     if ((db_check_table_version(&lcr_dbf, dbh, &gw_table, GW_TABLE_VERSION)
570          < 0) ||
571         (db_check_table_version(&lcr_dbf, dbh, &lcr_table, LCR_TABLE_VERSION)
572          < 0)) { 
573         LM_ERR("error during table version check\n");
574         lcr_dbf.close(dbh);
575         goto err;
576     }
577     lcr_dbf.close(dbh);
578
579     /* Allocate gw related shared memory */
580     /* gw table pointer table, index 0 points to temp gw table  */
581     gwtp = (struct gw_info **)shm_malloc(sizeof(struct gw_info *) *
582                                          (lcr_count + 1));
583     if (gwtp == 0) {
584         LM_ERR("no memory for gw table pointer table\n");
585         goto err;
586     }
587     memset(gwtp, 0, sizeof(struct gw_info *) * (lcr_count + 1));
588     /* gw tables */
589     for (i = 0; i <= lcr_count; i++) {
590         gwtp[i] = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
591                                                (MAX_NO_OF_GWS + 2));
592         if (gwtp[i] == 0) {
593             LM_ERR("no memory for gw table\n");
594             goto err;
595         }
596         (gwtp[i])[0].ip_addr = 0;    /* Number of gateways in table */
597     }
598
599     /* Allocate lcr rules related shared memory */
600     /* lcr hash table pointer table, index 0 points to temp lcr table */
601     lcrtp = (struct lcr_info ***)shm_malloc(sizeof(struct lcr_info **) *
602                                             (lcr_count + 1));
603     if (lcrtp == 0) {
604         LM_ERR("no memory for lcr hash table pointer table\n");
605         goto err;
606     }
607     memset(lcrtp, 0, sizeof(struct lcr_info **) * (lcr_count + 1));
608     /* lcr hash tables */
609     /* Last entry in hash table contains list of different prefix lengths */
610     for (i = 0; i <= lcr_count; i++) {
611         lcrtp[i] = (struct lcr_info **)shm_malloc(sizeof(struct lcr_info *) *
612                                                   (lcr_hash_size_param + 1));
613         if (lcrtp[i] == 0) {
614             LM_ERR("no memory for lcr hash table\n");
615             goto err;
616         }
617         memset(lcrtp[i], 0, sizeof(struct lcr_info *) *
618                (lcr_hash_size_param + 1));
619     }
620
621     /* Allocate and initialize locks */
622     reload_lock = lock_alloc();
623     if (reload_lock == NULL) {
624         LM_ERR("cannot allocate reload_lock\n");
625         goto err;
626     }
627     if (lock_init(reload_lock) == NULL) {
628         LM_ERR("cannot init reload_lock\n");
629         goto err;
630     }
631
632     /* First reload */
633     lock_get(reload_lock);
634     for (i = 1; i <= lcr_count; i++) {
635         if (reload_gws_and_lcrs(i) < 0) {
636             lock_release(reload_lock);
637             LM_CRIT("failed to reload gateways of lcr_id %i\n", i);
638             goto err;
639         }
640     }
641     lock_release(reload_lock);
642
643     return 0;
644
645 err:
646     free_shared_memory();
647     return -1;
648 }
649
650
651 /* Module initialization function called in each child separately */
652 static int child_init(int rank)
653 {
654 #ifdef RPC_SUPPORT
655         /* do nothing for the main process, tcp main process or timer */
656         if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN ||
657                 rank==PROC_TIMER)
658                 return 0;
659         /* init db for the rest of the processes:
660            - we need it for PROC_RPC and PROC_FIFO if we want db access from
661              RPC accessed via the ctl module
662            - we need it from all the ser tcp or tls processes if we want
663              db access from RPC via the xmlrpc module */
664         return lcr_db_init(&db_url);
665 #else
666         return 0;
667 #endif /* RPC_SUPPORT */
668 }
669
670
671 static void destroy(void)
672 {
673     lcr_db_close();
674
675     free_shared_memory();
676 }
677
678 /* Free shared memory */
679 static void free_shared_memory(void)
680 {
681     int i;
682     for (i = 0; i <= lcr_count; i++) {
683         if (gwtp && gwtp[i]) {
684             shm_free(gwtp[i]);
685             gwtp[i] = 0;
686         }
687         if (lcrtp && lcrtp[i]) {
688             lcr_hash_table_contents_free(lcrtp[i]);
689             shm_free(lcrtp[i]);
690             lcrtp[i] = 0;
691         }
692     }
693     if (gwtp) shm_free(gwtp);
694     if (lcrtp) shm_free(lcrtp);
695     if (reload_lock) {
696         lock_destroy(reload_lock);
697         lock_dealloc(reload_lock);
698         reload_lock=0;
699     }
700 }
701    
702 /*
703  * Compare matched gateways based on prefix_len, priority, and randomized
704  * weight.
705  */
706 static int comp_matched(const void *m1, const void *m2)
707 {
708     struct matched_gw_info *mi1 = (struct matched_gw_info *) m1;
709     struct matched_gw_info *mi2 = (struct matched_gw_info *) m2;
710
711     /* Sort by prefix_len */
712     if (mi1->prefix_len > mi2->prefix_len) return 1;
713     if (mi1->prefix_len == mi2->prefix_len) {
714         /* Sort by priority */
715         if (mi1->priority < mi2->priority) return 1;
716         if (mi1->priority == mi2->priority) {
717             /* Sort by randomized weigth */
718             if (mi1->weight > mi2->weight) return 1;
719             if (mi1->weight == mi2->weight) return 0;
720             return -1;
721         }
722         return -1;
723     }
724     return -1;
725 }
726
727
728 /* Compile pattern into shared memory and return pointer to it. */
729 static pcre *reg_ex_comp(const char *pattern)
730 {
731     pcre *re, *result;
732     const char *error;
733     int rc, size, err_offset;
734
735     re = pcre_compile(pattern, 0, &error, &err_offset, NULL);
736     if (re == NULL) {
737         LM_ERR("pcre compilation of '%s' failed at offset %d: %s\n",
738                pattern, err_offset, error);
739         return (pcre *)0;
740     }
741     rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size);
742     if (rc != 0) {
743         LM_ERR("pcre_fullinfo on compiled pattern '%s' yielded error: %d\n",
744                pattern, rc);
745         return (pcre *)0;
746     }
747     result = (pcre *)shm_malloc(size);
748     if (result == NULL) {
749         pcre_free(re);
750         LM_ERR("not enough shared memory for compiled PCRE pattern\n");
751         return (pcre *)0;
752     }
753     memcpy(result, re, size);
754     pcre_free(re);
755     return result;
756 }
757
758
759 /*
760  * Compare gateways based on their IP address and group id
761  */
762 static int comp_gw_grps(const void *_g1, const void *_g2)
763 {
764     struct gw_info *g1 = (struct gw_info *)_g1;
765     struct gw_info *g2 = (struct gw_info *)_g2;
766
767     if (g1->ip_addr < g2->ip_addr) return -1;
768     if (g1->ip_addr > g2->ip_addr) return 1;
769
770     if (g1->grp_id < g2->grp_id) return -1;
771     if (g1->grp_id > g2->grp_id) return 1;
772
773     return 0;
774 }
775
776
777 /*
778  * Compare gateways based on their IP address
779  */
780 static int comp_gws(const void *_g1, const void *_g2)
781 {
782     struct gw_info *g1 = (struct gw_info *)_g1;
783     struct gw_info *g2 = (struct gw_info *)_g2;
784
785     if (g1->ip_addr < g2->ip_addr) return -1;
786     if (g1->ip_addr > g2->ip_addr) return 1;
787
788     return 0;
789 }
790
791
792 /*
793  * Check if ip_addr/grp_id of gateway is unique.
794  */
795 static int gw_unique(const struct gw_info *gws, const unsigned int count,
796                      const unsigned int ip_addr, const unsigned int grp_id)
797 {
798     unsigned int i;
799
800     for (i = 1; i <= count; i++) {
801         if ((gws[i].ip_addr == ip_addr) &&
802             (gws[i].grp_id == grp_id))
803             return 0;
804     }
805
806     return 1;
807 }
808
809 static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int ip_addr,
810                      char *hostname, unsigned int hostname_len,
811                      unsigned int grp_id, char *ip_string, unsigned int port,
812                      unsigned int scheme, unsigned int transport,
813                      unsigned int flags, unsigned int strip, char *tag,
814                      unsigned int tag_len, unsigned short weight,
815                      unsigned int defunct_until)
816 {
817     if (gw_unique(gws, i - 1, ip_addr, grp_id) == 0) {
818         LM_ERR("ip_addr/grp_id <%s/%u> of gw is not unique\n",
819                ip_string, grp_id);
820         return 0;
821     }
822     gws[i].ip_addr = ip_addr;
823     if (hostname_len) memcpy(&(gws[i].hostname[0]), hostname, hostname_len);
824     gws[i].hostname_len = hostname_len;
825     gws[i].ip_addr = ip_addr;
826     gws[i].port = port;
827     gws[i].grp_id = grp_id;
828     gws[i].scheme = scheme;
829     gws[i].transport = transport;
830     gws[i].flags = flags;
831     gws[i].strip = strip;
832     gws[i].tag_len = tag_len;
833     if (tag_len) memcpy(&(gws[i].tag[0]), tag, tag_len);
834     gws[i].weight = weight;
835     gws[i].defunct_until = defunct_until;
836     gws[i].next = 0;
837
838     return 1;
839 }
840
841 /*
842  * Links gws that belong to same group via next field, sets gw_grps
843  * array with first indexes of each group, and sets grp_cnt to number of
844  * different gw groups.
845  */
846 static void link_gw_grps(struct gw_info *gws, struct gw_grp *gw_grps,
847                          unsigned int *grp_cnt)
848 {
849     unsigned int i, j;
850
851     *grp_cnt = 0;
852     
853     for (i = 1; i <= gws[0].ip_addr; i++) {
854         for (j = 1; j < i; j++) {
855             if (gws[j].grp_id == gws[i].grp_id) {
856                 gws[i].next = gws[j].next;
857                 gws[j].next = i;
858                 goto found;
859             }
860         }
861         gw_grps[*grp_cnt].grp_id = gws[i].grp_id;
862         gw_grps[*grp_cnt].first = i;
863         *grp_cnt = *grp_cnt + 1;
864     found:
865         continue;
866     }
867 }
868
869 /*
870  * Return gw table index of first gw in given group or 0 if no gws in
871  * the group.
872  */
873 static int find_first_gw(struct gw_grp *gw_grps, unsigned int grp_cnt,
874                          unsigned int grp_id)
875 {
876     unsigned int i;
877     
878     for (i = 0; i < grp_cnt; i++) {
879         if (gw_grps[i].grp_id == grp_id) {
880             return gw_grps[i].first;
881         }
882     }
883
884     return 0;
885 }
886
887 /*
888  * Insert prefix_len into list pointed by last lcr hash table entry 
889  * if not there already. Keep list in decending prefix_len order.
890  */
891 static int prefix_len_insert(struct lcr_info **table, unsigned short prefix_len)
892 {
893     struct lcr_info *lcr_rec, **previous, *this;
894     
895     previous = &(table[lcr_hash_size_param]);
896     this = table[lcr_hash_size_param];
897
898     while (this) {
899         if (this->prefix_len == prefix_len)
900             return 1;
901         if (this->prefix_len < prefix_len) {
902             lcr_rec = shm_malloc(sizeof(struct lcr_info));
903             if (lcr_rec == NULL) {
904                 LM_ERR("no shared memory for lcr_info\n");
905                 return 0;
906             }
907             memset(lcr_rec, 0, sizeof(struct lcr_info));
908             lcr_rec->prefix_len = prefix_len;
909             lcr_rec->next = this;
910             *previous = lcr_rec;
911             return 1;
912         }
913         previous = &(this->next);
914         this = this->next;
915     }
916
917     lcr_rec = shm_malloc(sizeof(struct lcr_info));
918     if (lcr_rec == NULL) {
919         LM_ERR("no shared memory for lcr_info\n");
920         return 0;
921     }
922     memset(lcr_rec, 0, sizeof(struct lcr_info));
923     lcr_rec->prefix_len = prefix_len;
924     lcr_rec->next = NULL;
925     *previous = lcr_rec;
926     return 1;
927 }
928
929
930 /*
931  * Reload gws to unused gw table, lcrs to unused lcr hash table, and
932  * prefix lens to a new prefix_len list.  When done, make these tables
933  * and list the current ones.
934  */
935 int reload_gws_and_lcrs(int lcr_id)
936 {
937     unsigned int i, n, port, strip, tag_len, prefix_len, from_uri_len,
938         grp_id, grp_cnt, priority, flags, first_gw, weight, gw_cnt,
939         hostname_len, defunct_until;
940     struct in_addr ip_addr;
941     uri_type scheme;
942     uri_transport transport;
943     db1_con_t* dbh;
944     char *ip_string, *hostname, *tag, *prefix, *from_uri;
945     db1_res_t* res = NULL;
946     db_row_t* row;
947     db_key_t key_cols[1];
948     db_op_t op[1];
949     db_val_t vals[1];
950     db_key_t gw_cols[11];
951     db_key_t lcr_cols[4];
952     pcre *from_uri_re;
953     struct gw_grp gw_grps[MAX_NO_OF_GWS];
954     struct gw_info *gws, *gwtp_tmp;
955     struct lcr_info **lcrs, **lcrtp_tmp;
956         
957     key_cols[0] = &lcr_id_col;
958     op[0] = OP_EQ;
959     VAL_TYPE(vals) = DB1_INT;
960     VAL_NULL(vals) = 0;
961     VAL_INT(vals) = lcr_id;
962
963     gw_cols[0] = &ip_addr_col;
964     gw_cols[1] = &port_col;
965     gw_cols[2] = &uri_scheme_col;
966     gw_cols[3] = &transport_col;
967     gw_cols[4] = &strip_col;
968     gw_cols[5] = &tag_col;
969     gw_cols[6] = &grp_id_col;
970     gw_cols[7] = &flags_col;
971     gw_cols[8] = &weight_col;
972     gw_cols[9] = &hostname_col;
973     gw_cols[10] = &defunct_col;
974
975     lcr_cols[0] = &prefix_col;
976     lcr_cols[1] = &from_uri_col;
977     lcr_cols[2] = &grp_id_col;
978     lcr_cols[3] = &priority_col;
979
980     /* Reload gws */
981
982     gws = gwtp[0];
983
984     if (lcr_dbf.init == 0) {
985         LM_CRIT("unbound database\n");
986         return -1;
987     }
988     dbh = lcr_dbf.init(&db_url);
989     if (dbh == 0) {
990         LM_ERR("unable to open database connection\n");
991         return -1;
992     }
993
994     if (lcr_dbf.use_table(dbh, &gw_table) < 0) {
995         LM_ERR("error while trying to use gw table\n");
996         return -1;
997     }
998
999     if (lcr_dbf.query(dbh, key_cols, op, vals, gw_cols, 1, 11, 0, &res) < 0) {
1000         LM_ERR("failed to query gw data\n");
1001         lcr_dbf.close(dbh);
1002         return -1;
1003     }
1004
1005     if (RES_ROW_N(res) + 1 > MAX_NO_OF_GWS) {
1006         LM_ERR("too many gateways\n");
1007         goto gw_err;
1008     }
1009
1010     for (i = 0; i < RES_ROW_N(res); i++) {
1011         row = RES_ROWS(res) + i;
1012         if (VAL_NULL(ROW_VALUES(row)) ||
1013             (VAL_TYPE(ROW_VALUES(row)) != DB1_STRING)) {
1014             LM_ERR("gw ip address at row <%u> is null or not string\n", i);
1015             goto gw_err;
1016         }
1017         ip_string = (char *)VAL_STRING(ROW_VALUES(row));
1018         if (inet_aton(ip_string, &ip_addr) == 0) {
1019             LM_ERR("gateway ip address <%s> at row <%u> is invalid\n",
1020                    ip_string, i);
1021             goto gw_err;
1022         }
1023         if (VAL_NULL(ROW_VALUES(row) + 1)) {
1024             port = 0;
1025         } else {
1026             if (VAL_TYPE(ROW_VALUES(row) + 1) != DB1_INT) {
1027                 LM_ERR("port of gw <%s> at row <%u> is not int\n",
1028                        ip_string, i);
1029                 goto gw_err;
1030             }
1031             port = (unsigned int)VAL_INT(ROW_VALUES(row) + 1);
1032         }
1033         if (port > 65536) {
1034             LM_ERR("port <%d> of gw <%s> at row <%u> is too large\n",
1035                    port, ip_string, i);
1036             goto gw_err;
1037         }
1038         if (VAL_NULL(ROW_VALUES(row) + 2)) {
1039             scheme = SIP_URI_T;
1040         } else {
1041             if (VAL_TYPE(ROW_VALUES(row) + 2) != DB1_INT) {
1042                 LM_ERR("uri scheme of gw <%s> at row <%u> is not int\n",
1043                        ip_string, i);
1044                 goto gw_err;
1045             }
1046             scheme = (uri_type)VAL_INT(ROW_VALUES(row) + 2);
1047         }
1048         if ((scheme != SIP_URI_T) && (scheme != SIPS_URI_T)) {
1049             LM_ERR("unknown or unsupported URI scheme <%u> of gw <%s> at "
1050                    "row <%u>\n", (unsigned int)scheme, ip_string, i);
1051             goto gw_err;
1052         }
1053         if (VAL_NULL(ROW_VALUES(row) + 3)) {
1054             transport = PROTO_NONE;
1055         } else {
1056             if (VAL_TYPE(ROW_VALUES(row) + 3) != DB1_INT) {
1057                 LM_ERR("transport of gw <%s> at row <%u> is not int\n",
1058                        ip_string, i);
1059                 goto gw_err;
1060             }
1061             transport = (uri_transport)VAL_INT(ROW_VALUES(row) + 3);    
1062         }
1063         if ((transport != PROTO_UDP) && (transport != PROTO_TCP) &&
1064             (transport != PROTO_TLS) && (transport != PROTO_SCTP) &&
1065             (transport != PROTO_NONE)) {
1066             LM_ERR("unknown or unsupported transport <%u> of gw <%s> at "
1067                    " row <%u>\n", (unsigned int)transport, ip_string, i);
1068             goto gw_err;
1069         }
1070         if ((scheme == SIPS_URI_T) && (transport == PROTO_UDP)) {
1071             LM_ERR("wrong transport <%u> for SIPS URI scheme of gw <%s> at "
1072                    "row <%u>\n", transport, ip_string, i); 
1073             goto gw_err;
1074         }
1075         if (VAL_NULL(ROW_VALUES(row) + 4)) {
1076             strip = 0;
1077         } else {
1078             if (VAL_TYPE(ROW_VALUES(row) + 4) != DB1_INT) {
1079                 LM_ERR("strip count of gw <%s> at row <%u> is not int\n",
1080                        ip_string, i);
1081                 goto gw_err;
1082             }
1083             strip = (unsigned int)VAL_INT(ROW_VALUES(row) + 4);
1084         }
1085         if (strip > MAX_USER_LEN) {
1086             LM_ERR("strip count <%u> of gw <%s> at row <%u> it too large\n",
1087                    strip, ip_string, i);
1088             goto gw_err;
1089         }
1090         if (VAL_NULL(ROW_VALUES(row) + 5)) {
1091             tag_len = 0;
1092             tag = (char *)0;
1093         } else {
1094             if (VAL_TYPE(ROW_VALUES(row) + 5) != DB1_STRING) {
1095                 LM_ERR("tag of gw <%s> at row <%u> is not string\n",
1096                        ip_string, i);
1097                 goto gw_err;
1098             }
1099             tag = (char *)VAL_STRING(ROW_VALUES(row) + 5);
1100             tag_len = strlen(tag);
1101         }
1102         if (tag_len > MAX_TAG_LEN) {
1103             LM_ERR("tag length <%u> of gw <%s> at row <%u> it too large\n",
1104                    tag_len, ip_string, i);
1105             goto gw_err;
1106         }
1107         if (VAL_NULL(ROW_VALUES(row) + 6)) {
1108             grp_id = 0;
1109         } else {
1110             if (VAL_TYPE(ROW_VALUES(row) + 6) != DB1_INT) {
1111                 LM_ERR("grp_id of gw <%s> at row <%u> is not int\n",
1112                        ip_string, i);
1113                 goto gw_err;
1114             }
1115             grp_id = VAL_INT(ROW_VALUES(row) + 6);
1116         }
1117         if (!VAL_NULL(ROW_VALUES(row) + 7) &&
1118             (VAL_TYPE(ROW_VALUES(row) + 7) == DB1_INT)) {
1119             flags = (unsigned int)VAL_INT(ROW_VALUES(row) + 7);
1120         } else {
1121             LM_ERR("flags of gw <%s> at row <%u> is NULL or not int\n",
1122                    ip_string, i);
1123             goto gw_err;
1124         }
1125         if (VAL_NULL(ROW_VALUES(row) + 8)) {
1126             weight = 1;
1127         } else {
1128             if (VAL_TYPE(ROW_VALUES(row) + 8) != DB1_INT) {
1129                 LM_ERR("weight of gw <%s> at row <%u> is not int\n",
1130                        ip_string, i);
1131                 goto gw_err;
1132             }
1133             weight = (unsigned int)VAL_INT(ROW_VALUES(row) + 8);
1134         }
1135         if ((weight < 1) || (weight > 254)) {
1136             LM_ERR("weight <%d> of gw <%s> at row <%u> is not 1-254\n",
1137                    weight, ip_string, i);
1138             goto gw_err;
1139         }
1140         if (VAL_NULL(ROW_VALUES(row) + 9)) {
1141             hostname_len = 0;
1142             hostname = (char *)0;
1143         } else {
1144             if (VAL_TYPE(ROW_VALUES(row) + 9) != DB1_STRING) {
1145                 LM_ERR("hostname of gw <%s> at row <%u> is not string\n",
1146                        ip_string, i);
1147                 goto gw_err;
1148             }
1149             hostname = (char *)VAL_STRING(ROW_VALUES(row) + 9);
1150             hostname_len = strlen(hostname);
1151         }
1152         if (hostname_len > MAX_HOST_LEN) {
1153             LM_ERR("hostname length <%u> of gw <%s> at row <%u> it too large\n",
1154                    hostname_len, ip_string, i);
1155             goto gw_err;
1156         }
1157         if (VAL_NULL(ROW_VALUES(row) + 10)) {
1158             defunct_until = 0;
1159         } else {
1160             if (VAL_TYPE(ROW_VALUES(row) + 10) != DB1_INT) {
1161                 LM_ERR("defunct of gw <%s> at row <%u> is not int\n",
1162                        ip_string, i);
1163                 goto gw_err;
1164             }
1165             defunct_until = (unsigned int)VAL_INT(ROW_VALUES(row) + 10);
1166         }
1167         if (!insert_gw(gws, i + 1, (unsigned int)ip_addr.s_addr, 
1168                        hostname, hostname_len, grp_id,
1169                        ip_string, port, scheme, transport, flags, strip,
1170                        tag, tag_len, weight, defunct_until)) {
1171             goto gw_err;
1172         }
1173     }
1174
1175     lcr_dbf.free_result(dbh, res);
1176     res = NULL;
1177     
1178     gw_cnt = i;
1179
1180     qsort(&(gws[1]), gw_cnt, sizeof(struct gw_info), comp_gw_grps);
1181     gws[0].ip_addr = gw_cnt;
1182     gws[gw_cnt + 1].ip_addr = 0;
1183     link_gw_grps(gws, gw_grps, &grp_cnt);
1184
1185     for (i = 0; i < grp_cnt; i++) {
1186         LM_DBG("lcr_id %u: gw_grps[%d].grp_id <%d>, gw_grps[%d].first <%d>\n",
1187                lcr_id, i, gw_grps[i].grp_id, i, gw_grps[i].first);
1188     }
1189
1190     /* Reload lcrs */
1191
1192     lcrs = lcrtp[0];
1193
1194     lcr_hash_table_contents_free(lcrs);
1195
1196     if (lcr_dbf.use_table(dbh, &lcr_table) < 0) {
1197         LM_ERR("error while trying to use lcr table\n");
1198         return -1;
1199     }
1200
1201     if (DB_CAPABILITY(lcr_dbf, DB_CAP_FETCH)) {
1202         if (lcr_dbf.query(dbh, key_cols, op, vals, lcr_cols, 1, 4, 0, 0) < 0) {
1203             LM_ERR("db query on lcr table failed\n");
1204             lcr_dbf.close(dbh);
1205             return -1;
1206         }
1207         if (lcr_dbf.fetch_result(dbh, &res, fetch_rows_param) < 0) {
1208             LM_ERR("failed to fetch rows from lcr table\n");
1209             lcr_dbf.close(dbh);
1210             return -1;
1211         }
1212     } else {
1213         if (lcr_dbf.query(dbh, key_cols, op, vals, lcr_cols, 1, 4, 0, &res)
1214             < 0) {
1215             LM_ERR("db query on lcr table failed\n");
1216             lcr_dbf.close(dbh);
1217             return -1;
1218         }
1219     }
1220
1221     n = 0;
1222     from_uri_re = 0;
1223     
1224     do {
1225         LM_DBG("loading, cycle %d with <%d> rows", n++, RES_ROW_N(res));
1226         for (i = 0; i < RES_ROW_N(res); i++) {
1227             from_uri_re = 0;
1228             row = RES_ROWS(res) + i;
1229             if (VAL_NULL(ROW_VALUES(row)) == 1) {
1230                 prefix_len = 0;
1231                 prefix = 0;
1232             } else {
1233                 if (VAL_TYPE(ROW_VALUES(row)) != DB1_STRING) {
1234                     LM_ERR("lcr prefix at row <%u> is not string\n", i);
1235                     goto lcr_err;
1236                 }
1237                 prefix = (char *)VAL_STRING(ROW_VALUES(row));
1238                 prefix_len = strlen(prefix);
1239             }
1240             if (prefix_len > MAX_PREFIX_LEN) {
1241                 LM_ERR("length <%u> of lcr prefix at row <%u> is too large\n",
1242                        prefix_len, i);
1243                 goto lcr_err;
1244             }
1245             if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
1246                 from_uri_len = 0;
1247                 from_uri = 0;
1248             } else {
1249                 if (VAL_TYPE(ROW_VALUES(row) + 1) != DB1_STRING) {
1250                     LM_ERR("lcr from_uri at row <%u> is not string\n", i);
1251                     goto lcr_err;
1252                 }
1253                 from_uri = (char *)VAL_STRING(ROW_VALUES(row) + 1);
1254                 from_uri_len = strlen(from_uri);
1255             }
1256             if (from_uri_len > MAX_URI_LEN) {
1257                 LM_ERR("length <%u> of lcr from_uri at row <%u> is too large\n",
1258                        from_uri_len, i);
1259                 goto lcr_err;
1260             }
1261             if (from_uri_len > 0) {
1262                 from_uri_re = reg_ex_comp(from_uri);
1263                 if (from_uri_re == 0) {
1264                     LM_ERR("failed to compile lcr from_uri <%s> at row <%u>\n",
1265                            from_uri, i);
1266                     goto lcr_err;
1267                 }
1268             } else {
1269                 from_uri_re = 0;
1270             }
1271             if ((VAL_NULL(ROW_VALUES(row) + 2) == 1) ||
1272                 (VAL_TYPE(ROW_VALUES(row) + 2) != DB1_INT)) {
1273                 LM_ERR("lcr grp_id at row <%u> is null or not int\n", i);
1274                 goto lcr_err;
1275             }
1276             grp_id = (unsigned int)VAL_INT(ROW_VALUES(row) + 2);
1277             first_gw = find_first_gw(gw_grps, grp_cnt, grp_id);
1278             if (first_gw == 0) {
1279                 LM_ERR("gw grp_id <%u> of prefix <%.*s> has no gateways\n",
1280                        grp_id, (int)prefix_len, prefix);
1281                 goto lcr_err;
1282             }
1283             if ((VAL_NULL(ROW_VALUES(row) + 3) == 1) ||
1284                 (VAL_TYPE(ROW_VALUES(row) + 3) != DB1_INT)) {
1285                 LM_ERR("lcr priority at row <%u> is null or not int\n", i);
1286                 goto lcr_err;
1287             }
1288             priority = (unsigned int)VAL_INT(ROW_VALUES(row) + 3);
1289
1290             if (!lcr_hash_table_insert(lcrs, prefix_len, prefix,
1291                                        from_uri_len, from_uri, from_uri_re,
1292                                        grp_id, first_gw, priority) ||
1293                 !prefix_len_insert(lcrs, prefix_len)) {
1294                 lcr_hash_table_contents_free(lcrs);
1295                 goto lcr_err;
1296             }
1297         }
1298         if (DB_CAPABILITY(lcr_dbf, DB_CAP_FETCH)) {
1299             if (lcr_dbf.fetch_result(dbh, &res, fetch_rows_param) < 0) {
1300                 LM_ERR("fetching of rows from lcr table failed\n");
1301                 goto lcr_err;
1302             }
1303         } else {
1304             break;
1305         }
1306     } while (RES_ROW_N(res) > 0);
1307
1308     lcr_dbf.free_result(dbh, res);
1309     lcr_dbf.close(dbh);
1310
1311     /* Swap gw and lcr hash table with index id with temporary table */  
1312     gwtp_tmp = gwtp[lcr_id];
1313     lcrtp_tmp = lcrtp[lcr_id];
1314     gwtp[lcr_id] = gwtp[0];
1315     lcrtp[lcr_id] = lcrtp[0];
1316     gwtp[0] = gwtp_tmp;
1317     lcrtp[0] = lcrtp_tmp;
1318
1319     return 1;
1320
1321  lcr_err:
1322     if (from_uri_re) shm_free(from_uri_re);
1323
1324  gw_err:
1325     lcr_dbf.free_result(dbh, res);
1326     lcr_dbf.close(dbh);
1327     return -1;
1328 }
1329
1330
1331 /* Print gateways from gws table */
1332 int mi_print_gws(struct mi_node* rpl)
1333 {
1334     unsigned int i, j;
1335     struct mi_attr* attr;
1336     uri_transport transport;
1337     char *transp;
1338     struct mi_node* node;
1339     struct ip_addr address;
1340     char* p;
1341     int len;
1342     struct gw_info *gws;
1343
1344     for (j = 1; j <= lcr_count; j++) {
1345
1346         gws = gwtp[j];
1347
1348         for (i = 1; i <= gws->ip_addr; i++) {
1349
1350             node = add_mi_node_child(rpl,0 ,"GW", 2, 0, 0);
1351             if (node == NULL) goto err;
1352
1353             p = int2str(j, &len );
1354             attr = add_mi_attr(node, MI_DUP_VALUE, "LCR_ID", 6, p, len );
1355             if (attr == NULL) goto err;
1356
1357             p = int2str((unsigned long)gws[i].grp_id, &len );
1358             attr = add_mi_attr(node, MI_DUP_VALUE, "GRP_ID", 6, p, len );
1359             if (attr == NULL) goto err;
1360
1361             address.af = AF_INET;
1362             address.len = 4;
1363             address.u.addr32[0] = gws[i].ip_addr;
1364             attr = addf_mi_attr(node, 0, "IP_ADDR", 6, "%s",
1365                                 ip_addr2a(&address));
1366             if (attr == NULL) goto err;
1367
1368             attr = add_mi_attr(node, MI_DUP_VALUE, "HOSTNAME", 8,
1369                                gws[i].hostname, gws[i].hostname_len );
1370             if (attr == NULL) goto err;
1371
1372             if (gws[i].port > 0) {
1373                 p = int2str((unsigned long)gws[i].port, &len );
1374                 attr = add_mi_attr(node, MI_DUP_VALUE, "PORT", 4, p, len);
1375             } else {
1376                 attr = add_mi_attr(node, MI_DUP_VALUE, "PORT", 4, (char *)0, 0);
1377             }       
1378             if (attr == NULL) goto err;
1379
1380             if (gws[i].scheme == SIP_URI_T) {
1381                 attr = add_mi_attr(node, MI_DUP_VALUE, "SCHEME", 6, "sip", 3);
1382             } else {
1383                 attr = add_mi_attr(node, MI_DUP_VALUE, "SCHEME", 6, "sips", 4);
1384             }
1385             if (attr == NULL) goto err;
1386
1387             transport = gws[i].transport;
1388             switch (transport) {
1389             case PROTO_UDP:
1390                 transp= "udp";
1391                 break;
1392             case PROTO_TCP:
1393                 transp= "tcp";
1394                 break;
1395             case PROTO_TLS:
1396                 transp= "tls";
1397                 break;
1398             case PROTO_SCTP:
1399                 transp= "sctp";
1400                 break;
1401             default:
1402                 transp = "";
1403             }
1404             attr = add_mi_attr(node, MI_DUP_VALUE, "TRANSPORT", 9,
1405                                transp, strlen(transp));
1406             if (attr == NULL) goto err;
1407             
1408             p = int2str((unsigned long)gws[i].strip, &len);
1409             attr = add_mi_attr(node, MI_DUP_VALUE, "STRIP", 5, p, len);
1410             if (attr == NULL) goto err;
1411             
1412             attr = add_mi_attr(node, MI_DUP_VALUE, "TAG", 3,
1413                                gws[i].tag, gws[i].tag_len);
1414             if (attr == NULL) goto err;
1415
1416             p = int2str((unsigned long)gws[i].weight, &len);
1417             attr = add_mi_attr(node, MI_DUP_VALUE, "WEIGHT", 6, p, len);
1418             if (attr == NULL) goto err;
1419             
1420             p = int2str((unsigned long)gws[i].flags, &len);
1421             attr = add_mi_attr(node, MI_DUP_VALUE, "FLAGS", 5, p, len);
1422             if (attr == NULL) goto err;
1423             
1424             p = int2str((unsigned long)gws[i].defunct_until, &len);
1425             attr = add_mi_attr(node, MI_DUP_VALUE, "DEFUNCT_UNTIL", 13, p, len);
1426             if (attr == NULL) goto err;
1427         }
1428     }
1429
1430     return 0;
1431
1432  err:
1433     return -1;
1434 }
1435
1436 /* Print lcrs from lcrs table */
1437 int mi_print_lcrs(struct mi_node* rpl)
1438 {
1439     unsigned int i, j;
1440     struct mi_attr* attr;
1441     struct mi_node* node;
1442     char* p;
1443     int len;
1444     struct lcr_info **lcrs, *lcr_rec;
1445
1446     for (j = 1; j <= lcr_count; j++) {
1447
1448         lcrs = lcrtp[j];
1449
1450         for (i = 0; i < lcr_hash_size_param; i++) {
1451
1452             lcr_rec = lcrs[i];
1453
1454             while (lcr_rec) {
1455
1456                 node = add_mi_node_child(rpl, 0, "RULE", 4, 0, 0);
1457                 if (node == NULL) goto err;
1458
1459                 p = int2str(j, &len );
1460                 attr = add_mi_attr(node, MI_DUP_VALUE, "LCR_ID", 6, p, len );
1461                 if (attr == NULL) goto err;
1462
1463                 attr = add_mi_attr(node, 0, "PREFIX", 6, lcr_rec->prefix,
1464                                    lcr_rec->prefix_len);
1465                 if (attr == NULL) goto err;
1466                 
1467                 attr = add_mi_attr(node, 0, "FROM_URI", 8, lcr_rec->from_uri,
1468                                    lcr_rec->from_uri_len);
1469                 if (attr == NULL) goto err;
1470         
1471                 p = int2str((unsigned long)lcr_rec->grp_id, &len );
1472                 attr = add_mi_attr(node, MI_DUP_VALUE, "GRP_ID", 6, p, len);
1473                 if (attr == NULL) goto err;
1474
1475                 p = int2str((unsigned long)lcr_rec->priority, &len);
1476                 attr = add_mi_attr(node, MI_DUP_VALUE, "PRIORITY", 8, p, len);
1477                 if (attr == NULL) goto err;
1478
1479                 lcr_rec = lcr_rec->next;
1480             }
1481         }
1482
1483         lcr_rec = lcrs[lcr_hash_size_param];
1484
1485         while (lcr_rec) {
1486
1487             node = add_mi_node_child(rpl, 0, "PREFIX_LENS", 11, 0, 0);
1488             if (node == NULL) goto err;
1489
1490             p = int2str((unsigned long)lcr_rec->prefix_len, &len );
1491             attr = add_mi_attr(node, MI_DUP_VALUE, "PREFIX_LEN", 10, p, len);
1492             if (attr == NULL) goto err;
1493
1494             lcr_rec = lcr_rec->next;
1495         }
1496     }
1497
1498     return 0;
1499
1500  err:
1501     return -1;
1502 }
1503
1504 inline int encode_avp_value(char *value, uri_type scheme, unsigned int strip,
1505                             char *tag, unsigned int tag_len,
1506                             unsigned int ip_addr, char *hostname,
1507                             unsigned int hostname_len, unsigned int port,
1508                             uri_transport transport, unsigned int flags)
1509 {
1510     char *at, *string;
1511     int len;
1512     
1513     /* scheme */
1514     at = value;
1515     string = int2str(scheme, &len);
1516     append_str(at, string, len);
1517     append_chr(at, '|');
1518     /* strip */
1519     string = int2str(strip, &len);
1520     append_str(at, string, len);
1521     append_chr(at, '|');
1522     /* tag */
1523     append_str(at, tag, tag_len);
1524     append_chr(at, '|');
1525     /* ip_addr */
1526     string = int2str(ip_addr, &len);
1527     append_str(at, string, len);
1528     append_chr(at, '|');
1529     /* hostname */
1530     append_str(at, hostname, hostname_len);
1531     append_chr(at, '|');
1532     /* port */
1533     string = int2str(port, &len);
1534     append_str(at, string, len);
1535     append_chr(at, '|');
1536     /* transport */
1537     string = int2str(transport, &len);
1538     append_str(at, string, len);
1539     append_chr(at, '|');
1540     /* flags */
1541     string = int2str(flags, &len);
1542     append_str(at, string, len);
1543     return at - value;
1544 }
1545
1546 inline int decode_avp_value(char *value, str *scheme, unsigned int *strip,
1547                             str *tag, unsigned int *addr, str *hostname,
1548                             str *port, str *transport, unsigned int *flags)
1549 {
1550     unsigned int u;
1551     str s;
1552     char *sep;
1553
1554     /* scheme */
1555     s.s = value;
1556     sep = index(s.s, '|');
1557     if (sep == NULL) {
1558         LM_ERR("scheme was not found in AVP value\n");
1559         return 0;
1560     }
1561     s.len = sep - s.s;
1562     str2int(&s, &u);
1563     if (u == SIP_URI_T) {
1564         scheme->s = "sip:";
1565         scheme->len = 4;
1566     } else {
1567         scheme->s = "sips:";
1568         scheme->len = 5;
1569     }
1570     /* strip */
1571     s.s = sep + 1;
1572     sep = index(s.s, '|');
1573     if (sep == NULL) {
1574         LM_ERR("strip was not found in AVP value\n");
1575         return 0;
1576     }
1577     s.len = sep - s.s;
1578     str2int(&s, strip);
1579     /* tag */
1580     tag->s = sep + 1;
1581     sep = index(tag->s, '|');
1582     if (sep == NULL) {
1583         LM_ERR("tag was not found in AVP value\n");
1584         return 0;
1585     }
1586     tag->len = sep - tag->s;
1587     /* addr */
1588     s.s = sep + 1;
1589     sep = index(s.s, '|');
1590     if (sep == NULL) {
1591         LM_ERR("ip_addr was not found in AVP value\n");
1592         return 0;
1593     }
1594     s.len = sep - s.s;
1595     str2int(&s, addr);
1596     /* hostname */
1597     hostname->s = sep + 1;
1598     sep = index(hostname->s, '|');
1599     if (sep == NULL) {
1600         LM_ERR("hostname was not found in AVP value\n");
1601         return 0;
1602     }
1603     hostname->len = sep - hostname->s;
1604     /* port */
1605     port->s = sep + 1;
1606     sep = index(port->s, '|');
1607     if (sep == NULL) {
1608         LM_ERR("scheme was not found in AVP value\n");
1609         return 0;
1610     }
1611     port->len = sep - port->s;
1612     /* transport */
1613     s.s = sep + 1;
1614     sep = index(s.s, '|');
1615     if (sep == NULL) {
1616         LM_ERR("transport was not found in AVP value\n");
1617         return 0;
1618     }
1619     s.len = sep - s.s;
1620     str2int(&s, &u);
1621     switch (u) {
1622     case PROTO_NONE:
1623     case PROTO_UDP:
1624         transport->s = (char *)0;
1625         transport->len = 0;
1626         break;
1627     case PROTO_TCP:
1628         transport->s = ";transport=tcp";
1629         transport->len = 14;
1630         break;
1631     case PROTO_TLS:
1632         transport->s = ";transport=tls";
1633         transport->len = 14;
1634     default:
1635         transport->s = ";transport=sctp";
1636         transport->len = 15;
1637         break;
1638     }
1639     /* flags */
1640     s.s = sep + 1;
1641     s.len = strlen(s.s);
1642     str2int(&s, flags);
1643
1644     return 1;
1645 }
1646     
1647
1648 /* Add gateways in matched_gws array into gw_uri_avps */
1649 void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws,
1650                        unsigned int gw_cnt, str *ruri_user)
1651 {
1652     unsigned int i, index, strip, hostname_len;
1653     int tag_len;
1654     str value;
1655     char encoded_value[MAX_URI_LEN];
1656     int_str val;
1657
1658     delete_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp);
1659
1660     for (i = 0; i < gw_cnt; i++) {
1661         if (matched_gws[i].duplicate == 1) continue;
1662         index = matched_gws[i].gw_index;
1663         hostname_len = gws[index].hostname_len;
1664         strip = gws[index].strip;
1665         if (strip > ruri_user->len) {
1666             LM_ERR("strip count of gw is too large <%u>\n", strip);
1667             goto skip;
1668         }
1669         tag_len = gws[index].tag_len;
1670         if (5 /* scheme */ + 4 /* strip */ + tag_len + 1 /* @ */ +
1671             ((hostname_len > 15)?hostname_len:15) + 6 /* port */ +
1672             15 /* transport */ + 10 /* flags */ + 7 /* separators */
1673             > MAX_URI_LEN) {
1674             LM_ERR("too long AVP value\n");
1675             goto skip;
1676         }
1677         value.len = 
1678             encode_avp_value(encoded_value, gws[index].scheme, strip,
1679                              gws[index].tag, tag_len, gws[index].ip_addr,
1680                              gws[index].hostname, hostname_len,
1681                              gws[index].port, gws[index].transport,
1682                              gws[index].flags);
1683         value.s = (char *)&(encoded_value[0]);
1684         val.s = value;
1685         add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val);
1686
1687         LM_DBG("added gw_uri_avp <%.*s> with weight <%u>\n",
1688                value.len, value.s, matched_gws[i].weight);
1689     skip:
1690         continue;
1691     }
1692 }
1693
1694
1695 /*
1696  * Load info of matching GWs into gw_uri_avps
1697  */
1698 static int load_gws(struct sip_msg* _m, char *_lcr_id, char *_from_uri)
1699 {
1700     str ruri_user, from_uri;
1701     int i, j, lcr_id;
1702     unsigned int gw_index, gw_count, now, ip_addr;
1703     int_str val;
1704     struct matched_gw_info matched_gws[MAX_NO_OF_GWS + 1];
1705     struct lcr_info **lcrs, *lcr_rec, *pl;
1706     struct gw_info *gws;
1707
1708     /* Get and check parameter values */
1709     if (get_int_fparam(&lcr_id, _m, (fparam_t *)_lcr_id) != 0) {
1710         LM_ERR("no lcr_id param value\n");
1711         return -1;
1712     }
1713     if ((lcr_id < 1) || (lcr_id > lcr_count)) {
1714         LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
1715         return -1;
1716     }
1717
1718     if (get_str_fparam(&from_uri, _m, (fparam_t *)_from_uri) != 0) {
1719         LM_ERR("no from_uri parameter value\n");
1720         return -1;
1721     }
1722     if (from_uri.len == 0) {
1723         LM_ERR("empry from_uri param value\n");
1724         return -1;
1725     }
1726
1727     /* Use gws and lcr rules with index lcr_id */
1728     gws = gwtp[lcr_id];
1729     lcrs = lcrtp[lcr_id];
1730
1731     /* Find Request-URI user */
1732     if ((parse_sip_msg_uri(_m) < 0) || (!_m->parsed_uri.user.s)) {
1733         LM_ERR("error while parsing R-URI\n");
1734         return -1;
1735     }
1736     ruri_user = _m->parsed_uri.user;
1737
1738     /*
1739      * Find lcr entries that match based on prefix and from_uri and collect
1740      * gateways of matching entries into matched_gws array so that each
1741      * gateway appears in the array only once.
1742      */
1743
1744     pl = lcrs[lcr_hash_size_param];
1745     gw_index = 0;
1746     gw_count = gws[0].ip_addr;
1747
1748     if (defunct_capability > 0) {
1749         now = time((time_t *)NULL);
1750         delete_avp(defunct_gw_avp_type, defunct_gw_avp);
1751     } else {
1752         now = MAX_UVAR_VALUE(now);
1753     }
1754
1755     while (pl) {
1756         if (ruri_user.len < pl->prefix_len) {
1757             pl = pl->next;
1758             continue;
1759         }
1760         lcr_rec = lcr_hash_table_lookup(lcrs, pl->prefix_len, ruri_user.s);
1761         while (lcr_rec) {
1762             /* Match prefix */
1763             if ((lcr_rec->prefix_len == pl->prefix_len) && 
1764                 (strncmp(lcr_rec->prefix, ruri_user.s, pl->prefix_len) == 0)) {
1765                 /* Match from uri */
1766                 if ((lcr_rec->from_uri_len == 0) ||
1767                     (pcre_exec(lcr_rec->from_uri_re, NULL, from_uri.s,
1768                                from_uri.len, 0, 0, NULL, 0) >= 0)) {
1769                     /* Load unique gws of the group of this lcr entry */
1770                     j = lcr_rec->first_gw;
1771                     while (j) {
1772                         /* If this gw is defunct, skip it */
1773                         if (gws[j].defunct_until > now) goto gw_found;
1774                         matched_gws[gw_index].gw_index = j;
1775                         matched_gws[gw_index].prefix_len = pl->prefix_len;
1776                         matched_gws[gw_index].priority = lcr_rec->priority;
1777                         matched_gws[gw_index].weight = gws[j].weight *
1778                             (rand() >> 8);
1779                         matched_gws[gw_index].duplicate = 0;
1780                         LM_DBG("added matched_gws[%d]=[%u, %u, %u, %u]\n",
1781                                gw_index, j, pl->prefix_len, lcr_rec->priority,
1782                                matched_gws[gw_index].weight);
1783                         gw_index++;
1784                     gw_found:
1785                         j = gws[j].next;
1786                     }
1787                 }
1788             }
1789             lcr_rec = lcr_rec->next;
1790         }
1791         pl = pl->next;
1792     }
1793
1794     /* Sort gateways in reverse order based on prefix_len, priority,
1795        and randomized weight */
1796     qsort(matched_gws, gw_index, sizeof(struct matched_gw_info), comp_matched);
1797
1798     /* Remove duplicate gws */
1799     for (i = gw_index - 1; i >= 0; i--) {
1800         if (matched_gws[i].duplicate == 1) continue;
1801         ip_addr = gws[matched_gws[i].gw_index].ip_addr;
1802         for (j = i - 1; j >= 0; j--) {
1803             if (gws[matched_gws[j].gw_index].ip_addr == ip_addr) {
1804                 matched_gws[j].duplicate = 1;
1805             }
1806         }
1807     }
1808
1809     /* Add gateways into gw_uris_avp */
1810     add_gws_into_avps(gws, matched_gws, gw_index, &ruri_user);
1811
1812     /* Add lcr_id into AVP */
1813     if (defunct_capability > 0) {
1814         delete_avp(lcr_id_avp_type, lcr_id_avp);
1815         val.n = lcr_id;
1816         add_avp(lcr_id_avp_type, lcr_id_avp, val);
1817     }
1818     
1819     return 1;
1820 }
1821
1822
1823 /* Generate Request-URI and Destination URI */
1824 static int generate_uris(char *r_uri, str *r_uri_user, unsigned int *r_uri_len,
1825                          char *dst_uri, unsigned int *dst_uri_len,
1826                          unsigned int *addr, unsigned int *flags)
1827 {
1828     int_str gw_uri_val;
1829     struct usr_avp *gu_avp;
1830     str scheme, tag, hostname, port, transport, addr_str;
1831     char *at;
1832     unsigned int strip;
1833     struct ip_addr a;
1834     
1835     gu_avp = search_first_avp(gw_uri_avp_type, gw_uri_avp, &gw_uri_val, 0);
1836
1837     if (!gu_avp) return 0; /* No more gateways left */
1838
1839     decode_avp_value(gw_uri_val.s.s, &scheme, &strip, &tag, addr,
1840                      &hostname, &port, &transport, flags);
1841
1842     a.af = AF_INET;
1843     a.len = 4;
1844     a.u.addr32[0] = *addr;
1845     addr_str.s = ip_addr2a(&a);
1846     addr_str.len = strlen(addr_str.s);
1847     
1848     if (scheme.len + r_uri_user->len - strip + tag.len + 1 /* @ */ +
1849         ((hostname.len > 15)?hostname.len:15) + 1 /* : */ +
1850         port.len + transport.len + 1 /* null */ > MAX_URI_LEN) {
1851         LM_ERR("too long Request URI or DST URI\n");
1852         return -1;
1853     }
1854
1855     at = r_uri;
1856     
1857     append_str(at, scheme.s, scheme.len);
1858     append_str(at, tag.s, tag.len);
1859         
1860     if (strip > r_uri_user->len) {
1861         LM_ERR("strip count <%u> is larger than R-URI user <%.*s>\n",
1862                strip, r_uri_user->len, r_uri_user->s);
1863         return -1;
1864     }
1865     append_str(at, r_uri_user->s + strip, r_uri_user->len - strip);
1866
1867     append_chr(at, '@');
1868         
1869     if (hostname.len == 0) {
1870         append_str(at, addr_str.s, addr_str.len);
1871         if (port.len > 0) {
1872             append_chr(at, ':');
1873             append_str(at, port.s, port.len);
1874         }
1875         if (transport.len > 0) {
1876             append_str(at, transport.s, transport.len);
1877         }
1878         *at = '\0';
1879         *r_uri_len = at - r_uri;
1880         *dst_uri_len = 0;
1881     } else {
1882         append_str(at, hostname.s, hostname.len);
1883         *at = '\0';
1884         *r_uri_len = at - r_uri;
1885         at = dst_uri;
1886         append_str(at, scheme.s, scheme.len);
1887         append_str(at, addr_str.s, addr_str.len);
1888         if (port.len > 0) {
1889             append_chr(at, ':');
1890             append_str(at, port.s, port.len);
1891         }
1892         if (transport.len > 0) {
1893             append_str(at, transport.s, transport.len);
1894         }
1895         *at = '\0';
1896         *dst_uri_len = at - dst_uri;
1897     }
1898
1899     destroy_avp(gu_avp);
1900         
1901     LM_DBG("r_uri <%.*s>, dst_uri <%.*s>\n",
1902            (int)*r_uri_len, r_uri, (int)*dst_uri_len, dst_uri);
1903
1904     return 1;
1905 }
1906
1907
1908 /*
1909  * Defunct current gw until time given as argument has passed.
1910  */
1911 static int defunct_gw(struct sip_msg* _m, char *_defunct_period, char *_s2)
1912 {
1913     int_str lcr_id_val, ip_addr_val;
1914     struct gw_info *gws, *res, *gw;
1915     unsigned int ip_addr, defunct_until;
1916     int defunct_period;
1917
1918     /* Check defunct gw capability */
1919     if (defunct_capability == 0) {
1920         LM_ERR("no defunct gw capability, activate by setting "
1921                "defunct_capability module param\n");
1922         return -1;
1923     }
1924
1925     /* Get parameter value */
1926     if (get_int_fparam(&defunct_period, _m, (fparam_t *)_defunct_period) != 0) {
1927         LM_ERR("no defunct_period param value\n");
1928         return -1;
1929     }
1930     if (defunct_period < 1) {
1931         LM_ERR("invalid defunct_period param value\n");
1932         return -1;
1933     }
1934
1935     /* Get AVP values */
1936     if (search_first_avp(lcr_id_avp_type, lcr_id_avp, &lcr_id_val, 0)
1937         == NULL) {
1938         LM_ERR("lcr_id_avp was not found\n");
1939         return -1;
1940     }
1941     if (search_first_avp(defunct_gw_avp_type, defunct_gw_avp,
1942                          &ip_addr_val, 0) == NULL) {
1943         LM_ERR("defucnt_gw_avp was not found\n");
1944         return -1;
1945     }
1946     ip_addr = ip_addr_val.n;
1947     
1948     /* Use gws with index lcr_id */
1949     gws = gwtp[lcr_id_val.n];
1950
1951     /* Search for gw address */
1952     res = (struct gw_info *)bsearch(&ip_addr, &(gws[1]), gws[0].ip_addr,
1953                                     sizeof(struct gw_info), comp_gws);
1954     if (res == NULL) return 1;
1955
1956     /* Defunct gw(s) */
1957     defunct_until = time((time_t *)NULL) + defunct_period;
1958     LM_DBG("defuncting gw %u in grp %u\n", res->ip_addr, res->grp_id);
1959     res->defunct_until = defunct_until;
1960     gw = res - 1;
1961     while (gw->ip_addr == ip_addr) {
1962         LM_DBG("defuncting gw %u in grp %u\n", gw->ip_addr, gw->grp_id);
1963         gw->defunct_until = defunct_until;
1964         gw = gw - 1;
1965     }
1966     gw = res + 1;
1967     while (gw->ip_addr == ip_addr) {
1968         LM_DBG("defuncting gw %u in grp %u\n", gw->ip_addr, gw->grp_id);
1969         gw->defunct_until = defunct_until;
1970         gw = gw + 1;
1971     }
1972
1973     return 1;
1974 }    
1975
1976
1977 /*
1978  * When called first time in route block, rewrites scheme, host, port, and
1979  * transport parts of R-URI based on first gw_uri_avp value, which is then
1980  * destroyed.  Saves R-URI user to ruri_user_avp for later use.
1981  *
1982  * On other calls appends a new branch to request, where scheme, host, port,
1983  * and transport of URI are taken from the first gw_uri_avp value, 
1984  * which is then destroyed. URI user is taken either from R-URI (first
1985  * call in failure route block) or from ruri_user_avp value saved earlier.
1986  *
1987  * Returns 1 upon success and -1 upon failure.
1988  */
1989 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2)
1990 {
1991     int_str ruri_user_val, val;
1992     struct action act;
1993     struct run_act_ctx ra_ctx;
1994     struct usr_avp *ru_avp;
1995     int rval;
1996     str uri_str;
1997     unsigned int flags, r_uri_len, dst_uri_len, addr;
1998     char r_uri[MAX_URI_LEN], dst_uri[MAX_URI_LEN];
1999
2000     ru_avp = search_first_avp(ruri_user_avp_type, ruri_user_avp,
2001                               &ruri_user_val, 0);
2002     
2003     if (ru_avp == NULL) {
2004         
2005         /* First invocation either in route or failure route block.
2006          * Take Request-URI user from Request-URI and generate Request
2007          * and Destination URIs. */
2008         if (parse_sip_msg_uri(_m) < 0) {
2009             LM_ERR("parsing of R-URI failed\n");
2010             return -1;
2011         }
2012         if (generate_uris(r_uri, &(_m->parsed_uri.user), &r_uri_len, dst_uri,
2013                           &dst_uri_len, &addr, &flags) != 1) {
2014             return -1;
2015         }
2016
2017         /* Save Request-URI user into uri_user_avp for use in subsequent
2018          * invocations. */
2019         val.s = _m->parsed_uri.user;
2020         add_avp(ruri_user_avp_type|AVP_VAL_STR, ruri_user_avp, val);
2021         LM_DBG("added ruri_user_avp <%.*s>\n", val.s.len, val.s.s);
2022
2023     } else {
2024
2025         /* Subsequent invocation either in route or failure route block. */
2026
2027         /* Take Request-URI user from ruri_user_avp and generate Request
2028          * and Destination URIs. */
2029         if (generate_uris(r_uri, &(ruri_user_val.s), &r_uri_len, dst_uri,
2030                           &dst_uri_len, &addr, &flags) != 1) {
2031             return -1;
2032         }
2033     }
2034
2035     if ((route_type == REQUEST_ROUTE) && (ru_avp == NULL)) {
2036
2037         /* First invocation in route block => Rewrite Request URI. */
2038         memset(&act, '\0', sizeof(act));
2039         act.type = SET_URI_T;
2040         act.val[0].type = STRING_ST;
2041         act.val[0].u.string = r_uri;
2042         init_run_actions_ctx(&ra_ctx);
2043         rval = do_action(&ra_ctx, &act, _m);
2044         if (rval != 1) {
2045             LM_ERR("do_action failed with return value <%d>\n", rval);
2046             return -1;
2047         }
2048
2049     } else {
2050         
2051         /* Subsequent invocation in route block or any invocation in
2052          * failure route block => append new branch. */
2053         uri_str.s = r_uri;
2054         uri_str.len = r_uri_len;
2055         LM_DBG("appending branch <%.*s>\n", uri_str.len, uri_str.s);
2056         if (append_branch(_m, &uri_str, 0, 0, Q_UNSPECIFIED, 0, 0) == -1) {
2057             LM_ERR("when appending branch <%.*s>\n", rval);
2058             return -1;
2059         }
2060     }
2061     
2062     /* Set Destination URI if not empty */
2063     if (dst_uri_len > 0) {
2064         uri_str.s = dst_uri;
2065         uri_str.len = dst_uri_len;
2066         rval = set_dst_uri(_m, &uri_str);
2067         if (rval != 0) {
2068             LM_ERR("calling do_action failed with return value <%d>\n", rval);
2069             return -1;
2070         }
2071         
2072     }
2073
2074     /* Set flags_avp */
2075     val.n = flags;
2076     add_avp(flags_avp_type, flags_avp, val);
2077     LM_DBG("added flags_avp <%u>\n", (unsigned int)val.n);
2078
2079     /* Add IP addr of selected gw to defunct gw AVP */
2080     if (defunct_capability > 0) {
2081         delete_avp(defunct_gw_avp_type, defunct_gw_avp);
2082         val.n = addr;
2083         add_avp(defunct_gw_avp_type, defunct_gw_avp, val);
2084         LM_DBG("added defunct_gw_avp <%u>", addr);
2085     }
2086     
2087     return 1;
2088 }
2089
2090
2091 /*
2092  * Checks if request comes from a gateway
2093  */
2094 static int do_from_gw(struct sip_msg* _m, unsigned int lcr_id,
2095                       unsigned int src_addr)
2096 {
2097     struct gw_info *res, *gws;
2098     int_str val;
2099         
2100     /* Use gws with index lcr_id */
2101     gws = gwtp[lcr_id];
2102
2103     /* Search for gw address */
2104     res = (struct gw_info *)bsearch(&src_addr, &(gws[1]), gws[0].ip_addr,
2105                                     sizeof(struct gw_info), comp_gws);
2106
2107     /* Store flags and return result */
2108     if (res == NULL) {
2109         LM_DBG("request did not come from gw\n");
2110         return -1;
2111     } else {
2112         LM_DBG("request game from gw\n");
2113         val.n = res->flags;
2114         add_avp(flags_avp_type, flags_avp, val);
2115         LM_DBG("added flags_avp <%u>\n", (unsigned int)val.n);
2116         return 1;
2117     }
2118 }
2119
2120
2121 /*
2122  * Checks if request comes from a gateway taking src_address from reques.
2123  */
2124 static int from_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2)
2125 {
2126     int lcr_id;
2127     unsigned int src_addr;
2128
2129     /* Get and check parameter value */
2130     if (get_int_fparam(&lcr_id, _m, (fparam_t *)_lcr_id) != 0) {
2131         LM_ERR("no lcr_id param value\n");
2132         return -1;
2133     }
2134     if ((lcr_id < 1) || (lcr_id > lcr_count)) {
2135         LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
2136         return -1;
2137     }
2138
2139     /* Get source address */
2140     src_addr = _m->rcv.src_ip.u.addr32[0];
2141
2142     /* Do test */
2143     return do_from_gw(_m, lcr_id, src_addr);
2144 }
2145
2146
2147 /*
2148  * Checks if request comes from a gateway taking source address from param.
2149  */
2150 static int from_gw_2(struct sip_msg* _m, char* _lcr_id, char* _addr)
2151 {
2152     unsigned int src_addr;
2153     int lcr_id;
2154     pv_value_t pv_val;
2155     struct ip_addr *ip;
2156
2157     /* Get and check parameter values */
2158     if (get_int_fparam(&lcr_id, _m, (fparam_t *)_lcr_id) != 0) {
2159         LM_ERR("no lcr_id param value\n");
2160         return -1;
2161     }
2162     if ((lcr_id < 1) || (lcr_id > lcr_count)) {
2163         LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
2164         return -1;
2165     }
2166
2167     if (_addr && (pv_get_spec_value(_m, (pv_spec_t *)_addr, &pv_val) == 0)) {
2168         if (pv_val.flags & PV_VAL_INT) {
2169             src_addr = pv_val.ri;
2170         } else if (pv_val.flags & PV_VAL_STR) {
2171             if ((ip = str2ip(&pv_val.rs)) == NULL) {
2172                 LM_DBG("request did not come from gw "
2173                        "(addr param value is not an IP address)\n");
2174                 return -1;
2175             } else {
2176                 src_addr = ip->u.addr32[0];
2177             }
2178         } else {
2179             LM_ERR("addr param has no value\n");
2180             return -1;
2181         }
2182     } else {
2183         LM_ERR("could not get source address from param\n");
2184         return -1;
2185     }
2186
2187     /* Do test */
2188     return do_from_gw(_m, lcr_id, src_addr);
2189 }
2190
2191
2192 /*
2193  * Checks if request comes from any gateway taking source address from request.
2194  */
2195 static int from_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
2196 {
2197     unsigned int src_addr, i;
2198
2199     src_addr = _m->rcv.src_ip.u.addr32[0];
2200
2201     for (i = 1; i <= lcr_count; i++) {
2202         if (do_from_gw(_m, i, src_addr) == 1) {
2203             return i;
2204         }
2205     }
2206     return -1;
2207 }
2208
2209
2210 /*
2211  * Checks if request comes from a gateway taking source address from param.
2212  */
2213 static int from_any_gw_1(struct sip_msg* _m, char* _addr, char* _s2)
2214 {
2215     unsigned int i, src_addr;
2216     pv_value_t pv_val;
2217     struct ip_addr *ip;
2218
2219     /* Get parameter value */
2220     if (_addr && (pv_get_spec_value(_m, (pv_spec_t *)_addr, &pv_val) == 0)) {
2221         if (pv_val.flags & PV_VAL_INT) {
2222             src_addr = pv_val.ri;
2223         } else if (pv_val.flags & PV_VAL_STR) {
2224             if ((ip = str2ip(&pv_val.rs)) == NULL) {
2225                 LM_DBG("request did not come from gw "
2226                        "(addr param value is not an IP address)\n");
2227                 return -1;
2228             } else {
2229                 src_addr = ip->u.addr32[0];
2230             }
2231         } else {
2232             LM_ERR("addr param has no value\n");
2233             return -1;
2234         }
2235     } else {
2236         LM_ERR("could not get source address from param\n");
2237         return -1;
2238     }
2239
2240     /* Do test */
2241     for (i = 1; i <= lcr_count; i++) {
2242         if (do_from_gw(_m, i, src_addr) == 1) {
2243             return i;
2244         }
2245     }
2246     return -1;
2247 }
2248
2249
2250 /*
2251  * Checks if in-dialog request goes to gateway
2252  */
2253 static int do_to_gw(struct sip_msg* _m, unsigned int lcr_id,
2254                     unsigned int dst_addr)
2255 {
2256     struct gw_info *res, *gws;
2257
2258     /* Use gws with index lcr_id */
2259     gws = gwtp[lcr_id];
2260
2261     /* Search for gw address */
2262     res = (struct gw_info *)bsearch(&dst_addr, &(gws[1]), gws[0].ip_addr,
2263                                     sizeof(struct gw_info), comp_gws);
2264
2265     /* Return result */
2266     if (res == NULL) {
2267         LM_DBG("request is not going to gw\n");
2268         return -1;
2269     } else {
2270         LM_DBG("request goes to gw\n");
2271         return 1;
2272     }
2273 }
2274
2275
2276 /*
2277  * Checks if request goes to a gateway taking destination address from request.
2278  */
2279 static int to_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2)
2280 {
2281     int lcr_id;
2282     unsigned int dst_addr;
2283     struct ip_addr *ip;
2284
2285     /* Get and check parameter value */
2286     if (get_int_fparam(&lcr_id, _m, (fparam_t *)_lcr_id) != 0) {
2287         LM_ERR("no lcr_id param value\n");
2288         return -1;
2289     }
2290     if ((lcr_id < 1) || (lcr_id > lcr_count)) {
2291         LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
2292         return -1;
2293     }
2294
2295     /* Get destination address */
2296     if ((_m->parsed_uri_ok == 0) && (parse_sip_msg_uri(_m) < 0)) {
2297         LM_ERR("while parsing Request-URI\n");
2298         return -1;
2299     }
2300     if (_m->parsed_uri.host.len > 15) {
2301         LM_DBG("request is not going to gw "
2302                "(Request-URI host is not an IP address)\n");
2303         return -1;
2304     }
2305     if ((ip = str2ip(&(_m->parsed_uri.host))) == NULL) {
2306         LM_DBG("request is not going to gw "
2307                "(Request-URI host is not an IP address)\n");
2308         return -1;
2309     } else {
2310         dst_addr = ip->u.addr32[0];
2311     }
2312
2313     /* Do test */
2314     return do_to_gw(_m, lcr_id, dst_addr);
2315 }
2316
2317
2318 /*
2319  * Checks if request goes to a gateway, taking destination address from param.
2320  */
2321 static int to_gw_2(struct sip_msg* _m, char* _lcr_id, char* _addr)
2322 {
2323     int lcr_id;
2324     unsigned int dst_addr;
2325     pv_value_t pv_val;
2326     struct ip_addr *ip;
2327
2328     /* Get and check parameter values */
2329     if (get_int_fparam(&lcr_id, _m, (fparam_t *)_lcr_id) != 0) {
2330         LM_ERR("no lcr_id param value\n");
2331         return -1;
2332     }
2333     if ((lcr_id < 1) || (lcr_id > lcr_count)) {
2334         LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
2335         return -1;
2336     }
2337
2338     if (_addr && (pv_get_spec_value(_m, (pv_spec_t *)_addr, &pv_val) == 0)) {
2339         if (pv_val.flags & PV_VAL_INT) {
2340             dst_addr = pv_val.ri;
2341         } else if (pv_val.flags & PV_VAL_STR) {
2342             if ((ip = str2ip(&pv_val.rs)) == NULL) {
2343                 LM_DBG("request is not going to gw "
2344                        "(addr param value is not an IP address)\n");
2345                 return -1;
2346             } else {
2347                 dst_addr = ip->u.addr32[0];
2348             }
2349         } else {
2350             LM_ERR("addr param has no value\n");
2351             return -1;
2352         }
2353     } else {
2354         LM_ERR("could not get destination address from param\n");
2355         return -1;
2356     }
2357     
2358     /* Do test */
2359     return do_to_gw(_m, lcr_id, dst_addr);
2360 }
2361
2362
2363 /*
2364  * Checks if request goes to any gateway taking dst_addr from request.
2365  */
2366 static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
2367 {
2368     unsigned int dst_addr, i;
2369     struct ip_addr *ip;
2370
2371     /* Get destination address */
2372     if ((_m->parsed_uri_ok == 0) && (parse_sip_msg_uri(_m) < 0)) {
2373         LM_ERR("while parsing Request-URI\n");
2374         return -1;
2375     }
2376     if (_m->parsed_uri.host.len > 15) {
2377         LM_DBG("request is not going to gw "
2378                "(Request-URI host is not an IP address)\n");
2379         return -1;
2380     }
2381     if ((ip = str2ip(&(_m->parsed_uri.host))) == NULL) {
2382         LM_DBG("request is not going to gw "
2383                "(Request-URI host is not an IP address)\n");
2384         return -1;
2385     } else {
2386         dst_addr = ip->u.addr32[0];
2387     }
2388
2389     for (i = 1; i <= lcr_count; i++) {
2390         if (do_to_gw(_m, i, dst_addr) == 1) {
2391             return i;
2392         }
2393     }
2394     return -1;
2395 }
2396
2397
2398 /*
2399  * Checks if request goes to any gateway taking dst_addr from param.
2400  */
2401 static int to_any_gw_1(struct sip_msg* _m, char* _addr, char* _s2)
2402 {
2403     unsigned int i, dst_addr;
2404     pv_value_t pv_val;
2405     struct ip_addr *ip;
2406
2407     /* Get parameter value */
2408     if (_addr && (pv_get_spec_value(_m, (pv_spec_t *)_addr, &pv_val) == 0)) {
2409         if (pv_val.flags & PV_VAL_INT) {
2410             dst_addr = pv_val.ri;
2411         } else if (pv_val.flags & PV_VAL_STR) {
2412             if ((ip = str2ip(&pv_val.rs)) == NULL) {
2413                 LM_DBG("request did go to any gw "
2414                        "(addr param value is not an IP address)\n");
2415                 return -1;
2416             } else {
2417                 dst_addr = ip->u.addr32[0];
2418             }
2419         } else {
2420             LM_ERR("addr param has no value\n");
2421             return -1;
2422         }
2423     } else {
2424         LM_ERR("could not get destination address from param\n");
2425         return -1;
2426     }
2427
2428     /* Do test */
2429     for (i = 1; i <= lcr_count; i++) {
2430         if (do_to_gw(_m, i, dst_addr) == 1) {
2431             return i;
2432         }
2433     }
2434     return -1;
2435 }