Wed, 10 Feb 2010 21:25:01 +0100
Extend uac_auth() of the UAC module to workaround CSEQ problems.
This logic is meant to complement that of changeset 17, which
added rich authentication credentials to the gw table and its
associated logic in the LCR module.
1 /*
2 * $Id: lcr_mod.c 6015 2009-08-22 21:45:06Z bogdan_iancu $
3 *
4 * Least Cost Routing module (also implements sequential forking)
5 *
6 * Copyright (C) 2005 Juha Heinanen
7 * Copyright (C) 2006 Voice Sistem SRL
8 *
9 * This file is part of opensips, a free SIP server.
10 *
11 * opensips is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version
15 *
16 * opensips is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 * History:
26 * -------
27 * 2005-02-14: Introduced lcr module (jh)
28 * 2005-02-20: Added sequential forking functions (jh)
29 * 2005-02-25: Added support for int AVP names, combined addr and port
30 * AVPs (jh)
31 * 2005-07-28: Added support for gw URI scheme and transport,
32 * backport from ser (kd)
33 * 2005-08-20: Added support for gw prefixes (jh)
34 * 2005-09-03: Request-URI user part can be modified between load_gws()
35 * and first next_gw() calls.
36 */
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45 #include <regex.h>
46 #include "../../sr_module.h"
47 #include "../../dprint.h"
48 #include "../../ut.h"
49 #include "../../error.h"
50 #include "../../mem/mem.h"
51 #include "../../mem/shm_mem.h"
52 #include "../../db/db.h"
53 #include "../../usr_avp.h"
54 #include "../../parser/parse_uri.h"
55 #include "../../parser/parse_from.h"
56 #include "../../parser/msg_parser.h"
57 #include "../../action.h"
58 #include "../../qvalue.h"
59 #include "../../dset.h"
60 #include "../../ip_addr.h"
61 #include "../../resolve.h"
62 #include "../../mi/mi.h"
63 #include "../../mod_fix.h"
64 #include "../../socket_info.h"
65 #include "../../pvar.h"
66 #include "../../mod_fix.h"
67 #include "mi.h"
71 /*
72 * Version of gw and lcr tables required by the module,
73 * increment this value if you change the table in
74 * an backwards incompatible way
75 */
76 #define GW_TABLE_VERSION 8
77 #define LCR_TABLE_VERSION 3
79 /* usr_avp flag for sequential forking */
80 #define Q_FLAG (1<<2)
82 static void destroy(void); /* Module destroy function */
83 static int mi_child_init(void);
84 static int mod_init(void); /* Module initialization function */
85 static int fixstringloadgws(void **param, int param_count);
87 int reload_gws ( void );
89 #define GW_TABLE "gw"
91 #define GW_NAME_COL "gw_name"
93 #define GRP_ID_COL "grp_id"
95 #define IP_ADDR_COL "ip_addr"
97 #define PORT_COL "port"
99 #define URI_SCHEME_COL "uri_scheme"
101 #define TRANSPORT_COL "transport"
103 #define STRIP_COL "strip"
105 #define TAG_COL "tag"
107 #define FLAGS_COL "flags"
109 #define LCR_TABLE "lcr"
111 #define PREFIX_COL "prefix"
113 #define FROM_URI_COL "from_uri"
115 #define PRIORITY_COL "priority"
117 #define USER_COL "user"
119 #define REALM_COL "realm"
121 #define PASSWD_COL "passwd"
123 #define MAX_NO_OF_GWS 32
124 #define MAX_NO_OF_LCRS 256
125 #define MAX_PREFIX_LEN 256
126 #define MAX_USER_LEN 64
127 #define MAX_REALM_LEN 64
128 #define MAX_PASSWD_LEN 64
129 #define MAX_TAG_LEN 16
130 #define MAX_FROM_URI_LEN 256
132 /* Default module parameter values */
133 #define DEF_FR_INV_TIMER 90
134 #define DEF_FR_INV_TIMER_NEXT 30
135 #define DEF_PREFIX_MODE 0
137 /*
138 * Type definitions
139 */
141 typedef enum sip_protos uri_transport;
143 struct gw_info {
144 unsigned int ip_addr;
145 unsigned int port;
146 unsigned int grp_id;
147 uri_type scheme;
148 uri_transport transport;
149 unsigned int strip;
150 char tag[MAX_TAG_LEN + 1];
151 unsigned short tag_len;
152 unsigned int flags;
153 char user[MAX_USER_LEN];
154 unsigned short user_len;
155 char realm[MAX_REALM_LEN];
156 unsigned short realm_len;
157 char passwd[MAX_PASSWD_LEN];
158 unsigned short passwd_len;
159 };
161 struct lcr_info {
162 char prefix[MAX_PREFIX_LEN + 1];
163 unsigned short prefix_len;
164 char from_uri[MAX_FROM_URI_LEN + 1];
165 unsigned short from_uri_len;
166 unsigned int grp_id;
167 unsigned short priority;
168 unsigned short end_record;
169 };
171 struct prefix_regex {
172 regex_t re;
173 short int valid;
174 };
176 struct from_uri_regex {
177 regex_t re;
178 short int valid;
179 };
181 struct mi {
182 int gw_index;
183 int route_index;
184 int randomizer;
185 };
188 /*
189 * Database variables
190 */
191 static db_con_t* db_handle = 0; /* Database connection handle */
192 static db_func_t lcr_dbf;
194 /*
195 * Module parameter variables
196 */
198 /* database */
199 static str db_url = str_init(DEFAULT_RODB_URL);
200 static str gw_table = str_init(GW_TABLE);
201 static str gw_name_col = str_init(GW_NAME_COL);
202 static str grp_id_col = str_init(GRP_ID_COL);
203 static str ip_addr_col = str_init(IP_ADDR_COL);
204 static str port_col = str_init(PORT_COL);
205 static str uri_scheme_col = str_init(URI_SCHEME_COL);
206 static str transport_col = str_init(TRANSPORT_COL);
207 static str strip_col = str_init(STRIP_COL);
208 static str tag_col = str_init(TAG_COL);
209 static str flags_col = str_init(FLAGS_COL);
210 static str lcr_table = str_init(LCR_TABLE);
211 static str prefix_col = str_init(PREFIX_COL);
212 static str from_uri_col = str_init(FROM_URI_COL);
213 static str priority_col = str_init(PRIORITY_COL);
214 static str user_col = str_init(USER_COL);
215 static str realm_col = str_init(REALM_COL);
216 static str passwd_col = str_init(PASSWD_COL);
218 /* timer */
219 int fr_inv_timer = DEF_FR_INV_TIMER;
220 int fr_inv_timer_next = DEF_FR_INV_TIMER_NEXT;
222 /* avps */
223 static char *fr_inv_timer_avp_param = NULL;
224 static char *gw_uri_avp_param = NULL;
225 static char *ruri_user_avp_param = NULL;
226 static char *contact_avp_param = NULL;
227 static char *rpid_avp_param = NULL;
228 static char *flags_avp_param = NULL;
229 static char *user_avp_param = NULL;
230 static char *realm_avp_param = NULL;
231 static char *passwd_avp_param = NULL;
233 /* prefix mode */
234 int prefix_mode_param = DEF_PREFIX_MODE;
236 /*
237 * Other module types and variables
238 */
240 struct contact {
241 str uri;
242 qvalue_t q;
243 str dst_uri;
244 str path;
245 unsigned int flags;
246 struct socket_info* sock;
247 unsigned short q_flag;
248 struct contact *next;
249 };
251 static int fr_inv_timer_avp_type;
252 static int_str fr_inv_timer_avp;
253 static int gw_uri_avp_type;
254 static int_str gw_uri_avp;
255 static int ruri_user_avp_type;
256 static int_str ruri_user_avp;
257 static int contact_avp_type;
258 static int_str contact_avp;
259 static int rpid_avp_type;
260 static int_str rpid_avp;
261 static int flags_avp_type;
262 static int_str flags_avp;
263 static int user_avp_type;
264 static int_str user_avp;
265 static int realm_avp_type;
266 static int_str realm_avp;
267 static int passwd_avp_type;
268 static int_str passwd_avp;
270 struct gw_info **gws; /* Pointer to current gw table pointer */
271 struct gw_info *gws_1; /* Pointer to gw table 1 */
272 struct gw_info *gws_2; /* Pointer to gw table 2 */
274 struct lcr_info **lcrs; /* Pointer to current lcr table pointer */
275 struct lcr_info *lcrs_1; /* Pointer to lcr table 1 */
276 struct lcr_info *lcrs_2; /* Pointer to lcr table 2 */
278 unsigned int *lcrs_ws_reload_counter;
279 unsigned int reload_counter;
281 struct prefix_regex prefix_reg[MAX_NO_OF_LCRS];
282 struct from_uri_regex from_uri_reg[MAX_NO_OF_LCRS];
284 /*
285 * Module functions that are defined later
286 */
287 static int load_gws_0(struct sip_msg* _m, char* _s1, char* _s2);
288 static int load_gws_1(struct sip_msg* _m, char* _s1, char* _s2);
289 static int load_gws_from_grp(struct sip_msg* _m, char* _s1, char* _s2);
290 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2);
291 static int from_gw_0(struct sip_msg* _m, char* _s1, char* _s2);
292 static int from_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
293 static int from_gw_grp(struct sip_msg* _m, char* _s1, char* _s2);
294 static int to_gw(struct sip_msg* _m, char* _s1, char* _s2);
295 static int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2);
296 static int load_contacts (struct sip_msg*, char*, char*);
297 static int next_contacts (struct sip_msg*, char*, char*);
300 /*
301 * Exported functions
302 */
303 static cmd_export_t cmds[] = {
304 {"load_gws", (cmd_function)load_gws_0, 0, 0, 0, REQUEST_ROUTE},
305 {"load_gws", (cmd_function)load_gws_1, 1, fixup_pvar_null,
306 fixup_free_pvar_null, REQUEST_ROUTE},
307 {"load_gws_from_grp", (cmd_function)load_gws_from_grp, 1,
308 fixstringloadgws, 0, REQUEST_ROUTE},
309 {"next_gw", (cmd_function)next_gw, 0, 0, 0,
310 REQUEST_ROUTE | FAILURE_ROUTE},
311 {"from_gw", (cmd_function)from_gw_0, 0, 0, 0,
312 REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
313 {"from_gw", (cmd_function)from_gw_1, 1, fixup_pvar_null,
314 fixup_free_pvar_null, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
315 {"from_gw_grp", (cmd_function)from_gw_grp, 1, fixup_uint_null, 0,
316 REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
317 {"to_gw", (cmd_function)to_gw, 0, 0, 0,
318 REQUEST_ROUTE | FAILURE_ROUTE},
319 {"to_gw", (cmd_function)to_gw_grp, 1, fixup_uint_null, 0,
320 REQUEST_ROUTE | FAILURE_ROUTE},
321 {"load_contacts", (cmd_function)load_contacts, 0, 0, 0,
322 REQUEST_ROUTE},
323 {"next_contacts", (cmd_function)next_contacts, 0, 0, 0,
324 REQUEST_ROUTE | FAILURE_ROUTE},
325 {0, 0, 0, 0, 0, 0}
326 };
329 /*
330 * Exported parameters
331 */
332 static param_export_t params[] = {
333 {"db_url", STR_PARAM, &db_url.s },
334 {"gw_table", STR_PARAM, &gw_table.s },
335 {"gw_name_column", STR_PARAM, &gw_name_col.s },
336 {"grp_id_column", STR_PARAM, &grp_id_col.s },
337 {"ip_addr_column", STR_PARAM, &ip_addr_col.s },
338 {"port_column", STR_PARAM, &port_col.s },
339 {"uri_scheme_column", STR_PARAM, &uri_scheme_col.s },
340 {"transport_column", STR_PARAM, &transport_col.s },
341 {"strip_column", STR_PARAM, &strip_col.s },
342 {"tag_column", STR_PARAM, &tag_col.s },
343 {"flags_column", STR_PARAM, &flags_col.s },
344 {"lcr_table", STR_PARAM, &lcr_table.s },
345 {"prefix_column", STR_PARAM, &prefix_col.s },
346 {"from_uri_column", STR_PARAM, &from_uri_col.s },
347 {"priority_column", STR_PARAM, &priority_col.s },
348 {"fr_inv_timer_avp", STR_PARAM, &fr_inv_timer_avp_param },
349 {"gw_uri_avp", STR_PARAM, &gw_uri_avp_param },
350 {"ruri_user_avp", STR_PARAM, &ruri_user_avp_param },
351 {"contact_avp", STR_PARAM, &contact_avp_param },
352 {"rpid_avp", STR_PARAM, &rpid_avp_param },
353 {"flags_avp", STR_PARAM, &flags_avp_param },
354 {"fr_inv_timer", INT_PARAM, &fr_inv_timer },
355 {"fr_inv_timer_next", INT_PARAM, &fr_inv_timer_next },
356 {"prefix_mode", INT_PARAM, &prefix_mode_param },
357 {"user_column", STR_PARAM, &user_col.s },
358 {"realm_column", STR_PARAM, &realm_col.s },
359 {"passwd_column", STR_PARAM, &passwd_col.s },
360 {"auth_username_avp", STR_PARAM, &user_avp_param },
361 {"auth_realm_avp", STR_PARAM, &realm_avp_param },
362 {"auth_password_avp", STR_PARAM, &passwd_avp_param },
363 {0, 0, 0}
364 };
367 /*
368 * Exported MI functions
369 */
370 static mi_export_t mi_cmds[] = {
371 { MI_LCR_RELOAD, mi_lcr_reload, MI_NO_INPUT_FLAG, 0, mi_child_init },
372 { MI_LCR_DUMP, mi_lcr_dump, MI_NO_INPUT_FLAG, 0, 0 },
373 { 0, 0, 0, 0 ,0}
374 };
377 /*
378 * Module interface
379 */
380 struct module_exports exports = {
381 "lcr",
382 MODULE_VERSION,
383 DEFAULT_DLFLAGS, /* dlopen flags */
384 cmds, /* Exported functions */
385 params, /* Exported parameters */
386 0, /* exported statistics */
387 mi_cmds, /* exported MI functions */
388 0, /* exported pseudo-variables */
389 0, /* extra processes */
390 mod_init, /* module initialization function */
391 0, /* response function */
392 destroy, /* destroy function */
393 0 /* child initialization function */
394 };
397 static int lcr_db_init(const str* db_url)
398 {
399 if (lcr_dbf.init==0){
400 LM_CRIT("Null lcr_dbf\n");
401 goto error;
402 }
403 db_handle=lcr_dbf.init(db_url);
404 if (db_handle==0){
405 LM_ERR("Unable to connect to the database\n");
406 goto error;
407 }
408 return 0;
409 error:
410 return -1;
411 }
415 static int lcr_db_bind(const str* db_url)
416 {
417 if (db_bind_mod(db_url, &lcr_dbf)<0){
418 LM_ERR("Unable to bind to the database module\n");
419 return -1;
420 }
422 if (!DB_CAPABILITY(lcr_dbf, DB_CAP_QUERY)) {
423 LM_ERR("Database module does not implement 'query' function\n");
424 return -1;
425 }
427 return 0;
428 }
431 static void lcr_db_close(void)
432 {
433 if (db_handle && lcr_dbf.close){
434 lcr_dbf.close(db_handle);
435 db_handle=0;
436 }
437 }
440 static int mi_child_init(void)
441 {
442 return lcr_db_init(&db_url);
443 }
446 /*
447 * Module initialization function that is called before the main process forks
448 */
449 static int mod_init(void)
450 {
451 int i;
452 pv_spec_t avp_spec;
453 str s;
454 unsigned short avp_flags;
456 LM_DBG("Initializing\n");
458 /* Update length of module variables */
459 db_url.len = strlen(db_url.s);
460 gw_table.len = strlen(gw_table.s);
461 gw_name_col.len = strlen(gw_name_col.s);
462 grp_id_col.len = strlen(grp_id_col.s);
463 ip_addr_col.len = strlen(ip_addr_col.s);
464 port_col.len = strlen(port_col.s);
465 uri_scheme_col.len = strlen(uri_scheme_col.s);
466 transport_col.len = strlen(transport_col.s);
467 strip_col.len = strlen(strip_col.s);
468 tag_col.len = strlen(tag_col.s);
469 flags_col.len = strlen(flags_col.s);
470 lcr_table.len = strlen(lcr_table.s);
471 prefix_col.len = strlen(prefix_col.s);
472 from_uri_col.len = strlen(from_uri_col.s);
473 priority_col.len = strlen(priority_col.s);
474 user_col.len = strlen(user_col.s);
475 realm_col.len = strlen(realm_col.s);
476 passwd_col.len = strlen(passwd_col.s);
478 /* Bind database */
479 if (lcr_db_bind(&db_url)) {
480 LM_ERR("No database module found\n");
481 return -1;
482 }
484 /* Check value of prefix_mode */
485 if ((prefix_mode_param != 0) && (prefix_mode_param != 1)) {
486 LM_ERR("Invalid prefix_mode value <%d>\n", prefix_mode_param);
487 return -1;
488 }
490 /* Process AVP params */
491 if (fr_inv_timer_avp_param && *fr_inv_timer_avp_param) {
492 s.s = fr_inv_timer_avp_param; s.len = strlen(s.s);
493 if (pv_parse_spec(&s, &avp_spec)==0
494 || avp_spec.type!=PVT_AVP) {
495 LM_ERR("Malformed or non AVP definition <%s>\n",
496 fr_inv_timer_avp_param);
497 return -1;
498 }
500 if(pv_get_avp_name(0, &(avp_spec.pvp), &fr_inv_timer_avp, &avp_flags)!=0) {
501 LM_ERR("Invalid AVP definition <%s>\n", fr_inv_timer_avp_param);
502 return -1;
503 }
504 fr_inv_timer_avp_type = avp_flags;
505 } else {
506 LM_ERR("AVP fr_inv_timer_avp has not been defined\n");
507 return -1;
508 }
510 if (gw_uri_avp_param && *gw_uri_avp_param) {
511 s.s = gw_uri_avp_param; s.len = strlen(s.s);
512 if (pv_parse_spec(&s, &avp_spec)==0
513 || avp_spec.type!=PVT_AVP) {
514 LM_ERR("Malformed or non AVP definition <%s>\n", gw_uri_avp_param);
515 return -1;
516 }
518 if(pv_get_avp_name(0, &(avp_spec.pvp), &gw_uri_avp, &avp_flags)!=0) {
519 LM_ERR("Invalid AVP definition <%s>\n", gw_uri_avp_param);
520 return -1;
521 }
522 gw_uri_avp_type = avp_flags;
523 } else {
524 LM_ERR("AVP gw_uri_avp has not been defined\n");
525 return -1;
526 }
528 if (ruri_user_avp_param && *ruri_user_avp_param) {
529 s.s = ruri_user_avp_param; s.len = strlen(s.s);
530 if (pv_parse_spec(&s, &avp_spec)==0
531 || avp_spec.type!=PVT_AVP) {
532 LM_ERR("Malformed or non AVP definition <%s>\n",
533 ruri_user_avp_param);
534 return -1;
535 }
537 if(pv_get_avp_name(0, &(avp_spec.pvp), &ruri_user_avp, &avp_flags)!=0) {
538 LM_ERR("Invalid AVP definition <%s>\n", ruri_user_avp_param);
539 return -1;
540 }
541 ruri_user_avp_type = avp_flags;
542 } else {
543 LM_ERR("AVP ruri_user_avp has not been defined\n");
544 return -1;
545 }
547 if (contact_avp_param && *contact_avp_param) {
548 s.s = contact_avp_param; s.len = strlen(s.s);
549 if (pv_parse_spec(&s, &avp_spec)==0
550 || avp_spec.type!=PVT_AVP) {
551 LM_ERR("Malformed or non AVP definition <%s>\n",
552 contact_avp_param);
553 return -1;
554 }
556 if(pv_get_avp_name(0, &(avp_spec.pvp), &contact_avp, &avp_flags)!=0) {
557 LM_ERR("Invalid AVP definition <%s>\n", contact_avp_param);
558 return -1;
559 }
560 contact_avp_type = avp_flags;
561 } else {
562 LM_ERR("AVP contact_avp has not been defined\n");
563 return -1;
564 }
566 if (rpid_avp_param && *rpid_avp_param) {
567 s.s = rpid_avp_param; s.len = strlen(s.s);
568 if (pv_parse_spec(&s, &avp_spec)==0
569 || avp_spec.type!=PVT_AVP) {
570 LM_ERR("Malformed or non AVP definition <%s>\n", rpid_avp_param);
571 return -1;
572 }
574 if(pv_get_avp_name(0, &(avp_spec.pvp), &rpid_avp, &avp_flags)!=0) {
575 LM_ERR("Invalid AVP definition <%s>\n", rpid_avp_param);
576 return -1;
577 }
578 rpid_avp_type = avp_flags;
579 } else {
580 LM_ERR("AVP rpid_avp has not been defined\n");
581 return -1;
582 }
584 if (flags_avp_param && *flags_avp_param) {
585 s.s = flags_avp_param; s.len = strlen(s.s);
586 if (pv_parse_spec(&s, &avp_spec)==0
587 || avp_spec.type!=PVT_AVP) {
588 LM_ERR("Malformed or non AVP definition <%s>\n", flags_avp_param);
589 return -1;
590 }
592 if(pv_get_avp_name(0, &(avp_spec.pvp), &flags_avp, &avp_flags)!=0) {
593 LM_ERR("Invalid AVP definition <%s>\n", flags_avp_param);
594 return -1;
595 }
596 flags_avp_type = avp_flags;
597 } else {
598 LM_ERR("AVP flags_avp has not been defined\n");
599 return -1;
600 }
602 if (user_avp_param && *user_avp_param) {
603 s.s = user_avp_param; s.len = strlen(s.s);
604 if (pv_parse_spec(&s, &avp_spec)==0
605 || avp_spec.type!=PVT_AVP) {
606 LM_ERR("Malformed or non AVP definition <%s>\n", user_avp_param);
607 return -1;
608 }
610 if(pv_get_avp_name(0, &(avp_spec.pvp), &user_avp, &avp_flags)!=0) {
611 LM_ERR("Invalid AVP definition <%s>\n", user_avp_param);
612 return -1;
613 }
614 user_avp_type = avp_flags;
615 } else {
616 LM_ERR("AVP user_avp has not been defined\n");
617 return -1;
618 }
620 if (realm_avp_param && *realm_avp_param) {
621 s.s = realm_avp_param; s.len = strlen(s.s);
622 if (pv_parse_spec(&s, &avp_spec)==0
623 || avp_spec.type!=PVT_AVP) {
624 LM_ERR("Malformed or non AVP definition <%s>\n", realm_avp_param);
625 return -1;
626 }
628 if(pv_get_avp_name(0, &(avp_spec.pvp), &realm_avp, &avp_flags)!=0) {
629 LM_ERR("Invalid AVP definition <%s>\n", realm_avp_param);
630 return -1;
631 }
632 realm_avp_type = avp_flags;
633 } else {
634 LM_ERR("AVP realm_avp has not been defined\n");
635 return -1;
636 }
638 if (passwd_avp_param && *passwd_avp_param) {
639 s.s = passwd_avp_param; s.len = strlen(s.s);
640 if (pv_parse_spec(&s, &avp_spec)==0
641 || avp_spec.type!=PVT_AVP) {
642 LM_ERR("Malformed or non AVP definition <%s>\n", passwd_avp_param);
643 return -1;
644 }
646 if(pv_get_avp_name(0, &(avp_spec.pvp), &passwd_avp, &avp_flags)!=0) {
647 LM_ERR("Invalid AVP definition <%s>\n", passwd_avp_param);
648 return -1;
649 }
650 passwd_avp_type = avp_flags;
651 } else {
652 LM_ERR("AVP passwd_avp has not been defined\n");
653 return -1;
654 }
656 /* Check table version */
657 db_con_t* dbh;
658 if (lcr_dbf.init==0){
659 LM_CRIT("Unbound database\n");
660 return -1;
661 }
662 dbh=lcr_dbf.init(&db_url);
663 if (dbh==0){
664 LM_ERR("Unable to open database connection\n");
665 return -1;
666 }
667 if((db_check_table_version(&lcr_dbf, dbh, &gw_table, GW_TABLE_VERSION) < 0) ||
668 (db_check_table_version(&lcr_dbf, dbh, &lcr_table, LCR_TABLE_VERSION) < 0)) {
669 LM_ERR("error during table version check.\n");
670 lcr_dbf.close(dbh);
671 goto err;
672 }
673 lcr_dbf.close(dbh);
675 /* Initializing gw tables and gw table pointer variable */
676 gws_1 = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
677 (MAX_NO_OF_GWS + 1));
678 if (gws_1 == 0) {
679 LM_ERR("No memory for gw table\n");
680 goto err;
681 }
682 gws_2 = (struct gw_info *)shm_malloc(sizeof(struct gw_info) *
683 (MAX_NO_OF_GWS + 1));
684 if (gws_2 == 0) {
685 LM_ERR("No memory for gw table\n");
686 goto err;
687 }
688 for (i = 0; i < MAX_NO_OF_GWS + 1; i++) {
689 gws_1[i].ip_addr = gws_2[i].ip_addr = 0;
690 }
691 gws = (struct gw_info **)shm_malloc(sizeof(struct gw_info *));
692 if (gws == 0) {
693 LM_ERR("No memory for gw table pointer\n");
694 }
695 *gws = gws_1;
697 /* Initializing lcr tables and lcr table pointer variable */
698 lcrs_1 = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info) *
699 (MAX_NO_OF_LCRS + 1));
700 if (lcrs_1 == 0) {
701 LM_ERR("No memory for lcr table\n");
702 goto err;
703 }
704 lcrs_2 = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info) *
705 (MAX_NO_OF_LCRS + 1));
706 if (lcrs_2 == 0) {
707 LM_ERR("No memory for lcr table\n");
708 goto err;
709 }
710 for (i = 0; i < MAX_NO_OF_LCRS + 1; i++) {
711 lcrs_1[i].end_record = lcrs_2[i].end_record = 0;
712 }
713 lcrs = (struct lcr_info **)shm_malloc(sizeof(struct lcr_info *));
714 if (lcrs == 0) {
715 LM_ERR("No memory for lcr table pointer\n");
716 goto err;
717 }
718 *lcrs = lcrs_1;
720 lcrs_ws_reload_counter = (unsigned int *)shm_malloc(sizeof(unsigned int));
721 if (lcrs_ws_reload_counter == 0) {
722 LM_ERR("No memory for reload counter\n");
723 goto err;
724 }
725 *lcrs_ws_reload_counter = reload_counter = 0;
727 memset(prefix_reg, 0, sizeof(struct prefix_regex) * MAX_NO_OF_LCRS);
728 memset(from_uri_reg, 0, sizeof(struct from_uri_regex) * MAX_NO_OF_LCRS);
730 /* First reload */
731 if (reload_gws() == -1) {
732 LM_CRIT("Failed to reload gateways and routes\n");
733 goto err;
734 }
736 return 0;
738 err:
739 return -1;
740 }
743 static void destroy(void)
744 {
745 lcr_db_close();
746 }
748 /*
749 * Sort lcr records by prefix_len and priority.
750 */
751 static int comp_lcrs(const void *m1, const void *m2)
752 {
753 int result = -1;
755 struct mi *mi1 = (struct mi *) m1;
756 struct mi *mi2 = (struct mi *) m2;
758 struct lcr_info lcr_record1 = (*lcrs)[mi1->route_index];
759 struct lcr_info lcr_record2 = (*lcrs)[mi2->route_index];
761 if (prefix_mode_param == 0) {
762 /* Sort by prefix. */
763 if (lcr_record1.prefix_len > lcr_record2.prefix_len) {
764 result = 1;
765 } else if (lcr_record1.prefix_len == lcr_record2.prefix_len) {
766 /* Sort by priority. */
767 if (lcr_record1.priority < lcr_record2.priority) {
768 result = 1;
769 } else if (lcr_record1.priority == lcr_record2.priority) {
770 /* Nothing to do. */
771 result = 0;
772 }
773 }
774 } else {
775 if (lcr_record1.priority < lcr_record2.priority) {
776 result = 1;
777 } else if (lcr_record1.priority == lcr_record2.priority) {
778 /* Nothing to do. */
779 result = 0;
780 }
781 }
783 return result;
784 }
786 /*
787 * Sort lcr records by rand table.
788 */
789 static int rand_lcrs(const void *m1, const void *m2)
790 {
791 int result = -1;
793 struct mi mi1 = *((struct mi *) m1);
794 struct mi mi2 = *((struct mi *) m2);
796 if (mi1.randomizer > mi2.randomizer) {
797 result = 1;
798 } else if (mi1.randomizer == mi2.randomizer) {
799 result = 0;
800 }
802 return result;
803 }
805 /*
806 * regcomp each prefix.
807 */
808 static int load_prefix_regex(void)
809 {
810 int i, status, result = 0;
812 for (i = 0; i < MAX_NO_OF_LCRS; i++) {
813 if ((*lcrs)[i].end_record != 0) {
814 break;
815 }
816 if (prefix_reg[i].valid) {
817 regfree(&(prefix_reg[i].re));
818 prefix_reg[i].valid = 0;
819 }
820 memset(&(prefix_reg[i].re), 0, sizeof(regex_t));
821 if ((status=regcomp(&(prefix_reg[i].re),(*lcrs)[i].prefix,0))!=0){
822 LM_ERR("bad prefix re <%s>, regcomp returned %d (check regex.h)\n",
823 (*lcrs)[i].prefix, status);
824 result = -1;
825 break;
826 }
827 prefix_reg[i].valid = 1;
828 }
830 return result;
831 }
833 /*
834 * regcomp each from_uri.
835 */
836 static int load_from_uri_regex(void)
837 {
838 int i, status, result = 0;
840 for (i = 0; i < MAX_NO_OF_LCRS; i++) {
841 if ((*lcrs)[i].end_record != 0) {
842 break;
843 }
844 if (from_uri_reg[i].valid) {
845 regfree(&(from_uri_reg[i].re));
846 from_uri_reg[i].valid = 0;
847 }
848 memset(&(from_uri_reg[i].re), 0, sizeof(regex_t));
849 if ((status=regcomp(&(from_uri_reg[i].re),(*lcrs)[i].from_uri,0))!=0){
850 LM_ERR("Bad from_uri re <%s>, regcomp returned %d (check regex.h)\n",
851 (*lcrs)[i].from_uri, status);
852 result = -1;
853 break;
854 }
855 from_uri_reg[i].valid = 1;
856 }
858 if (result != -1) {
859 reload_counter = *lcrs_ws_reload_counter;
860 }
861 return result;
862 }
864 static int load_all_regex(void)
865 {
866 int result =0;
868 if (prefix_mode_param != 0) {
869 result = load_prefix_regex();
870 }
872 if (result == 0) {
873 result = load_from_uri_regex();
874 } else {
875 LM_ERR("Unable to load prefix regex\n");
876 }
878 if (result == 0) {
879 reload_counter = *lcrs_ws_reload_counter;
880 } else {
881 LM_ERR("Unable to load from_uri regex\n");
882 }
884 return result;
885 }
887 /*
888 * Reload gws to unused gw table and lcrs to unused lcr table, and, when done
889 * make unused gw and lcr table the one in use.
890 */
891 int reload_gws(void)
892 {
893 unsigned int i, port, strip, tag_len, prefix_len, from_uri_len,
894 user_len, realm_len, passwd_len, grp_id, priority;
895 struct in_addr ip_addr;
896 unsigned int flags;
897 uri_type scheme;
898 uri_transport transport;
899 db_con_t* dbh;
900 char *tag, *prefix, *from_uri;
901 char *user, *realm, *passwd;
902 db_res_t* res = NULL;
903 db_row_t* row;
904 db_key_t gw_cols[11];
905 db_key_t lcr_cols[4];
907 gw_cols[0] = &ip_addr_col;
908 gw_cols[1] = &port_col;
909 gw_cols[2] = &uri_scheme_col;
910 gw_cols[3] = &transport_col;
911 gw_cols[4] = &strip_col;
912 gw_cols[5] = &tag_col;
913 /* FIXME: is this ok if we have different names for grp_id
914 in the two tables? (ge vw lcr) */
915 gw_cols[6] = &grp_id_col;
916 gw_cols[7] = &flags_col;
917 gw_cols[8] = &user_col;
918 gw_cols[9] = &realm_col;
919 gw_cols[10] = &passwd_col;
921 lcr_cols[0] = &prefix_col;
922 lcr_cols[1] = &from_uri_col;
923 /* FIXME: is this ok if we have different names for grp_id
924 in the two tables? (ge vw lcr) */
925 lcr_cols[2] = &grp_id_col;
926 lcr_cols[3] = &priority_col;
928 if (lcr_dbf.init==0){
929 LM_CRIT("Unbound database\n");
930 return -1;
931 }
932 dbh=lcr_dbf.init(&db_url);
933 if (dbh==0){
934 LM_ERR("Unable to open database connection\n");
935 return -1;
936 }
938 if (lcr_dbf.use_table(dbh, &gw_table) < 0) {
939 LM_ERR("Error while trying to use gw table\n");
940 return -1;
941 }
943 if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 11, 0, &res) < 0) {
944 LM_ERR("Failed to query gw data\n");
945 lcr_dbf.close(dbh);
946 return -1;
947 }
949 if (RES_ROW_N(res) + 1 > MAX_NO_OF_GWS) {
950 LM_ERR("Too many gateways\n");
951 lcr_dbf.free_result(dbh, res);
952 lcr_dbf.close(dbh);
953 return -1;
954 }
956 for (i = 0; i < RES_ROW_N(res); i++) {
957 row = RES_ROWS(res) + i;
958 if (!((VAL_TYPE(ROW_VALUES(row)) == DB_STRING) &&
959 !VAL_NULL(ROW_VALUES(row)) &&
960 inet_aton((char *)VAL_STRING(ROW_VALUES(row)), &ip_addr) != 0)) {
961 LM_ERR("Invalid IP address of gw <%s>\n",
962 (char *)VAL_STRING(ROW_VALUES(row)));
963 lcr_dbf.free_result(dbh, res);
964 lcr_dbf.close(dbh);
965 return -1;
966 }
967 if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {
968 port = 0;
969 } else {
970 port = (unsigned int)VAL_INT(ROW_VALUES(row) + 1);
971 }
972 if (port > 65536) {
973 LM_ERR("Port of gw is too large <%u>\n", port);
974 lcr_dbf.free_result(dbh, res);
975 lcr_dbf.close(dbh);
976 return -1;
977 }
978 if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {
979 scheme = SIP_URI_T;
980 } else {
981 scheme = (uri_type)VAL_INT(ROW_VALUES(row) + 2);
982 if ((scheme != SIP_URI_T) && (scheme != SIPS_URI_T)) {
983 LM_ERR("Unknown or unsupported URI scheme <%u>\n",
984 (unsigned int)scheme);
985 lcr_dbf.free_result(dbh, res);
986 lcr_dbf.close(dbh);
987 return -1;
988 }
989 }
990 if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {
991 transport = PROTO_NONE;
992 } else {
993 transport = (uri_transport)VAL_INT(ROW_VALUES(row) + 3);
994 if ((transport != PROTO_UDP) && (transport != PROTO_TCP) &&
995 (transport != PROTO_TLS)) {
996 LM_ERR("Unknown or unsupported transport <%u>\n",
997 (unsigned int)transport);
998 lcr_dbf.free_result(dbh, res);
999 lcr_dbf.close(dbh);
1000 return -1;
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 }