TT#143950 lcr: add new function for searching gw based on IP and src_port

It has been noticed, that after a list of contributions into lcr.so of kamailio,
the from_gw() and from_any_gw() functions are not working fully correct.

However it is only related to the usage with the third parameter 'src_port'.
Last time (last commit into lcr.so), the back compatibility was provided not to break anything for the kamailio community,
this means, it's only related to usage with the 'src_port' parameter.

from_gw() and from_any_gw() functions are not working fine,
when we have tens of gateways with the same IP address in the 'lcr_gw', and you use src_port for searching as well.
It works fine, if you have 2-5 gateways, but not with tens of them.

This is all the matter of the implementation and some limitations of how
the iteration through the memory is done (memory allocated for a list of specific structures),
and binary search used for that.

This is our own Sipwise's patch to handle that case which is intended to be kept internally.
This patch introduces a more simple iteration, but it works more efficient,
when the search for two objects at a time for matching items is done.

Change-Id: I0e7fb2ea59edb7d22636e58f002ca9cb59d42315
mr10.1
Donat Zenichev 5 years ago committed by Víctor Seva
parent 3d3b5c115b
commit 9dbf01e87f

@ -56,6 +56,7 @@ sipwise/db_redis_sscan_fix_empty_key.patch
sipwise/kamctl-TMPDIR-config.patch
### active development
sipwise/lcr-stopper_mode-parameter.patch
sipwise/lcr_improve_comparison_based_on_gws_port.patch
#
### Don't just put stuff in any order
### use gbp pq import/export tooling to help maintain patches

@ -0,0 +1,40 @@
--- a/src/modules/lcr/lcr_mod.c
+++ b/src/modules/lcr/lcr_mod.c
@@ -951,6 +951,27 @@ static int comp_gws_include_port(const v
return memcmp(g1->ip_addr.u.addr, g2->ip_addr.u.addr, g1->ip_addr.len);
}
+/*
+ * Find a gateway using IP address and the src port
+ */
+static struct gw_info * find_gateway_by_ip_and_port(struct gw_info * gw, struct gw_info * gws) {
+ int tmp = 0, gw_index = 0;
+
+ for (int i = 1; i <= gws[0].ip_addr.u.addr32[0]; i++) {
+ tmp = memcmp(gws[i].ip_addr.u.addr, gw->ip_addr.u.addr, gws[i].ip_addr.len);
+ if (gws[i].ip_addr.af == gw->ip_addr.af &&
+ gws[i].ip_addr.len == gw->ip_addr.len &&
+ tmp == 0 && /* a comparison of the IP address value */
+ gws[i].port == gw->port) {
+ gw_index = i;
+ break;
+ }
+ }
+ if (gw_index != 0) return &(gws[gw_index]);
+
+ return NULL;
+}
+
/*
* Insert gw info into index i or gws table
*/
@@ -3061,8 +3082,7 @@ static int do_from_gw(struct sip_msg *_m
if (src_port != 0) {
/* Search for gw based on its ip address and port */
gw.port = src_port;
- res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr.u.addr32[0],
- sizeof(struct gw_info), comp_gws_include_port);
+ res = find_gateway_by_ip_and_port(&gw, gws);
} else {
/* Search for gw based on its ip address */
res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr.u.addr32[0],
Loading…
Cancel
Save