[sr-dev] git:master:ce95734c: nathelper: new nat test (512) based on target addresses

Daniel-Constantin Mierla miconda at gmail.com
Tue Jul 6 20:45:13 CEST 2021


Module: kamailio
Branch: master
Commit: ce95734c97e8443facf224a1833f67a78ab67d21
URL: https://github.com/kamailio/kamailio/commit/ce95734c97e8443facf224a1833f67a78ab67d21

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date: 2021-07-06T11:08:50+02:00

nathelper: new nat test (512) based on target addresses

- return true if the target proto is ws or wss
- return true if the target addresses are different
  - for requests it compares r-uri with d-uri
  - for replies compares 2nd Via host and port with received and rport

---

Modified: src/modules/nathelper/nathelper.c

---

Diff:  https://github.com/kamailio/kamailio/commit/ce95734c97e8443facf224a1833f67a78ab67d21.diff
Patch: https://github.com/kamailio/kamailio/commit/ce95734c97e8443facf224a1833f67a78ab67d21.patch

---

diff --git a/src/modules/nathelper/nathelper.c b/src/modules/nathelper/nathelper.c
index df9a5bce2c..bdf1b7777a 100644
--- a/src/modules/nathelper/nathelper.c
+++ b/src/modules/nathelper/nathelper.c
@@ -101,6 +101,7 @@ MODULE_VERSION
 #define NAT_UAC_TEST_WS 0x40
 #define NAT_UAC_TEST_C_PORT 0x80
 #define NAT_UAC_TEST_SDP_CLINE 0x100
+#define NAT_UAC_TEST_DEST 0x200
 
 #define DEFAULT_NATPING_STATE 1
 
@@ -1540,6 +1541,125 @@ static int via_1918(struct sip_msg *msg)
 	return (is1918addr(&(msg->via1->host)) == 1) ? 1 : 0;
 }
 
+/*
+ * test if destination address is different than R-URI/2nd Via
+ * - ws/wss target is true
+ */
+static int nh_test_destination(sip_msg_t *msg)
+{
+	str rhost = STR_NULL;
+	int rport = 0;
+	str dhost = STR_NULL;
+	int dport = 0;
+	sip_uri_t pduri;
+	ip_addr_t *rhostip = NULL;
+	ip_addr_t *dhostip = NULL;
+
+	if(msg==NULL)
+		return -1;
+
+	if(msg->first_line.type == SIP_REPLY) {
+		if(parse_headers(msg, HDR_VIA2_F, 0)==-1) {
+			LM_DBG("no 2nd via parsed\n");
+			return 0;
+		}
+		if((msg->via2==0) || (msg->via2->error!=PARSE_OK)) {
+			return -1;
+		}
+		if(msg->via2->proto==PROTO_WSS || msg->via2->proto==PROTO_WS) {
+			/* going to ws/wss */
+			return 1;
+		}
+		if(msg->via2->rport && msg->via2->rport->value.s
+				 && msg->via2->rport->value.len>0) {
+			if(str2sint(&msg->via2->rport->value, &dport)<0) {
+				LM_ERR("invalid rport value\n");
+				return -1;
+			}
+		}
+		if(dport!=0) {
+			rport = GET_SIP_PORT(msg->via2->port, msg->via2->proto);
+			if(dport != rport) {
+				/* ports are different */
+				return 1;
+			}
+		}
+		if(!msg->via2->received) {
+			/* no received param - going to Via host */
+			return 0;
+		}
+		dhost = msg->via2->received->value;
+		rhost = msg->via2->host;
+	} else {
+		if(msg->dst_uri.s==NULL || msg->dst_uri.len<=0) {
+			/* no destination uri - target is r-uri */
+			if(msg->parsed_uri_ok==0 /* R-URI not parsed*/
+					&& parse_sip_msg_uri(msg)<0) {
+				LM_ERR("failed to parse the R-URI\n");
+				return -1;
+			}
+			if(msg->parsed_uri.proto==PROTO_WSS
+					|| msg->parsed_uri.proto==PROTO_WS) {
+				/* going to ws/wss */
+				return 1;
+			}
+			return 0;
+		}
+		if(parse_uri(msg->dst_uri.s, msg->dst_uri.len, &pduri)!=0) {
+			LM_ERR("failed to parse dst uri [%.*s]\n",
+					msg->dst_uri.len, msg->dst_uri.s);
+			return -1;
+		}
+		if(pduri.proto==PROTO_WSS || pduri.proto==PROTO_WS) {
+			/* going to ws/wss */
+			return 1;
+		}
+		if(msg->parsed_uri_ok==0 /* R-URI not parsed*/
+				&& parse_sip_msg_uri(msg)<0) {
+			LM_ERR("failed to parse the R-URI\n");
+			return -1;
+		}
+		dport = GET_SIP_PORT(pduri.port_no, pduri.proto);
+		rport = GET_SIP_PORT(msg->parsed_uri.port_no, msg->parsed_uri.proto);
+		if(dport != rport) {
+			/* ports are different */
+			return 1;
+		}
+		dhost = pduri.host;
+		rhost = msg->parsed_uri.host;
+	}
+	if(dhost.s==NULL || dhost.len<=0) {
+		return 0;
+	}
+	dhostip = str2ipx(&dhost);
+	rhostip = str2ipx(&rhost);
+	if(dhostip==NULL && rhostip==NULL) {
+		/* both are hostnames - do str comparison */
+		if(rhost.s==NULL || rhost.len<=0) {
+			return 0;
+		}
+		if(rhost.len != dhost.len) {
+			/* different in length */
+			return 1;
+		}
+		if(memcmp(rhost.s, dhost.s, dhost.len)!=0) {
+			/* different in content */
+			return 1;
+		}
+		return 0;
+	}
+	if(dhostip==NULL || rhostip==NULL) {
+		/* different in content */
+		return 1;
+	}
+	if(ip_addr_cmp(dhostip, rhostip)) {
+		/* same ip addresses */
+		return 0;
+	}
+	/* different ip addresses */
+	return 1;
+}
+
 static int nat_uac_test(struct sip_msg *msg, int tests)
 {
 	/* return true if any of the NAT-UAC tests holds */
@@ -1599,6 +1719,13 @@ static int nat_uac_test(struct sip_msg *msg, int tests)
 	if((tests & NAT_UAC_TEST_SDP_CLINE) && (test_sdp_cline(msg) > 0))
 		return 1;
 
+	/**
+	* test if destination address is different than R-URI/2ndVia
+	* - ws/wss target is true
+	*/
+	if((tests & NAT_UAC_TEST_DEST) && (nh_test_destination(msg) > 0))
+		return 1;
+
 	/* no test succeeded */
 	return -1;
 }




More information about the sr-dev mailing list