diff --git a/debian/patches/series b/debian/patches/series index 9efd85c17..bc188458e 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -40,6 +40,7 @@ upstream/pv_headers-fix-removal-of-all-values-on-when-using-P.patch upstream/pv_headers-pvh_set_header-remove-values-to-set-null-.patch upstream/lcr-source-port-check-for-from_any_gw-and-from_gw.patch upstream/lcr-remove-excessive-checks-for-the-src_port-accurac.patch +upstream/lcr-improve-binary-search-to-support-match-including-src-port.patch ### relevant for upstream sipwise/pua_dialoginfo-refresh_pubruri_avps_flag.patch sipwise/pua_dialoginfo-local_identity_dlg_var.patch diff --git a/debian/patches/upstream/lcr-improve-binary-search-to-support-match-including-src-port.patch b/debian/patches/upstream/lcr-improve-binary-search-to-support-match-including-src-port.patch new file mode 100644 index 000000000..cbdf36839 --- /dev/null +++ b/debian/patches/upstream/lcr-improve-binary-search-to-support-match-including-src-port.patch @@ -0,0 +1,146 @@ +From e82819e6613dd64ca5c887759eab18cd38d20373 Mon Sep 17 00:00:00 2001 +From: Donat Zenichev +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 +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 +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 +