Module: kamailio Branch: master Commit: ce95734c97e8443facf224a1833f67a78ab67d21 URL: https://github.com/kamailio/kamailio/commit/ce95734c97e8443facf224a1833f67a7...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@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/ce95734c97e8443facf224a1833f67a7... Patch: https://github.com/kamailio/kamailio/commit/ce95734c97e8443facf224a1833f67a7...
---
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; }