From 9dbf01e87f771976fbf729107e63bc5eca287171 Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Sat, 2 Oct 2021 22:13:23 +0300 Subject: [PATCH] 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 --- debian/patches/series | 1 + ...improve_comparison_based_on_gws_port.patch | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 debian/patches/sipwise/lcr_improve_comparison_based_on_gws_port.patch diff --git a/debian/patches/series b/debian/patches/series index bc188458e..ec12fee9f 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -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 diff --git a/debian/patches/sipwise/lcr_improve_comparison_based_on_gws_port.patch b/debian/patches/sipwise/lcr_improve_comparison_based_on_gws_port.patch new file mode 100644 index 000000000..3ee0f624d --- /dev/null +++ b/debian/patches/sipwise/lcr_improve_comparison_based_on_gws_port.patch @@ -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],