Index: modules/lcr/lcr_mod.c =================================================================== RCS file: /cvsroot/openser/sip-server/modules/lcr/lcr_mod.c,v retrieving revision 1.25 diff -u -r1.25 lcr_mod.c --- modules/lcr/lcr_mod.c 21 Mar 2006 12:53:10 -0000 1.25 +++ modules/lcr/lcr_mod.c 27 Apr 2006 13:04:47 -0000 @@ -73,6 +73,7 @@ static void destroy(void); /* Module destroy function */ static int child_init(int rank); /* Per-child initialization function */ static int mod_init(void); /* Module initialization function */ +static int fixstring2int(void **param, int param_count); /* string to int fixup */ int reload_gws ( void ); @@ -221,9 +222,12 @@ * Module functions that are defined later */ int load_gws(struct sip_msg* _m, char* _s1, char* _s2); +int load_gws_grp(struct sip_msg* _m, char* _s1, char* _s2); int next_gw(struct sip_msg* _m, char* _s1, char* _s2); int from_gw(struct sip_msg* _m, char* _s1, char* _s2); +int from_gw_grp(struct sip_msg* _m, char* _s1, char* _s2); int to_gw(struct sip_msg* _m, char* _s1, char* _s2); +int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2); int load_contacts (struct sip_msg*, char*, char*); int next_contacts (struct sip_msg*, char*, char*); @@ -232,9 +236,12 @@ */ static cmd_export_t cmds[] = { {"load_gws", load_gws, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, + {"load_gws", load_gws_grp, 1, fixstring2int, REQUEST_ROUTE | FAILURE_ROUTE}, {"next_gw", next_gw, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, {"from_gw", from_gw, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + {"from_gw", from_gw_grp, 1, fixstring2int, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, {"to_gw", to_gw, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, + {"to_gw", to_gw_grp, 1, fixstring2int, REQUEST_ROUTE | FAILURE_ROUTE}, {"load_contacts", load_contacts, 0, 0, REQUEST_ROUTE}, {"next_contacts", next_contacts, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, {0, 0, 0, 0, 0} @@ -959,11 +966,10 @@ } } - /* * Load info of matching GWs from database to gw_uri AVPs */ -int load_gws(struct sip_msg* _m, char* _s1, char* _s2) +static int do_load_gws(struct sip_msg* _m, int grp_id) { db_res_t* res; db_row_t *row, *r; @@ -1034,22 +1040,42 @@ } if (db_mode == 0) { - q_len = snprintf(query, MAX_QUERY_SIZE, "SELECT %.*s.%.*s, %.*s.%.*s, %.*s.%.*s, %.*s.%.*s, %.*s.%.*s, %.*s.%.*s FROM %.*s, %.*s WHERE '%.*s' LIKE %.*s.%.*s AND '%.*s' LIKE CONCAT(%.*s.%.*s, '%%') AND %.*s.%.*s = %.*s.%.*s ORDER BY CHAR_LENGTH(%.*s.%.*s), %.*s.%.*s DESC, RAND()", - gw_table.len, gw_table.s, ip_addr_col.len, ip_addr_col.s, - gw_table.len, gw_table.s, port_col.len, port_col.s, - gw_table.len, gw_table.s, uri_scheme_col.len, uri_scheme_col.s, - gw_table.len, gw_table.s, transport_col.len, transport_col.s, - gw_table.len, gw_table.s, strip_col.len, strip_col.s, - gw_table.len, gw_table.s, prefix_col.len, prefix_col.s, - gw_table.len, gw_table.s, lcr_table.len, lcr_table.s, - from_uri.len, from_uri.s, - lcr_table.len, lcr_table.s, from_uri_col.len, from_uri_col.s, - ruri_user.len, ruri_user.s, - lcr_table.len, lcr_table.s, prefix_col.len, prefix_col.s, - lcr_table.len, lcr_table.s, grp_id_col.len, grp_id_col.s, - gw_table.len, gw_table.s, grp_id_col.len, grp_id_col.s, - lcr_table.len, lcr_table.s, prefix_col.len, prefix_col.s, - lcr_table.len, lcr_table.s, priority_col.len, priority_col.s); + if(grp_id >= 0) { + q_len = snprintf(query, MAX_QUERY_SIZE, "SELECT %.*s.%.*s, %.*s.%.*s, %.*s.%.*s, %.*s.%.*s, %.*s.%.*s, %.*s.%.*s FROM %.*s, %.*s WHERE %.*s.%.*s = %d AND '%.*s' LIKE %.*s.%.*s AND '%.*s' LIKE CONCAT(%.*s.%.*s, '%%') AND %.*s.%.*s = %.*s.%.*s ORDER BY CHAR_LENGTH(%.*s.%.*s), %.*s.%.*s DESC, RAND()", + gw_table.len, gw_table.s, ip_addr_col.len, ip_addr_col.s, + gw_table.len, gw_table.s, port_col.len, port_col.s, + gw_table.len, gw_table.s, uri_scheme_col.len, uri_scheme_col.s, + gw_table.len, gw_table.s, transport_col.len, transport_col.s, + gw_table.len, gw_table.s, strip_col.len, strip_col.s, + gw_table.len, gw_table.s, prefix_col.len, prefix_col.s, + gw_table.len, gw_table.s, lcr_table.len, lcr_table.s, + lcr_table.len, lcr_table.s, grp_id_col.len, grp_id_col.s, grp_id, + from_uri.len, from_uri.s, + lcr_table.len, lcr_table.s, from_uri_col.len, from_uri_col.s, + ruri_user.len, ruri_user.s, + lcr_table.len, lcr_table.s, prefix_col.len, prefix_col.s, + lcr_table.len, lcr_table.s, grp_id_col.len, grp_id_col.s, + gw_table.len, gw_table.s, grp_id_col.len, grp_id_col.s, + lcr_table.len, lcr_table.s, prefix_col.len, prefix_col.s, + lcr_table.len, lcr_table.s, priority_col.len, priority_col.s); + } else { + q_len = snprintf(query, MAX_QUERY_SIZE, "SELECT %.*s.%.*s, %.*s.%.*s, %.*s.%.*s, %.*s.%.*s, %.*s.%.*s, %.*s.%.*s FROM %.*s, %.*s WHERE '%.*s' LIKE %.*s.%.*s AND '%.*s' LIKE CONCAT(%.*s.%.*s, '%%') AND %.*s.%.*s = %.*s.%.*s ORDER BY CHAR_LENGTH(%.*s.%.*s), %.*s.%.*s DESC, RAND()", + gw_table.len, gw_table.s, ip_addr_col.len, ip_addr_col.s, + gw_table.len, gw_table.s, port_col.len, port_col.s, + gw_table.len, gw_table.s, uri_scheme_col.len, uri_scheme_col.s, + gw_table.len, gw_table.s, transport_col.len, transport_col.s, + gw_table.len, gw_table.s, strip_col.len, strip_col.s, + gw_table.len, gw_table.s, prefix_col.len, prefix_col.s, + gw_table.len, gw_table.s, lcr_table.len, lcr_table.s, + from_uri.len, from_uri.s, + lcr_table.len, lcr_table.s, from_uri_col.len, from_uri_col.s, + ruri_user.len, ruri_user.s, + lcr_table.len, lcr_table.s, prefix_col.len, prefix_col.s, + lcr_table.len, lcr_table.s, grp_id_col.len, grp_id_col.s, + gw_table.len, gw_table.s, grp_id_col.len, grp_id_col.s, + lcr_table.len, lcr_table.s, prefix_col.len, prefix_col.s, + lcr_table.len, lcr_table.s, priority_col.len, priority_col.s); + } if (q_len >= MAX_QUERY_SIZE) { LOG(L_ERR, "load_gws(): Too long database query\n"); return -1; @@ -1199,7 +1225,7 @@ if ((*gws)[j].ip_addr == 0) { break; } - if (lcr_rec.grp_id == (*gws)[j].grp_id) { + if (lcr_rec.grp_id == (*gws)[j].grp_id && (grp_id < 0 || (*gws)[j].grp_id == grp_id)) { /* 3. grp_id matching is done */ for (k = 0; k < gw_index; k++) { if ((*gws)[j].ip_addr == @@ -1392,6 +1418,28 @@ } } +/* + * Load info of matching GWs from database to gw_uri AVPs + * taking into account the given group id. + */ +int load_gws_grp(struct sip_msg* _m, char* _s1, char* _s2) +{ + int grp_id; + + grp_id = (int)(long)_s1; + return do_load_gws(_m, grp_id); +} + +/* + * Load info of matching GWs from database to gw_uri AVPs + * ignoring the group id. + */ +int load_gws(struct sip_msg* _m, char* _s1, char* _s2) +{ + return do_load_gws(_m, -1); +} + + /* * If called from request route block, rewrites scheme, host, port, and @@ -1532,7 +1580,7 @@ /* * Checks if request comes from a gateway */ -int from_gw(struct sip_msg* _m, char* _s1, char* _s2) +static int do_from_gw(struct sip_msg* _m, int grp_id) { int i; unsigned int src_addr; @@ -1543,7 +1591,8 @@ if ((*gws)[i].ip_addr == 0) { return -1; } - if ((*gws)[i].ip_addr == src_addr) { + if ((*gws)[i].ip_addr == src_addr && + (grp_id < 0 || (*gws)[i].grp_id == grp_id)) { return 1; } } @@ -1553,9 +1602,31 @@ /* + * Checks if request comes from a gateway, taking + * into account the group id. + */ +int from_gw_grp(struct sip_msg* _m, char* _s1, char* _s2) +{ + int grp_id; + + grp_id = (int)(long)_s1; + return do_from_gw(_m, grp_id); +} + +/* + * Checks if request comes from a gateway, ignoring + * the group id. + */ +int from_gw(struct sip_msg* _m, char* _s1, char* _s2) +{ + return do_from_gw(_m, -1); +} + + +/* * Checks if in-dialog request goes to gateway */ -int to_gw(struct sip_msg* _m, char* _s1, char* _s2) +static int do_to_gw(struct sip_msg* _m, int grp_id) { char host[16]; struct in_addr addr; @@ -1580,7 +1651,8 @@ if ((*gws)[i].ip_addr == 0) { return -1; } - if ((*gws)[i].ip_addr == addr.s_addr) { + if ((*gws)[i].ip_addr == addr.s_addr && + (grp_id < 0 || (*gws)[i].grp_id == grp_id)) { return 1; } } @@ -1589,6 +1661,29 @@ } +/* + * Checks if in-dialog request goes to gateway, taking + * into account the group id. + */ +int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2) +{ + int grp_id; + + grp_id = (int)(long)_s1; + return do_to_gw(_m, grp_id); +} + + +/* + * Checks if in-dialog request goes to gateway, ignoring + * the group id. + */ +int to_gw(struct sip_msg* _m, char* _s1, char* _s2) +{ + return do_to_gw(_m, -1); +} + + /* * Frees contact list used by load_contacts function */ @@ -1825,3 +1920,28 @@ return 1; } + +/* + * Convert string parameter to integer for functions that expect an integer. + * Taken from mediaproxy module. + */ +static int fixstring2int(void **param, int param_count) +{ + unsigned long number; + int err; + + if (param_count == 1) { + number = str2s(*param, strlen(*param), &err); + if (err == 0) { + pkg_free(*param); + *param = (void*)number; + return 0; + } else { + LOG(L_ERR, "lcr/fixstring2int(): ERROR: bad number `%s'\n", + (char*)(*param)); + return E_CFG; + } + } + return 0; +} + Index: modules/lcr/doc/lcr_user.sgml =================================================================== RCS file: /cvsroot/openser/sip-server/modules/lcr/doc/lcr_user.sgml,v retrieving revision 1.9 diff -u -r1.9 lcr_user.sgml --- modules/lcr/doc/lcr_user.sgml 11 Jan 2006 11:38:55 -0000 1.9 +++ modules/lcr/doc/lcr_user.sgml 27 Apr 2006 13:04:48 -0000 @@ -67,8 +67,7 @@ In addition to gw and lcr tables there is third table gw_grp that is - used for administrative purposes only to associate names with gateway - group ids. + used to associate names with gateway group ids. @@ -594,6 +593,30 @@
+ <function moreinfo="none">load_gws(int)</function> + + + Loads URI schemes, addresses, ports, and transports of gateways + that match user part of Request-URI and the given group id to + gw_uri_avp AVPs. Returns 1 or -1 depending on success. + + + This function can be used from REQUEST_ROUTE. + + + <function>load_gws</function> usage + +... +if (!load_gws("1")) { + sl_send_reply("500", "Server Internal Error - Cannot load gateways of group 1"); + break; +}; +... + + +
+
+ <function moreinfo="none">next_gw()</function> @@ -666,6 +689,30 @@
+
+ + <function moreinfo="none">from_gw(int)</function> + + + Checks if request came from IP address of a gateway belonging + to the group with the given id. + + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, + ONREPLY_ROUTE. + + + <function>from_gw</function> usage + +... +if (from_gw("1")) { + ... + break; +}; +... + + +
<function moreinfo="none">to_gw()</function> @@ -688,6 +735,29 @@ </programlisting> </example> </section> + <section> + <title> + <function moreinfo="none">to_gw(int)</function> + + + Checks if in-dialog request goes to a gateway belonging to + the group with the given id. + + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + + <function>to_gw</function> usage + +... +if (to_gw("1")) { + ... + break; +}; +... + + +
<function moreinfo="none">load_contacts()</function>