Mon, 16 Jan 2012 22:56:52 +0100
Import original vendor code for correction and improvement.
1 /*
2 * $Id: lcr_mod.c 6015 2009-08-22 21:45:06Z bogdan_iancu $
3 *
4 * Least Cost Routing module (also implements sequential forking)
5 *
6 * Copyright (C) 2005 Juha Heinanen
7 * Copyright (C) 2006 Voice Sistem SRL
8 *
9 * This file is part of opensips, a free SIP server.
10 *
11 * opensips is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version
15 *
16 * opensips is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 * History:
26 * -------
27 * 2005-02-14: Introduced lcr module (jh)
28 * 2005-02-20: Added sequential forking functions (jh)
29 * 2005-02-25: Added support for int AVP names, combined addr and port
30 * AVPs (jh)
31 * 2005-07-28: Added support for gw URI scheme and transport,
32 * backport from ser (kd)
33 * 2005-08-20: Added support for gw prefixes (jh)
34 * 2005-09-03: Request-URI user part can be modified between load_gws()
35 * and first next_gw() calls.
36 */
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45 #include <regex.h>
46 #include "../../sr_module.h"
47 #include "../../dprint.h"
48 #include "../../ut.h"
49 #include "../../error.h"
50 #include "../../mem/mem.h"
51 #include "../../mem/shm_mem.h"
52 #include "../../db/db.h"
53 #include "../../usr_avp.h"
54 #include "../../parser/parse_uri.h"
55 #include "../../parser/parse_from.h"
56 #include "../../parser/msg_parser.h"
57 #include "../../action.h"
58 #include "../../qvalue.h"
59 #include "../../dset.h"
60 #include "../../ip_addr.h"
61 #include "../../resolve.h"
62 #include "../../mi/mi.h"
63 #include "../../mod_fix.h"
64 #include "../../socket_info.h"
65 #include "../../pvar.h"
66 #include "../../mod_fix.h"
67 #include "mi.h"
71 /*
72 * Version of gw and lcr tables required by the module,
73 * increment this value if you change the table in
74 * an backwards incompatible way
75 */
76 #define GW_TABLE_VERSION 8
77 #define LCR_TABLE_VERSION 3
79 /* usr_avp flag for sequential forking */
80 #define Q_FLAG (1<<2)
82 static void destroy(void); /* Module destroy function */
83 static int mi_child_init(void);
84 static int mod_init(void); /* Module initialization function */
85 static int fixstringloadgws(void **param, int param_count);
87 int reload_gws ( void );
89 #define GW_TABLE "gw"
91 #define GW_NAME_COL "gw_name"
93 #define GRP_ID_COL "grp_id"
95 #define IP_ADDR_COL "ip_addr"
97 #define PORT_COL "port"
99 #define URI_SCHEME_COL "uri_scheme"
101 #define TRANSPORT_COL "transport"
103 #define STRIP_COL "strip"
105 #define TAG_COL "tag"
107 #define FLAGS_COL "flags"
109 #define LCR_TABLE "lcr"
111 #define PREFIX_COL "prefix"
113 #define FROM_URI_COL "from_uri"
115 #define PRIORITY_COL "priority"
117 #define USER_COL "user"
119 #define REALM_COL "realm"
121 #define PASSWD_COL "passwd"
123 #define MAX_NO_OF_GWS 32
124 #define MAX_NO_OF_LCRS 256
125 #define MAX_PREFIX_LEN 256
126 #define MAX_USER_LEN 64
127 #define MAX_REALM_LEN 64
128 #define MAX_PASSWD_LEN 64
129 #define MAX_TAG_LEN 16
130 #define MAX_FROM_URI_LEN 256
132 /* Default module parameter values */
133 #define DEF_FR_INV_TIMER 90
134 #define DEF_FR_INV_TIMER_NEXT 30
135 #define DEF_PREFIX_MODE 0
137 /*
138 * Type definitions
139 */
141 typedef enum sip_protos uri_transport;
143 struct gw_info {
144 unsigned int ip_addr;
145 unsigned int port;
146 unsigned int grp_id;
147 uri_type scheme;
148 uri_transport transport;
149 unsigned int strip;
150 char tag[MAX_TAG_LEN + 1];
151 unsigned short tag_len;
152 unsigned int flags;
153 char user[MAX_USER_LEN];
154 unsigned short user_len;
155 char realm[MAX_REALM_LEN];
156 unsigned short realm_len;
157 char passwd[MAX_PASSWD_LEN];
158 unsigned short passwd_len;
159 };
161 struct lcr_info {
162 char prefix[MAX_PREFIX_LEN + 1];
163 unsigned short prefix_len;
164 char from_uri[MAX_FROM_URI_LEN + 1];
165 unsigned short from_uri_len;
166 unsigned int grp_id;
167 unsigned short priority;
168 unsigned short end_record;
169 };
171 struct prefix_regex {
172 regex_t re;
173 short int valid;
174 };
176 struct from_uri_regex {
177 regex_t re;
178 short int valid;
179 };
181 struct mi {
182 int gw_index;
183 int route_index;
184 int randomizer;
185 };
188 /*
189 * Database variables
190 */
191 static db_con_t* db_handle = 0; /* Database connection handle */
192 static db_func_t lcr_dbf;
194 /*
195 * Module parameter variables
196 */
198 /* database */
199 static str db_url = str_init(DEFAULT_RODB_URL);
200 static str gw_table = str_init(GW_TABLE);
201 static str gw_name_col = str_init(GW_NAME_COL);
202 static str grp_id_col = str_init(GRP_ID_COL);
203 static str ip_addr_col = str_init(IP_ADDR_COL);
204 static str port_col = str_init(PORT_COL);
205 static str uri_scheme_col = str_init(URI_SCHEME_COL);
206 static str transport_col = str_init(TRANSPORT_COL);
207 static str strip_col = str_init(STRIP_COL);
208 static str tag_col = str_init(TAG_COL);
209 static str flags_col = str_init(FLAGS_COL);
210 static str lcr_table = str_init(LCR_TABLE);
211 static str prefix_col = str_init(PREFIX_COL);
212 static str from_uri_col = str_init(FROM_URI_COL);
213 static str priority_col = str_init(PRIORITY_COL);
214 static str user_col = str_init(USER_COL);
215 static str realm_col = str_init(REALM_COL);
216 static str passwd_col = str_init(PASSWD_COL);
218 /* timer */
219 int fr_inv_timer = DEF_FR_INV_TIMER;
220 int fr_inv_timer_next = DEF_FR_INV_TIMER_NEXT;
222 /* avps */
223 static char *fr_inv_timer_avp_param = NULL;
224 static char *gw_uri_avp_param = NULL;
225 static char *ruri_user_avp_param = NULL;
226 static char *contact_avp_param = NULL;
227 static char *rpid_avp_param = NULL;
228 static char *flags_avp_param = NULL;
229 static char *user_avp_param = NULL;
230 static char *realm_avp_param = NULL;
231 static char *passwd_avp_param = NULL;
233 /* prefix mode */
234 int prefix_mode_param = DEF_PREFIX_MODE;
236 /*
237 * Other module types and variables
238 */
240 struct contact {
241 str uri;
242 qvalue_t q;
243 str dst_uri;
244 str path;
245 unsigned int flags;
246 struct socket_info* sock;
247 unsigned short q_flag;
248 struct contact *next;
249 };
251 static int fr_inv_timer_avp_type;
252 static int_str fr_inv_timer_avp;
253 static int gw_uri_avp_type;
254 static int_str gw_uri_avp;
255 static int ruri_user_avp_type;
256 static int_str ruri_user_avp;
257 static int contact_avp_type;
258 static int_str contact_avp;
259 static int rpid_avp_type;
260 static int_str rpid_avp;
261 static int flags_avp_type;
262 static int_str flags_avp;
263 static int user_avp_type;
264 static int_str user_avp;
265 static int realm_avp_type;
266 static int_str realm_avp;
267 static int passwd_avp_type;
268 static int_str passwd_avp;
270 struct gw_info **gws; /* Pointer to current gw table pointer */
271 struct gw_info *gws_1; /* Pointer to gw table 1 */
272 struct gw_info *gws_2; /* Pointer to gw table 2 */
274 struct lcr_info **lcrs; /* Pointer to current lcr table pointer */
275 struct lcr_info *lcrs_1; /* Pointer to lcr table 1 */
276 struct lcr_info *lcrs_2; /* Pointer to lcr table 2 */
278 unsigned int *lcrs_ws_reload_counter;
279 unsigned int reload_counter;
281 struct prefix_regex prefix_reg[MAX_NO_OF_LCRS];
282 struct from_uri_regex from_uri_reg[MAX_NO_OF_LCRS];
284 /*
285 * Module functions that are defined later
286 */
287 static int load_gws_0(struct sip_msg* _m, char* _s1, char* _s2);
288 static int load_gws_1(struct sip_msg* _m, char* _s1, char* _s2);
289 static int load_gws_from_grp(struct sip_msg* _m, char* _s1, char* _s2);
290 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2);
291 static int from_gw_0(struct sip_msg* _m, char* _s1, char* _s2);
292 static int from_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
293 static int from_gw_grp(struct sip_msg* _m, char* _s1, char* _s2);
294 static int to_gw(struct sip_msg* _m, char* _s1, char* _s2);
295 static int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2);
296 static int load_contacts (struct sip_msg*, char*, char*);
297 static int next_contacts (struct sip_msg*, char*, char*);
300 /*
301 * Exported functions
302 */
303 static cmd_export_t cmds[] = {
304 {"load_gws", (cmd_function)load_gws_0, 0, 0, 0, REQUEST_ROUTE},
305 {"load_gws", (cmd_function)load_gws_1, 1, fixup_pvar_null,
306 fixup_free_pvar_null, REQUEST_ROUTE},
307 {"load_gws_from_grp", (cmd_function)load_gws_from_grp, 1,
308 fixstringloadgws, 0, REQUEST_ROUTE},
309 {"next_gw", (cmd_function)next_gw, 0, 0, 0,
310 REQUEST_ROUTE | FAILURE_ROUTE},
311 {"from_gw", (cmd_function)from_gw_0, 0, 0, 0,
312 REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
313 {"from_gw", (cmd_function)from_gw_1, 1, fixup_pvar_null,
314 fixup_free_pvar_null, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
315 {"from_gw_grp", (cmd_function)from_gw_grp, 1, fixup_uint_null, 0,
316 REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
317 {"to_gw", (cmd_function)to_gw, 0, 0, 0,
318 REQUEST_ROUTE | FAILURE_ROUTE},
319 {"to_gw", (cmd_function)to_gw_grp, 1, fixup_uint_null, 0,
320 REQUEST_ROUTE | FAILURE_ROUTE},
321 {"load_contacts", (cmd_function)load_contacts, 0, 0, 0,
322 REQUEST_ROUTE},
323 {"next_contacts", (cmd_function)next_contacts, 0, 0, 0,
324 REQUEST_ROUTE | FAILURE_ROUTE},
325 {0, 0, 0, 0, 0, 0}
326 };
329 /*
330 * Exported parameters
331 */
332 static param_export_t params[] = {
333 {"db_url", STR_PARAM, &db_url.s },
334 {"gw_table", STR_PARAM, &gw_table.s },
335 {"gw_name_column", STR_PARAM, &gw_name_col.s },
336 {"grp_id_column", STR_PARAM, &grp_id_col.s },
337 {"ip_addr_column", STR_PARAM, &ip_addr_col.s },
338 {"port_column", STR_PARAM, &port_col.s },
339 {"uri_scheme_column", STR_PARAM, &uri_scheme_col.s },
340 {"transport_column", STR_PARAM, &transport_col.s },
341 {"strip_column", STR_PARAM, &strip_col.s },
342 {"tag_column", STR_PARAM, &tag_col.s },
343 {"flags_column", STR_PARAM, &flags_col.s },
344 {"lcr_table", STR_PARAM, &lcr_table.s },
345 {"prefix_column", STR_PARAM, &prefix_col.s },
346 {"from_uri_column", STR_PARAM, &from_uri_col.s },
347 {"priority_column", STR_PARAM, &priority_col.s },
348 {"fr_inv_timer_avp", STR_PARAM, &fr_inv_timer_avp_param },
349 {"gw_uri_avp", STR_PARAM, &gw_uri_avp_param },
350 {"ruri_user_avp", STR_PARAM, &ruri_user_avp_param },
351 {"contact_avp", STR_PARAM, &contact_avp_param },
352 {"rpid_avp", STR_PARAM, &rpid_avp_param },
353 {"flags_avp", STR_PARAM, &flags_avp_param },
354 {"fr_inv_timer", INT_PARAM, &fr_inv_timer },
355 {"fr_inv_timer_next", INT_PARAM, &fr_inv_timer_next },
356 {"prefix_mode", INT_PARAM, &prefix_mode_param },
357 {"user_column", STR_PARAM, &user_col.s },
358 {"realm_column", STR_PARAM, &realm_col.s },
359 {"passwd_column", STR_PARAM, &passwd_col.s },
360 {"auth_username_avp", STR_PARAM, &user_avp_param },
361 {"auth_realm_avp", STR_PARAM, &realm_avp_param },
362 {"auth_password_avp", STR_PARAM, &passwd_avp_param },
363 {0, 0, 0}
364 };
367 /*
368 * Exported MI functions
369 */
370 static mi_export_t mi_cmds[] = {
371 { MI_LCR_RELOAD, mi_lcr_reload, MI_NO_INPUT_FLAG, 0, mi_child_init },
372 { MI_LCR_DUMP, mi_lcr_dump, MI_NO_INPUT_FLAG, 0, 0 },
373 { 0, 0, 0, 0 ,0}
374 };
377 /*
378 * Module interface
379 */
380 struct module_exports exports = {
381 "lcr",
382 MODULE_VERSION,
383 DEFAULT_DLFLAGS, /* dlopen flags */
384 cmds, /* Exported functions */
385 params, /* Exported parameters */
386 0, /* exported statistics */
387 mi_cmds, /* exported MI functions */
388 0, /* exported pseudo-variables */
389 0, /* extra processes */
390 mod_init, /* module initialization function */
391 0, /* response function */
392 destroy, /* destroy function */
393 0 /* child initialization function */
394 };
397 static int lcr_db_init(const str* db_url)
398 {
399 if (lcr_dbf.init==0){
400 LM_CRIT("Null lcr_dbf\n");
401 goto error;
402 }
403 db_handle=lcr_dbf.init(db_url);
404 if (db_handle==0){
405 LM_ERR("Unable to connect to the database\n");
406 goto error;
407 }
408 return 0;
409 error:
410 return -1;
411 }
415 static int lcr_db_bind(const str* db_url)
416 {
417 if (db_bind_mod(db_url, &lcr_dbf)<0){
418 LM_ERR("Unable to bind to the database module\n");
419 return -1;
420 }
422 if (!DB_CAPABILITY(lcr_dbf, DB_CAP_QUERY)) {
423 LM_ERR("Database module does not implement 'query' function\n");
424 return -1;
425 }
427 return 0;
428 }
431 static void lcr_db_close(void)
432 {
433 if (db_handle && lcr_dbf.close){
434 lcr_dbf.close(db_handle);
435 db_handle=0;
436 }
437 }
440 static int mi_child_init(void)
441 {
442 return lcr_db_init(&db_url);
443 }
446 /*
447 * Module initialization function that is called before the main process forks
448 */
449 static int mod_init(void)
450 {
451 int i;
452 pv_spec_t avp_spec;
453 str s;
454 unsigned short avp_flags;
456 LM_DBG("Initializing\n");
458 /* Update length of module variables */
459 db_url.len = strlen(db_url.s);
460 gw_table.len = strlen(gw_table.s);
461 gw_name_col.len = strlen(gw_name_col.s);
462 grp_id_col.len = strlen(grp_id_col.s);
463 ip_addr_col.len = strlen(ip_addr_col.s);
464 port_col.len = strlen(port_col.s);
465 uri_scheme_col.len = strlen(uri_scheme_col.s);
466 transport_col.len = strlen(transport_col.s);
467 strip_col.len = strlen(strip_col.s);
468 tag_col.len = strlen(tag_col.s);
469 flags_col.len = strlen(flags_col.s);
470 lcr_table.len = strlen(lcr_table.s);
471 prefix_col.len = strlen(prefix_col.s);
472 from_uri_col.len = strlen(from_uri_col.s);
473 priority_col.len = strlen(priority_col.s);
474 user_col.len = strlen(user_col.s);
475 realm_col.len = strlen(realm_col.s);
476 passwd_col.len = strlen(passwd_col.s);
478 /* Bind database */
479 if (lcr_db_bind(&db_url)) {
480 LM_ERR("No database module found\n");
481 return -1;
482 }
484 /* Check value of prefix_mode */
485 if ((prefix_mode_param != 0) && (prefix_mode_param != 1)) {
486 LM_ERR("Invalid prefix_mode value <%d>\n", prefix_mode_param);
487 return -1;
488 }
490 /* Process AVP params */
491 if (fr_inv_timer_avp_param && *fr_inv_timer_avp_param) {
492 s.s = fr_inv_timer_avp_param; s.len = strlen(s.s);
493 if (pv_parse_spec(&s, &avp_spec)==0
494 || avp_spec.type!=PVT_AVP) {
495 LM_ERR("Malformed or non AVP definition <%s>\n",
496 fr_inv_timer_avp_param);
497 return -1;
498 }
500 if(pv_get_avp_name(0, &(avp_spec.pvp), &fr_inv_timer_avp, &avp_flags)!=0) {
501 LM_ERR("Invalid AVP definition <%s>\n", fr_inv_timer_avp_param);
502 return -1;
503 }
504 fr_inv_timer_avp_type = avp_flags;
505 } else {
506 LM_ERR("AVP fr_inv_timer_avp has not been defined\n");
507 return -1;
508 }
510 if (gw_uri_avp_param && *gw_uri_avp_param) {
511 s.s = gw_uri_avp_param; s.len = strlen(s.s);
512 if (pv_parse_spec(&s, &avp_spec)==0
513 || avp_spec.type!=PVT_AVP) {
514 LM_ERR("Malformed or non AVP definition <%s>\n", gw_uri_avp_param);
515 return -1;
516 }
518 if(pv_get_avp_name(0, &(avp_spec.pvp), &gw_uri_avp, &avp_flags)!=0) {
519 LM_ERR("Invalid AVP definition <%s>\n", gw_uri_avp_param);
520 return -1;
521 }
522 gw_uri_avp_type = avp_flags;
523 } else {
524 LM_ERR("AVP gw_uri_avp has not been defined\n");
525 return -1;
526 }
528 if (ruri_user_avp_param && *ruri_user_avp_param) {
529 s.s = ruri_user_avp_param; s.len = strlen(s.s);
530 if (pv_parse_spec(&s, &avp_spec)==0
531 || avp_spec.type!=PVT_AVP) {
532 LM_ERR("Malformed or non AVP definition <%s>\n",
533 ruri_user_avp_param);
534 return -1;
535 }
537 if(pv_get_avp_name(0, &(avp_spec.pvp), &ruri_user_avp, &avp_flags)!=0) {
538 LM_ERR("Invalid AVP definition <%s>\n", ruri_user_avp_param);
539 return -1;
540 }
541 ruri_user_avp_type = avp_flags;
542 } else {
543 LM_ERR("AVP ruri_user_avp has not been defined\n");
544 return -1;
545 }
547 if (contact_avp_param && *contact_avp_param) {
548 s.s = contact_avp_param; s.len = strlen(s.s);
549 if (pv_parse_spec(&s, &avp_spec)==0
550 || avp_spec.type!=PVT_AVP) {
551 LM_ERR("Malformed or non AVP definition <%s>\n",
552 contact_avp_param);
553 return -1;
554 }
556 if(pv_get_avp_name(0, &(avp_spec.pvp), &contact_avp, &avp_flags)!=0) {
557 LM_ERR("Invalid AVP definition <%s>\n", contact_avp_param);
558 return -1;
559 }
560 contact_avp_type = avp_flags;
561 } else {
562 LM_ERR("AVP contact_avp has not been defined\n");
563 return -1;
564 }
566 if (rpid_avp_param && *rpid_avp_param) {
567 s.s = rpid_avp_param; s.len = strlen(s.s);
568 if (pv_parse_spec(&s, &avp_spec)==0
569 || avp_spec.type!=PVT_AVP) {
570 LM_ERR("Malformed or non AVP definition <%s>\n", rpid_avp_param);
571 return -1;
572 }
574 if(pv_get_avp_name(0, &(avp_spec.pvp), &rpid_avp, &avp_flags)!=0) {
575 LM_ERR("Invalid AVP definition <%s>\n", rpid_avp_param);
576 return -1;
577 }
578 rpid_avp_type = avp_flags;
579 } else {
580 LM_ERR("AVP rpid_avp has not been defined\n");
581 return -1;
582 }
584 if (flags_avp_param && *flags_avp_param) {
585 s.s = flags_avp_param; s.len = strlen(s.s);
586 if (pv_parse_spec(&s, &avp_spec)==0
587 || avp_spec.type!=PVT_AVP) {
588 LM_ERR("Malformed or non AVP definition <%s>\n", flags_avp_param);
589 return -1;
590 }
592 if(pv_get_avp_name(0, &(avp_spec.pvp), &flags_avp, &avp_flags)!=0) {
593 LM_ERR("Invalid AVP definition <%s>\n", flags_avp_param);
594 return -1;
595 }
596 flags_avp_type = avp_flags;
597 } else {
598 LM_ERR("AVP flags_avp has not been defined\n");
599 return -1;
600 }
602 if (user_avp_param && *user_avp_param) {
603 s.s = user_avp_param; s.len = strlen(s.s);
604 if (pv_parse_spec(&s, &avp_spec)==0
605 || avp_spec.type!=PVT_AVP) {
606 LM_ERR("Malformed or non AVP definition <%s>\n", user_avp_param);
607 return -1;
608 }
610 if(pv_get_avp_name(0, &(avp_spec.pvp), &user_avp, &avp_flags)!=0) {
611 LM_ERR("Invalid AVP definition <%s>\n", user_avp_param);
612 return -1;
613 }
614 user_avp_type = avp_flags;
615 } else {
616 LM_ERR("AVP user_avp has not been defined\n");
617 return -1;
618 }
620 if (realm_avp_param && *realm_avp_param) {
621 s.s = realm_avp_param; s.len = strlen(s.s);
622 if (pv_parse_spec(&s, &avp_spec)==0
623 || avp_spec.type!=PVT_AVP) {
624 LM_ERR("Malformed or non AVP definition <%s>\n", realm_avp_param);
625 return -1;
626 }
628 if(pv_get_avp_name(0, &(avp_spec.pvp), &realm_avp, &avp_flags)!=0) {
629 LM_ERR("Invalid AVP definition <%s>\n", realm_avp_param);
630 return -1;
631 }
632 realm_avp_type = avp_flags;
633 } else {
634 LM_ERR("AVP realm_avp has not been defined\n");
635 return -1;
636 }
638 if (passwd_avp_param && *passwd_avp_param) {
639 s.s = passwd_avp_param; s.len = strlen(s.s);
640 if (pv_parse_spec(&s, &avp_spec)==0
641 || avp_spec.type!=PVT_AVP) {
642 LM_ERR("Malformed or non AVP definition <%s>\n", passwd_avp_param);
643 return -1;
644 }
646 if(pv_get_avp_name(0, &(avp_spec.pvp), &passwd_avp, &avp_flags)!=0) {
647 LM_ERR("Invalid AVP definition <%s>\n", passwd_avp_param);
648 return -1;
649 }
650 passwd_avp_type = avp_flags;
651 } else {
652 LM_ERR("AVP passwd_avp has not been defined\n");
653 return -1;
654 }
656 /* Check table version */
657 db_con_t* dbh;
658 if (lcr_dbf.init==0){
659 LM_CRIT("Unbound database\n");
660 return -1;
661 }
662 dbh=lcr_dbf.init(&db_url);
663 if (dbh==0){
664 LM_ERR("Unable to open database connection\n");
665 return -1;
666 }
667 if((db_check_table_version(&lcr_dbf, dbh, &gw_table, GW_TABLE_VERSION) < 0) ||
668 (db_check_table_version(&lcr_dbf, dbh, &lcr_table, LCR_TABLE_VERSION) < 0)) {
669 LM_ERR("error during table version check.\n");
670 lcr_dbf.close(dbh);
671 goto err;
672 }
673 lcr_dbf.close(dbh);
675 /* Initializing gw tables and gw table pointer variable */
676 gws_1 = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
677 (MAX_NO_OF_GWS + 1));
678 if (gws_1 == 0) {
679 LM_ERR("No memory for gw table\n");
680 goto err;
681 }
682 gws_2 = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
683 (MAX_NO_OF_GWS + 1));
684 if (gws_2 == 0) {
685 LM_ERR("No memory for gw table\n");
686 goto err;
687 }
688 for (i = 0; i < MAX_NO_OF_GWS + 1; i++) {
689 gws_1[i].ip_addr = gws_2[i].ip_addr = 0;
690 }
691 gws = (struct gw_info **)shm_malloc(sizeof(struct gw_info *));
692 if (gws == 0) {
693 LM_ERR("No memory for gw table pointer\n");
694 }
695 *gws = gws_1;
697 /* Initializing lcr tables and lcr table pointer variable */
698 lcrs_1 = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info) *
699 (MAX_NO_OF_LCRS + 1));
700 if (lcrs_1 == 0) {
701 LM_ERR("No memory for lcr table\n");
702 goto err;
703 }
704 lcrs_2 = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info) *
705 (MAX_NO_OF_LCRS + 1));
706 if (lcrs_2 == 0) {
707 LM_ERR("No memory for lcr table\n");
708 goto err;
709 }
710 for (i = 0; i < MAX_NO_OF_LCRS + 1; i++) {
711 lcrs_1[i].end_record = lcrs_2[i].end_record = 0;
712 }
713 lcrs = (struct lcr_info **)shm_malloc(sizeof(struct lcr_info *));
714 if (lcrs == 0) {
715 LM_ERR("No memory for lcr table pointer\n");
716 goto err;
717 }
718 *lcrs = lcrs_1;
720 lcrs_ws_reload_counter = (unsigned int *)shm_malloc(sizeof(unsigned int));
721 if (lcrs_ws_reload_counter == 0) {
722 LM_ERR("No memory for reload counter\n");
723 goto err;
724 }
725 *lcrs_ws_reload_counter = reload_counter = 0;
727 memset(prefix_reg, 0, sizeof(struct prefix_regex) * MAX_NO_OF_LCRS);
728 memset(from_uri_reg, 0, sizeof(struct from_uri_regex) * MAX_NO_OF_LCRS);
730 /* First reload */
731 if (reload_gws() == -1) {
732 LM_CRIT("Failed to reload gateways and routes\n");
733 goto err;
734 }
736 return 0;
738 err:
739 return -1;
740 }
743 static void destroy(void)
744 {
745 lcr_db_close();
746 }
748 /*
749 * Sort lcr records by prefix_len and priority.
750 */
751 static int comp_lcrs(const void *m1, const void *m2)
752 {
753 int result = -1;
755 struct mi *mi1 = (struct mi *) m1;
756 struct mi *mi2 = (struct mi *) m2;
758 struct lcr_info lcr_record1 = (*lcrs)[mi1->route_index];
759 struct lcr_info lcr_record2 = (*lcrs)[mi2->route_index];
761 if (prefix_mode_param == 0) {
762 /* Sort by prefix. */
763 if (lcr_record1.prefix_len > lcr_record2.prefix_len) {
764 result = 1;
765 } else if (lcr_record1.prefix_len == lcr_record2.prefix_len) {
766 /* Sort by priority. */
767 if (lcr_record1.priority < lcr_record2.priority) {
768 result = 1;
769 } else if (lcr_record1.priority == lcr_record2.priority) {
770 /* Nothing to do. */
771 result = 0;
772 }
773 }
774 } else {
775 if (lcr_record1.priority < lcr_record2.priority) {
776 result = 1;
777 } else if (lcr_record1.priority == lcr_record2.priority) {
778 /* Nothing to do. */
779 result = 0;
780 }
781 }
783 return result;
784 }
786 /*
787 * Sort lcr records by rand table.
788 */
789 static int rand_lcrs(const void *m1, const void *m2)
790 {
791 int result = -1;
793 struct mi mi1 = *((struct mi *) m1);
794 struct mi mi2 = *((struct mi *) m2);
796 if (mi1.randomizer > mi2.randomizer) {
797 result = 1;
798 } else if (mi1.randomizer == mi2.randomizer) {
799 result = 0;
800 }
802 return result;
803 }
805 /*
806 * regcomp each prefix.
807 */
808 static int load_prefix_regex(void)
809 {
810 int i, status, result = 0;
812 for (i = 0; i < MAX_NO_OF_LCRS; i++) {
813 if ((*lcrs)[i].end_record != 0) {
814 break;
815 }
816 if (prefix_reg[i].valid) {
817 regfree(&(prefix_reg[i].re));
818 prefix_reg[i].valid = 0;
819 }
820 memset(&(prefix_reg[i].re), 0, sizeof(regex_t));
821 if ((status=regcomp(&(prefix_reg[i].re),(*lcrs)[i].prefix,0))!=0){
822 LM_ERR("bad prefix re <%s>, regcomp returned %d (check regex.h)\n",
823 (*lcrs)[i].prefix, status);
824 result = -1;
825 break;
826 }
827 prefix_reg[i].valid = 1;
828 }
830 return result;
831 }
833 /*
834 * regcomp each from_uri.
835 */
836 static int load_from_uri_regex(void)
837 {
838 int i, status, result = 0;
840 for (i = 0; i < MAX_NO_OF_LCRS; i++) {
841 if ((*lcrs)[i].end_record != 0) {
842 break;
843 }
844 if (from_uri_reg[i].valid) {
845 regfree(&(from_uri_reg[i].re));
846 from_uri_reg[i].valid = 0;
847 }
848 memset(&(from_uri_reg[i].re), 0, sizeof(regex_t));
849 if ((status=regcomp(&(from_uri_reg[i].re),(*lcrs)[i].from_uri,0))!=0){
850 LM_ERR("Bad from_uri re <%s>, regcomp returned %d (check regex.h)\n",
851 (*lcrs)[i].from_uri, status);
852 result = -1;
853 break;
854 }
855 from_uri_reg[i].valid = 1;
856 }
858 if (result != -1) {
859 reload_counter = *lcrs_ws_reload_counter;
860 }
861 return result;
862 }
864 static int load_all_regex(void)
865 {
866 int result =0;
868 if (prefix_mode_param != 0) {
869 result = load_prefix_regex();
870 }
872 if (result == 0) {
873 result = load_from_uri_regex();
874 } else {
875 LM_ERR("Unable to load prefix regex\n");
876 }
878 if (result == 0) {
879 reload_counter = *lcrs_ws_reload_counter;
880 } else {
881 LM_ERR("Unable to load from_uri regex\n");
882 }
884 return result;
885 }
887 /*
888 * Reload gws to unused gw table and lcrs to unused lcr table, and, when done
889 * make unused gw and lcr table the one in use.
890 */
891 int reload_gws(void)
892 {
893 unsigned int i, port, strip, tag_len, prefix_len, from_uri_len,
894 user_len, realm_len, passwd_len, grp_id, priority;
895 struct in_addr ip_addr;
896 unsigned int flags;
897 uri_type scheme;
898 uri_transport transport;
899 db_con_t* dbh;
900 char *tag, *prefix, *from_uri;
901 char *user, *realm, *passwd;
902 db_res_t* res = NULL;
903 db_row_t* row;
904 db_key_t gw_cols[11];
905 db_key_t lcr_cols[4];
907 gw_cols[0] = &ip_addr_col;
908 gw_cols[1] = &port_col;
909 gw_cols[2] = &uri_scheme_col;
910 gw_cols[3] = &transport_col;
911 gw_cols[4] = &strip_col;
912 gw_cols[5] = &tag_col;
913 /* FIXME: is this ok if we have different names for grp_id
914 in the two tables? (ge vw lcr) */
915 gw_cols[6] = &grp_id_col;
916 gw_cols[7] = &flags_col;
917 gw_cols[8] = &user_col;
918 gw_cols[9] = &realm_col;
919 gw_cols[10] = &passwd_col;
921 lcr_cols[0] = &prefix_col;
922 lcr_cols[1] = &from_uri_col;
923 /* FIXME: is this ok if we have different names for grp_id
924 in the two tables? (ge vw lcr) */
925 lcr_cols[2] = &grp_id_col;
926 lcr_cols[3] = &priority_col;
928 if (lcr_dbf.init==0){
929 LM_CRIT("Unbound database\n");
930 return -1;
931 }
932 dbh=lcr_dbf.init(&db_url);
933 if (dbh==0){
934 LM_ERR("Unable to open database connection\n");
935 return -1;
936 }
938 if (lcr_dbf.use_table(dbh, &gw_table) < 0) {
939 LM_ERR("Error while trying to use gw table\n");
940 return -1;
941 }
943 if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 11, 0, &res) < 0) {
944 LM_ERR("Failed to query gw data\n");
945 lcr_dbf.close(dbh);
946 return -1;
947 }
949 if (RES_ROW_N(res) + 1 > MAX_NO_OF_GWS) {
950 LM_ERR("Too many gateways\n");
951 lcr_dbf.free_result(dbh, res);
952 lcr_dbf.close(dbh);
953 return -1;
954 }
956 for (i = 0; i < RES_ROW_N(res); i++) {
957 row = RES_ROWS(res) + i;
958 if (!((VAL_TYPE(ROW_VALUES(row)) == DB_STRING) &&
959 !VAL_NULL(ROW_VALUES(row)) &&
960 inet_aton((char *)VAL_STRING(ROW_VALUES(row)), &ip_addr) != 0)) {
961 LM_ERR("Invalid IP address of gw <%s>\n",
962 (char *)VAL_STRING(ROW_VALUES(row)));
963 lcr_dbf.free_result(dbh, res);
964 lcr_dbf.close(dbh);
965 return -1;
966 }
967 if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
968 port = 0;
969 } else {
970 port = (unsigned int)VAL_INT(ROW_VALUES(row) + 1);
971 }
972 if (port > 65536) {
973 LM_ERR("Port of gw is too large <%u>\n", port);
974 lcr_dbf.free_result(dbh, res);
975 lcr_dbf.close(dbh);
976 return -1;
977 }
978 if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {
979 scheme = SIP_URI_T;
980 } else {
981 scheme = (uri_type)VAL_INT(ROW_VALUES(row) + 2);
982 if ((scheme != SIP_URI_T) && (scheme != SIPS_URI_T)) {
983 LM_ERR("Unknown or unsupported URI scheme <%u>\n",
984 (unsigned int)scheme);
985 lcr_dbf.free_result(dbh, res);
986 lcr_dbf.close(dbh);
987 return -1;
988 }
989 }
990 if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {
991 transport = PROTO_NONE;
992 } else {
993 transport = (uri_transport)VAL_INT(ROW_VALUES(row) + 3);
994 if ((transport != PROTO_UDP) && (transport != PROTO_TCP) &&
995 (transport != PROTO_TLS)) {
996 LM_ERR("Unknown or unsupported transport <%u>\n",
997 (unsigned int)transport);
998 lcr_dbf.free_result(dbh, res);
999 lcr_dbf.close(dbh);
1000 return -1;
1001 }
1002 }
1003 if (VAL_NULL(ROW_VALUES(row) + 4) == 1) {
1004 strip = 0;
1005 } else {
1006 strip = (unsigned int)VAL_INT(ROW_VALUES(row) + 4);
1007 }
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;
1019 }
1020 }
1021 if (VAL_NULL(ROW_VALUES(row) + 6) == 1) {
1022 grp_id = 0;
1023 } else {
1024 grp_id = VAL_INT(ROW_VALUES(row) + 6);
1025 }
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;
1034 }
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;
1046 }
1047 }
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;
1059 }
1060 }
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;
1072 }
1073 }
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);
1114 }
1115 }
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;
1125 }
1128 if (lcr_dbf.use_table(dbh, &lcr_table) < 0) {
1129 LM_ERR("Error while trying to use lcr table\n");
1130 return -1;
1131 }
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;
1137 }
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;
1144 }
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;
1158 }
1159 }
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;
1171 }
1172 }
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;
1178 }
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;
1185 }
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';
1196 }
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';
1208 }
1209 lcrs_1[i].grp_id = grp_id;
1210 lcrs_1[i].priority = priority;
1211 lcrs_1[i].end_record = 0;
1212 }
1213 }
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;
1224 }
1226 (*lcrs_ws_reload_counter)++;
1227 if (0 != load_all_regex()) {
1229 return -1;
1230 }
1232 return 1;
1233 }
1236 int mi_print_gws(struct mi_node* rpl)
1237 {
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;
1310 }
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;
1337 }
1339 return 0;
1340 }
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)
1347 {
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;
1373 }
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;
1389 }
1390 } else {
1391 from_uri.s = int2str(val.n, &from_uri.len);
1392 have_rpid_avp = 1;
1393 }
1394 }
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;
1400 }
1401 if (!_m->from) {
1402 LM_ERR("From header field not found\n");
1403 return -1;
1404 }
1405 if ((!(_m->from)->parsed) && (parse_from_header(_m) < 0)) {
1406 LM_ERR("Error while parsing From header\n");
1407 return -1;
1408 }
1409 from_uri = get_from(_m)->uri;
1410 }
1411 }
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;
1418 }
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;
1426 }
1427 }
1429 /*
1430 * Let's match the gws:
1431 * 1. prefix matching
1432 * 2. from_uri matching
1433 * 3. _grp_id matching
1434 *
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;
1443 }
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;
1459 }
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;
1504 }
1505 }
1506 }
1507 }
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;
1517 }
1518 }
1519 }
1520 }
1521 }
1522 }
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;
1545 }
1546 matched_gws[i - 1].randomizer = rand();
1547 }
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);
1555 }
1556 prefix_len = (*lcrs)[matched_gws[i].route_index].prefix_len;
1557 priority = (*lcrs)[matched_gws[i].route_index].priority;
1558 }
1559 }
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);
1566 }
1568 for (i = 0; i < MAX_NO_OF_GWS; i++) {
1569 index = matched_gws[i].gw_index;
1570 if (index == -1) {
1571 break;
1572 }
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;
1585 }
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;
1592 }
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;
1605 }
1606 if (tag_len) {
1607 memcpy(at, tag, tag_len); at = at + tag_len;
1608 }
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;
1627 }
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;
1631 }
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;
1644 }
1645 }
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;
1672 }
1674 return 1;
1675 }
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)
1683 {
1684 str grp_s;
1685 unsigned int grp_id;
1687 if(((pv_elem_p)_s1)->spec.getf!=NULL)
1688 {
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;
1695 }
1696 if (grp_id > 0) return do_load_gws(_m, (str *)0, (int)grp_id);
1697 else return -1;
1698 }
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)
1706 {
1707 return do_load_gws(_m, (str *)0, -1);
1708 }
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)
1716 {
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;
1726 }
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;
1731 }
1732 } else {
1733 LM_DBG("cannot get pseudo variable value\n");
1734 return -1;
1735 }
1736 }
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)
1750 {
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;
1777 }
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);
1781 }
1782 if (!rlm_avp) {
1783 LM_DBG("Realm AVP no set\n");
1784 return -1;
1785 }
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);
1789 }
1790 if (!pwd_avp) {
1791 LM_DBG("Passwd AVP no set\n");
1792 return -1;
1793 }
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);
1797 }
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;
1809 }
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);
1815 }
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;
1821 }
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;
1828 }
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;
1836 }
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;
1846 }
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;
1851 }
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);
1859 }
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;
1869 }
1871 return 1;
1872 }
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)
1879 {
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];
1895 }
1896 } else {
1897 LM_ERR("IP address PV empty value\n");
1898 return -1;
1899 }
1900 } else {
1901 src_addr = _m->rcv.src_ip.u.addr32[0];
1902 }
1904 for (i = 0; i < MAX_NO_OF_GWS; i++) {
1905 if ((*gws)[i].ip_addr == 0) {
1906 return -1;
1907 }
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;
1915 }
1916 }
1918 LM_DBG("Request did not come from gw\n");
1919 return -1;
1920 }
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)
1928 {
1929 return do_from_gw(_m, (pv_spec_t *)0, (int)(long)_grp_id);
1930 }
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)
1938 {
1939 return do_from_gw(_m, (pv_spec_t *)0, -1);
1940 }
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)
1948 {
1949 return do_from_gw(_m, (pv_spec_t *)_addr_sp, -1);
1950 }
1953 /*
1954 * Checks if in-dialog request goes to gateway
1955 */
1956 static int do_to_gw(struct sip_msg* _m, int grp_id)
1957 {
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;
1965 }
1967 if (_m->parsed_uri.host.len > 15) {
1968 return -1;
1969 }
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;
1975 }
1977 for (i = 0; i < MAX_NO_OF_GWS; i++) {
1978 if ((*gws)[i].ip_addr == 0) {
1979 return -1;
1980 }
1981 if ((*gws)[i].ip_addr == addr.s_addr &&
1982 (grp_id < 0 || (*gws)[i].grp_id == grp_id)) {
1983 return 1;
1984 }
1985 }
1987 return -1;
1988 }
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)
1996 {
1997 int grp_id;
1999 grp_id = (int)(long)_s1;
2000 return do_to_gw(_m, grp_id);
2001 }
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)
2009 {
2010 return do_to_gw(_m, -1);
2011 }
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);
2023 }
2024 }
2026 /* Encode branch info from contact struct to str */
2027 static inline int encode_branch_info(str *info, struct contact *con)
2028 {
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;
2038 }
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;
2057 }
2058 } else {
2059 len = 0;
2060 }
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;
2071 }
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)
2077 {
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;
2088 }
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;
2097 }
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;
2106 }
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;
2117 }
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;
2123 }
2124 } else {
2125 *sock = 0;
2126 }
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;
2136 }
2137 } else {
2138 *flags = 0;
2139 }
2141 return 1;
2142 }
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)
2152 {
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;
2165 }
2167 ruri = GET_RURI(msg);
2168 if (!ruri) {
2169 LM_ERR("No Request-URI found\n");
2170 return -1;
2171 }
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;
2178 }
2179 }
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;
2189 }
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;
2209 }
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;
2222 }
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;
2232 }
2233 }
2234 }
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;
2244 }
2245 curr = curr->next;
2246 }
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;
2256 }
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;
2264 }
2266 /* Clear all branches */
2267 clear_branches();
2269 /* Free contact list */
2270 free_contact_list(contacts);
2272 return 1;
2273 }
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)
2284 {
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;
2296 }
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;
2305 }
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;
2321 }
2322 }
2323 return 1;
2324 }
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;
2338 }
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;
2344 }
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;
2353 }
2354 }
2355 return 1;
2356 }
2357 prev = avp;
2358 }
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;
2365 }
2367 return 1;
2368 }
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)
2376 {
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;
2389 }
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;
2394 }
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;
2401 }
2402 }
2403 }
2404 *param = (void*)model;
2405 }
2407 return 0;
2408 }