mirror of https://github.com/sipwise/kamailio.git
A simple change, which allows to check, if a coming request matches not only by an IP address and a transport protocol, but also using the source port of a request. Improvements are done for the following functions of the lcr module: - from_any_gw() - from_gw() Back compatibility provided, hence it does not affect already existing behavior. Change-Id: Id0496fad75ce64f1abecaa4747b4a77ec6b87cbfmr10.1
parent
788f229622
commit
672fc64db1
@ -0,0 +1,48 @@
|
|||||||
|
From 536736f2529f7554929f3aa6b74ac616c382bc6e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Donat Zenichev <dzenichev@sipwise.com>
|
||||||
|
Date: Tue, 24 Aug 2021 18:50:16 +0300
|
||||||
|
Subject: [PATCH 1/2] lcr: remove excessive checks for the 'src_port' accuracy
|
||||||
|
|
||||||
|
Remove unneeded check for 'src_port' in:
|
||||||
|
- ki_from_any_gw_addr()
|
||||||
|
- ki_from_gw_addr()
|
||||||
|
|
||||||
|
Which makes no sense because 'src_port' is of type 'unsigned int',
|
||||||
|
and the check concerns whether it's less than 0 or not.
|
||||||
|
---
|
||||||
|
src/modules/lcr/lcr_mod.c | 12 ++++++------
|
||||||
|
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/modules/lcr/lcr_mod.c b/src/modules/lcr/lcr_mod.c
|
||||||
|
index 858352f2c7..57b4021ac9 100644
|
||||||
|
--- a/src/modules/lcr/lcr_mod.c
|
||||||
|
+++ b/src/modules/lcr/lcr_mod.c
|
||||||
|
@@ -3093,9 +3093,9 @@ static int ki_from_gw_addr(
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* src_port set to 0 means we don't want to check it */
|
||||||
|
- if((src_port < 0) || (src_port > 65535)) {
|
||||||
|
- LM_ERR("invalid port parameter value %d\n", transport);
|
||||||
|
+ /* src_port set to 0 is allowed and means we don't want to check it */
|
||||||
|
+ if(src_port > 65535) {
|
||||||
|
+ LM_ERR("invalid port parameter value %d\n", src_port);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3215,9 +3215,9 @@ static int ki_from_any_gw_addr(sip_msg_t *_m, str *addr_str, int transport, unsi
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* src_port set to 0 means we don't want to check it */
|
||||||
|
- if((src_port < 0) || (src_port > 65535)) {
|
||||||
|
- LM_ERR("invalid port parameter value %d\n", transport);
|
||||||
|
+ /* src_port set to 0 is allowed and means we don't want to check it */
|
||||||
|
+ if(src_port > 65535) {
|
||||||
|
+ LM_ERR("invalid port parameter value %d\n", src_port);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
@ -0,0 +1,338 @@
|
|||||||
|
From 9115d74b33aefb0febad7c7fffe7d184e4066b77 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Donat Zenichev <dzenichev@sipwise.com>
|
||||||
|
Date: Mon, 23 Aug 2021 21:50:50 +0300
|
||||||
|
Subject: [PATCH 2/2] lcr: source port check for from_any_gw() and from_gw().
|
||||||
|
|
||||||
|
A simple change, which allows to check, if a coming request matches
|
||||||
|
not only by an IP address and a transport protocol,
|
||||||
|
but also using the source port of a request.
|
||||||
|
|
||||||
|
Improvements are done for the following functions of the lcr module:
|
||||||
|
- from_any_gw()
|
||||||
|
- from_gw()
|
||||||
|
|
||||||
|
Back compatibility provided, hence it does not affect already existing behavior.
|
||||||
|
---
|
||||||
|
src/modules/lcr/doc/lcr_admin.xml | 31 ++++----
|
||||||
|
src/modules/lcr/lcr_mod.c | 116 +++++++++++++++++++++++++-----
|
||||||
|
2 files changed, 116 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/modules/lcr/doc/lcr_admin.xml b/src/modules/lcr/doc/lcr_admin.xml
|
||||||
|
index 2c5bfb0d85..f6461e1a24 100644
|
||||||
|
--- a/src/modules/lcr/doc/lcr_admin.xml
|
||||||
|
+++ b/src/modules/lcr/doc/lcr_admin.xml
|
||||||
|
@@ -1425,16 +1425,16 @@ defunct_gw(60);
|
||||||
|
|
||||||
|
<section id="lcr.f.from_gw">
|
||||||
|
<title>
|
||||||
|
- <function moreinfo="none">from_gw(lcr_id[, ip_addr, proto])</function>
|
||||||
|
+ <function moreinfo="none">from_gw(lcr_id[, ip_addr, proto[, src_port]])</function>
|
||||||
|
</title>
|
||||||
|
<para>
|
||||||
|
- Checks if request comes from IP address and transport protocol
|
||||||
|
+ Checks if request comes from IP address, transport protocol and source port
|
||||||
|
specified for a gateway in LCR instance lcr_id.
|
||||||
|
Fails if the LCR instance includes
|
||||||
|
one or more gateways without IP address.
|
||||||
|
- IP address and transport protocol to be checked are either
|
||||||
|
- taken from source IP address of the request or
|
||||||
|
- (if present) from ip_addr and proto arguments.
|
||||||
|
+ IP address, transport protocol and source port to be checked are either
|
||||||
|
+ taken from source IP address and port of the request or
|
||||||
|
+ (if present) from ip_addr, proto and src_port arguments.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
lcr_id can be an integer constant or a pseudo variable
|
||||||
|
@@ -1442,7 +1442,8 @@ defunct_gw(60);
|
||||||
|
variable holding a string value. proto can be an integer
|
||||||
|
constant (0 = ANY, 1 = UDP, 2 = TCP,
|
||||||
|
3 = TLS, 4 = SCTP) or a pseudo variable holding such an
|
||||||
|
- integer value.
|
||||||
|
+ integer value. src_port can be an integer or a pseudo variable
|
||||||
|
+ holding such an integer value.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If request comes from a gateway, gateway's tag and flags are
|
||||||
|
@@ -1466,7 +1467,7 @@ defunct_gw(60);
|
||||||
|
<title><function>from_gw</function> usage</title>
|
||||||
|
<programlisting format="linespecific">
|
||||||
|
...
|
||||||
|
-if (from_gw(1, $avp(real_source_addr), 2) {
|
||||||
|
+if (from_gw(1, $avp(real_source_addr), 2, 5060) {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
...
|
||||||
|
@@ -1476,21 +1477,21 @@ if (from_gw(1, $avp(real_source_addr), 2) {
|
||||||
|
|
||||||
|
<section id="lcr.f.from_any_gw">
|
||||||
|
<title>
|
||||||
|
- <function moreinfo="none">from_any_gw([ip_addr, proto])</function>
|
||||||
|
+ <function moreinfo="none">from_any_gw([ip_addr, proto[, src_port]])</function>
|
||||||
|
</title>
|
||||||
|
<para>
|
||||||
|
- Checks if request comes from IP address and transport
|
||||||
|
- protocol specified for any gateway. Only LCR instances,
|
||||||
|
+ Checks if request comes from IP address, transport protocol and source port
|
||||||
|
+ specified for any gateway. Only LCR instances,
|
||||||
|
where all gateways
|
||||||
|
have IP address, are included in the test.
|
||||||
|
- IP address and transport protocol to be checked are either
|
||||||
|
- taken from source IP address and transport protocol
|
||||||
|
+ IP address, transport protocol and source port to be checked are either
|
||||||
|
+ taken from source IP address, transport protocol and source port
|
||||||
|
of the request or
|
||||||
|
- (if present) from ip_addr and proto arguments. See from_gw()
|
||||||
|
+ (if present) from ip_addr, proto and src_port arguments. See from_gw()
|
||||||
|
function for more info about the arguments.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
- If any gateway has the IP address and transport protocol,
|
||||||
|
+ If any gateway has the IP address, transport protocol and source port,
|
||||||
|
function returns LCR
|
||||||
|
identifier of the gateway. Returns -1 on error or if
|
||||||
|
the request does not come from a gateway.
|
||||||
|
@@ -1515,7 +1516,7 @@ if (from_gw(1, $avp(real_source_addr), 2) {
|
||||||
|
<title><function>from_gw</function> usage</title>
|
||||||
|
<programlisting format="linespecific">
|
||||||
|
...
|
||||||
|
-$var(lcr_id) = from_any_gw("192.168.1.1", 3);
|
||||||
|
+$var(lcr_id) = from_any_gw("192.168.1.1", 3, 5061);
|
||||||
|
...
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
diff --git a/src/modules/lcr/lcr_mod.c b/src/modules/lcr/lcr_mod.c
|
||||||
|
index 579ec06d4d..858352f2c7 100644
|
||||||
|
--- a/src/modules/lcr/lcr_mod.c
|
||||||
|
+++ b/src/modules/lcr/lcr_mod.c
|
||||||
|
@@ -260,8 +260,10 @@ static int inactivate_gw(struct sip_msg *_m, char *_s1, char *_s2);
|
||||||
|
static int defunct_gw(struct sip_msg *_m, char *_s1, char *_s2);
|
||||||
|
static int from_gw_1(struct sip_msg *_m, char *_s1, char *_s2);
|
||||||
|
static int from_gw_3(struct sip_msg *_m, char *_s1, char *_s2, char *_s3);
|
||||||
|
+static int from_gw_4(struct sip_msg *_m, char *_s1, char *_s2, char *_s3, char *_s4);
|
||||||
|
static int from_any_gw_0(struct sip_msg *_m, char *_s1, char *_s2);
|
||||||
|
static int from_any_gw_2(struct sip_msg *_m, char *_s1, char *_s2);
|
||||||
|
+static int from_any_gw_3(struct sip_msg *_m, char *_s1, char *_s2, char *_s3);
|
||||||
|
static int to_gw_1(struct sip_msg *_m, char *_s1, char *_s2);
|
||||||
|
static int to_gw_3(struct sip_msg *_m, char *_s1, char *_s2, char *_s3);
|
||||||
|
static int to_any_gw_0(struct sip_msg *_m, char *_s1, char *_s2);
|
||||||
|
@@ -283,10 +285,14 @@ static cmd_export_t cmds[] = {
|
||||||
|
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
|
||||||
|
{"from_gw", (cmd_function)from_gw_3, 3, 0, 0,
|
||||||
|
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
|
||||||
|
+ {"from_gw", (cmd_function)from_gw_4, 4, 0, 0,
|
||||||
|
+ REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
|
||||||
|
{"from_any_gw", (cmd_function)from_any_gw_0, 0, 0, 0,
|
||||||
|
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
|
||||||
|
{"from_any_gw", (cmd_function)from_any_gw_2, 2, 0, 0,
|
||||||
|
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
|
||||||
|
+ {"from_any_gw", (cmd_function)from_any_gw_3, 3, 0, 0,
|
||||||
|
+ REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
|
||||||
|
{"to_gw", (cmd_function)to_gw_1, 1, 0, 0,
|
||||||
|
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
|
||||||
|
{"to_gw", (cmd_function)to_gw_3, 3, 0, 0,
|
||||||
|
@@ -2978,7 +2984,7 @@ static int next_gw(struct sip_msg *_m, char *_s1, char *_s2)
|
||||||
|
* Checks if request comes from ip address of a gateway
|
||||||
|
*/
|
||||||
|
static int do_from_gw(struct sip_msg *_m, unsigned int lcr_id,
|
||||||
|
- struct ip_addr *src_addr, uri_transport transport)
|
||||||
|
+ struct ip_addr *src_addr, uri_transport transport, unsigned int src_port)
|
||||||
|
{
|
||||||
|
struct gw_info *res, gw, *gws;
|
||||||
|
int_str val;
|
||||||
|
@@ -2997,9 +3003,10 @@ static int do_from_gw(struct sip_msg *_m, unsigned int lcr_id,
|
||||||
|
sizeof(struct gw_info), comp_gws);
|
||||||
|
|
||||||
|
/* Store tag and flags and return result */
|
||||||
|
- if((res != NULL) && ((transport == PROTO_NONE)
|
||||||
|
- || (res->transport_code == transport))) {
|
||||||
|
- LM_DBG("request game from gw\n");
|
||||||
|
+ if((res != NULL)
|
||||||
|
+ && ((transport == PROTO_NONE) || (res->transport_code == transport))
|
||||||
|
+ && ((src_port == 0) || (res->port == src_port))) {
|
||||||
|
+ LM_DBG("request came from gw\n");
|
||||||
|
if(tag_avp_param) {
|
||||||
|
val.s.s = res->tag;
|
||||||
|
val.s.len = res->tag_len;
|
||||||
|
@@ -3021,22 +3028,24 @@ static int do_from_gw(struct sip_msg *_m, unsigned int lcr_id,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if request comes from ip address of a gateway taking source
|
||||||
|
- * address and transport protocol from request.
|
||||||
|
+ * address, transport protocol and source port from request.
|
||||||
|
*/
|
||||||
|
static int ki_from_gw(sip_msg_t *_m, int lcr_id)
|
||||||
|
{
|
||||||
|
uri_transport transport;
|
||||||
|
+ unsigned int src_port;
|
||||||
|
|
||||||
|
if((lcr_id < 1) || (lcr_id > lcr_count_param)) {
|
||||||
|
LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Get transport protocol */
|
||||||
|
+ /* Get transport protocol and port */
|
||||||
|
transport = _m->rcv.proto;
|
||||||
|
+ src_port = _m->rcv.src_port;
|
||||||
|
|
||||||
|
/* Do test */
|
||||||
|
- return do_from_gw(_m, lcr_id, &_m->rcv.src_ip, transport);
|
||||||
|
+ return do_from_gw(_m, lcr_id, &_m->rcv.src_ip, transport, src_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int from_gw_1(struct sip_msg *_m, char *_lcr_id, char *_s2)
|
||||||
|
@@ -3056,10 +3065,10 @@ static int from_gw_1(struct sip_msg *_m, char *_lcr_id, char *_s2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if request comes from ip address of a gateway taking source
|
||||||
|
- * address and transport protocol from parameters
|
||||||
|
+ * address, transport protocol and source port from parameters.
|
||||||
|
*/
|
||||||
|
static int ki_from_gw_addr(
|
||||||
|
- sip_msg_t *_m, int lcr_id, str *addr_str, int transport)
|
||||||
|
+ sip_msg_t *_m, int lcr_id, str *addr_str, int transport, unsigned int src_port)
|
||||||
|
{
|
||||||
|
struct ip_addr src_addr;
|
||||||
|
struct ip_addr *ip;
|
||||||
|
@@ -3084,8 +3093,14 @@ static int ki_from_gw_addr(
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* src_port set to 0 means we don't want to check it */
|
||||||
|
+ if((src_port < 0) || (src_port > 65535)) {
|
||||||
|
+ LM_ERR("invalid port parameter value %d\n", transport);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Do test */
|
||||||
|
- return do_from_gw(_m, lcr_id, &src_addr, transport);
|
||||||
|
+ return do_from_gw(_m, lcr_id, &src_addr, transport, src_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int from_gw_3(
|
||||||
|
@@ -3112,7 +3127,41 @@ static int from_gw_3(
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return ki_from_gw_addr(_m, lcr_id, &addr_str, transport);
|
||||||
|
+ return ki_from_gw_addr(_m, lcr_id, &addr_str, transport, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int from_gw_4(
|
||||||
|
+ struct sip_msg *_m, char *_lcr_id, char *_addr, char *_transport, char *_src_port)
|
||||||
|
+{
|
||||||
|
+ int lcr_id;
|
||||||
|
+ str addr_str;
|
||||||
|
+ char *tmp;
|
||||||
|
+ uri_transport transport;
|
||||||
|
+ unsigned int src_port;
|
||||||
|
+
|
||||||
|
+ /* Get and check parameter values */
|
||||||
|
+ lcr_id = strtol(_lcr_id, &tmp, 10);
|
||||||
|
+ if((tmp == 0) || (*tmp) || (tmp == _lcr_id)) {
|
||||||
|
+ LM_ERR("invalid lcr_id parameter %s\n", _lcr_id);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ addr_str.s = _addr;
|
||||||
|
+ addr_str.len = strlen(_addr);
|
||||||
|
+
|
||||||
|
+ transport = strtol(_transport, &tmp, 10);
|
||||||
|
+ if((tmp == 0) || (*tmp) || (tmp == _transport)) {
|
||||||
|
+ LM_ERR("invalid transport parameter %s\n", _lcr_id);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ tmp=0;
|
||||||
|
+ src_port = strtol(_src_port, &tmp, 10);
|
||||||
|
+ if((tmp == 0) || (*tmp) || (tmp == _src_port)) {
|
||||||
|
+ LM_ERR("invalid port parameter %s\n", _src_port);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ki_from_gw_addr(_m, lcr_id, &addr_str, transport, src_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -3123,11 +3172,14 @@ static int ki_from_any_gw(sip_msg_t *_m)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
uri_transport transport;
|
||||||
|
+ unsigned int src_port;
|
||||||
|
|
||||||
|
+ /* Get transport protocol and port */
|
||||||
|
transport = _m->rcv.proto;
|
||||||
|
+ src_port = _m->rcv.src_port;
|
||||||
|
|
||||||
|
for(i = 1; i <= lcr_count_param; i++) {
|
||||||
|
- if(do_from_gw(_m, i, &_m->rcv.src_ip, transport) == 1) {
|
||||||
|
+ if(do_from_gw(_m, i, &_m->rcv.src_ip, transport, src_port) == 1) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -3141,9 +3193,9 @@ static int from_any_gw_0(struct sip_msg *_m, char *_s1, char *_s2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if request comes from ip address of a a gateway taking source
|
||||||
|
- * IP address and transport protocol from parameters.
|
||||||
|
+ * IP address, transport protocol and source port from parameters.
|
||||||
|
*/
|
||||||
|
-static int ki_from_any_gw_addr(sip_msg_t *_m, str *addr_str, int transport)
|
||||||
|
+static int ki_from_any_gw_addr(sip_msg_t *_m, str *addr_str, int transport, unsigned int src_port)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
struct ip_addr *ip, src_addr;
|
||||||
|
@@ -3163,9 +3215,15 @@ static int ki_from_any_gw_addr(sip_msg_t *_m, str *addr_str, int transport)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* src_port set to 0 means we don't want to check it */
|
||||||
|
+ if((src_port < 0) || (src_port > 65535)) {
|
||||||
|
+ LM_ERR("invalid port parameter value %d\n", transport);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Do test */
|
||||||
|
for(i = 1; i <= lcr_count_param; i++) {
|
||||||
|
- if(do_from_gw(_m, i, &src_addr, transport) == 1) {
|
||||||
|
+ if(do_from_gw(_m, i, &src_addr, transport, src_port) == 1) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -3188,7 +3246,33 @@ static int from_any_gw_2(struct sip_msg *_m, char *_addr, char *_transport)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return ki_from_any_gw_addr(_m, &addr_str, transport);
|
||||||
|
+ return ki_from_any_gw_addr(_m, &addr_str, transport, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int from_any_gw_3(struct sip_msg *_m, char *_addr, char *_transport, char *_src_port)
|
||||||
|
+{
|
||||||
|
+ str addr_str;
|
||||||
|
+ uri_transport transport;
|
||||||
|
+ unsigned int src_port;
|
||||||
|
+ char *tmp;
|
||||||
|
+
|
||||||
|
+ /* Get and check parameter values */
|
||||||
|
+ addr_str.s = _addr;
|
||||||
|
+ addr_str.len = strlen(_addr);
|
||||||
|
+
|
||||||
|
+ transport = strtol(_transport, &tmp, 10);
|
||||||
|
+ if((tmp == 0) || (*tmp) || (tmp == _transport)) {
|
||||||
|
+ LM_ERR("invalid transport parameter %s\n", _transport);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ tmp=0;
|
||||||
|
+ src_port = strtol(_src_port, &tmp, 10);
|
||||||
|
+ if((tmp == 0) || (*tmp) || (tmp == _src_port)) {
|
||||||
|
+ LM_ERR("invalid port parameter %s\n", _src_port);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ki_from_any_gw_addr(_m, &addr_str, transport, src_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
Loading…
Reference in new issue