mirror of https://github.com/sipwise/kamailio.git
Improve binary search in the lcr module and add a possibility to do a matching not only based on an IP address of a GW, but also using a source port. When a possibility to use 'src_port' parameter in from_gw() and from_any_gw() was introduced, the bsearch() remained untouched, and hence the matching (iteration through existing GWs) is now done only based on an IP address. This leads to the issue, when there are more than one GW with the same IP address in gws table, and from_gw() and from_any_gw() functions are used with the 'src_port' parameter, it can happen that a wrong GW is picked out by bsearch() from gws table (lcr_gw) and a check by from_gw() and from_any_gw() returns False. Hence the matching based on IP address and source port is required for bsearch(), when from_gw() and from_any_gw() functions are used with the 'src_port' parameter. This means backwards compatibility is still present (when one uses functions without 'src_port'). Change-Id: I90327ef69d8132cc9e11522567cbc026e0808602mr10.1
parent
672fc64db1
commit
f2417add3e
@ -0,0 +1,146 @@
|
||||
From e82819e6613dd64ca5c887759eab18cd38d20373 Mon Sep 17 00:00:00 2001
|
||||
From: Donat Zenichev <dzenichev@sipwise.com>
|
||||
Date: Fri, 17 Sep 2021 12:56:39 +0300
|
||||
Subject: [PATCH 1/3] lcr: improve binary search to support a match including
|
||||
src port
|
||||
|
||||
Improve binary search in the lcr module and add a possibility
|
||||
to do a matching not only based on an IP address of a GW, but also using a source port.
|
||||
|
||||
When a possibility to use 'src_port' parameter in from_gw() and from_any_gw()
|
||||
was introduced here: 14e6fc80b3d2389567c73c4a2196bf8e6d92d8d2
|
||||
the bsearch() remained untouched, and hence the matching (iteration through existing GWs)
|
||||
is now done only based on an IP address.
|
||||
|
||||
This leads to the issue, when there are more than one GW with the same IP address in gws table,
|
||||
and from_gw() and from_any_gw() functions are used with the 'src_port' parameter,
|
||||
it can happen that a wrong GW is picked out by bsearch() from gws table (lcr_gw) and
|
||||
a check by from_gw() and from_any_gw() returns False.
|
||||
|
||||
Hence the matching based on IP address and source port is required for bsearch(),
|
||||
when from_gw() and from_any_gw() functions are used with the 'src_port' parameter.
|
||||
|
||||
This means backwards compatibility is still present (when one uses functions without 'src_port').
|
||||
---
|
||||
src/modules/lcr/lcr_mod.c | 37 ++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 34 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/modules/lcr/lcr_mod.c b/src/modules/lcr/lcr_mod.c
|
||||
index 21f05a4730..8c5b05d1df 100644
|
||||
--- a/src/modules/lcr/lcr_mod.c
|
||||
+++ b/src/modules/lcr/lcr_mod.c
|
||||
@@ -921,6 +921,30 @@ static int comp_gws(const void *_g1, const void *_g2)
|
||||
return memcmp(g1->ip_addr.u.addr, g2->ip_addr.u.addr, g1->ip_addr.len);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Compare gateways based on their IP address and port
|
||||
+ */
|
||||
+static int comp_gws_include_port(const void *_g1, const void *_g2)
|
||||
+{
|
||||
+ struct gw_info *g1 = (struct gw_info *)_g1;
|
||||
+ struct gw_info *g2 = (struct gw_info *)_g2;
|
||||
+
|
||||
+ /* first address family comparison */
|
||||
+ if(g1->ip_addr.af < g2->ip_addr.af)
|
||||
+ return -1;
|
||||
+ if(g1->ip_addr.af > g2->ip_addr.af)
|
||||
+ return 1;
|
||||
+ if(g1->ip_addr.len < g2->ip_addr.len)
|
||||
+ return -1;
|
||||
+ if(g1->ip_addr.len > g2->ip_addr.len)
|
||||
+ return 1;
|
||||
+
|
||||
+ /* secondly ports comparison */
|
||||
+ if(g1->port != g2->port)
|
||||
+ return -1;
|
||||
+
|
||||
+ return memcmp(g1->ip_addr.u.addr, g2->ip_addr.u.addr, g1->ip_addr.len);
|
||||
+}
|
||||
|
||||
/*
|
||||
* Insert gw info into index i or gws table
|
||||
@@ -2997,10 +3021,17 @@ static int do_from_gw(struct sip_msg *_m, unsigned int lcr_id,
|
||||
return -1;
|
||||
}
|
||||
|
||||
- /* Search for gw ip address */
|
||||
gw.ip_addr = *src_addr;
|
||||
- res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr.u.addr32[0],
|
||||
- sizeof(struct gw_info), comp_gws);
|
||||
+ 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);
|
||||
+ } else {
|
||||
+ /* Search for gw based on its ip address */
|
||||
+ res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr.u.addr32[0],
|
||||
+ sizeof(struct gw_info), comp_gws);
|
||||
+ }
|
||||
|
||||
/* Store tag and flags and return result */
|
||||
if((res != NULL)
|
||||
--
|
||||
2.25.1
|
||||
|
||||
|
||||
From 7a3a54433bbbfdb2521d4f8981c5b72423299bb1 Mon Sep 17 00:00:00 2001
|
||||
From: Donat Zenichev <dzenichev@sipwise.com>
|
||||
Date: Sun, 19 Sep 2021 10:01:53 +0300
|
||||
Subject: [PATCH 2/3] lcr: remove excessive conditional check in do_from_gw()
|
||||
|
||||
After an update of the bsearch(), which now supports matching not only
|
||||
by the IP address, but also using the 'src_port', there is no need to check,
|
||||
if the source port of a request matched the one from the 'lcr_gw'
|
||||
('res' pointer will be NULL anyway, if ports don't match).
|
||||
|
||||
Nor do we need to check if it's zero.
|
||||
---
|
||||
src/modules/lcr/lcr_mod.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/modules/lcr/lcr_mod.c b/src/modules/lcr/lcr_mod.c
|
||||
index 8c5b05d1df..23b5bce0dc 100644
|
||||
--- a/src/modules/lcr/lcr_mod.c
|
||||
+++ b/src/modules/lcr/lcr_mod.c
|
||||
@@ -3035,8 +3035,7 @@ static int do_from_gw(struct sip_msg *_m, unsigned int lcr_id,
|
||||
|
||||
/* Store tag and flags and return result */
|
||||
if((res != NULL)
|
||||
- && ((transport == PROTO_NONE) || (res->transport_code == transport))
|
||||
- && ((src_port == 0) || (res->port == src_port))) {
|
||||
+ && ((transport == PROTO_NONE) || (res->transport_code == transport))) {
|
||||
LM_DBG("request came from gw\n");
|
||||
if(tag_avp_param) {
|
||||
val.s.s = res->tag;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
|
||||
From 10b014b505080a918a8443ff83029a0155364661 Mon Sep 17 00:00:00 2001
|
||||
From: Henning Westerholt <hw@skalatan.de>
|
||||
Date: Mon, 20 Sep 2021 18:14:35 +0000
|
||||
Subject: [PATCH 3/3] lcr: small white-space (related to GH #2859)
|
||||
|
||||
---
|
||||
src/modules/lcr/lcr_mod.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/modules/lcr/lcr_mod.c b/src/modules/lcr/lcr_mod.c
|
||||
index 23b5bce0dc..93c5181600 100644
|
||||
--- a/src/modules/lcr/lcr_mod.c
|
||||
+++ b/src/modules/lcr/lcr_mod.c
|
||||
@@ -3034,8 +3034,7 @@ static int do_from_gw(struct sip_msg *_m, unsigned int lcr_id,
|
||||
}
|
||||
|
||||
/* Store tag and flags and return result */
|
||||
- if((res != NULL)
|
||||
- && ((transport == PROTO_NONE) || (res->transport_code == transport))) {
|
||||
+ if((res != NULL) && ((transport == PROTO_NONE) || (res->transport_code == transport))) {
|
||||
LM_DBG("request came from gw\n");
|
||||
if(tag_avp_param) {
|
||||
val.s.s = res->tag;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
Loading…
Reference in new issue