Răsfoiți Sursa

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.
Donat Zenichev 4 ani în urmă
părinte
comite
9115d74b33
2 a modificat fișierele cu 116 adăugiri și 31 ștergeri
  1. 16 15
      src/modules/lcr/doc/lcr_admin.xml
  2. 100 16
      src/modules/lcr/lcr_mod.c

+ 16 - 15
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>

+ 100 - 16
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);
 }
 
 /*