The file [th-test.c.txt](https://github.com/kamailio/kamailio/files/10608862/th-test.c.txt) contains the exact copy of the th_mask_encode() and th_mask_decode() functions from src/modules/topoh/th_mask.c . (except LM_ERR is removed and pkg_malloc/pkg_free are replaced with malloc/free).
When I run Kamilio under topoh and the websocket client calls, at some moment `sip:test-gnome-calls@bapha.be;gr=urn:uuid:f2f5a3cf-a0fb-0047-be50-740fb9bdc562;alias=87.118.146.153~60472~2>;+sip.instance="urn:uuid:f2f5a3cf-a0fb-0047-be50-740fb9bdc562";+org.linphone.specs="conference/1.0,ephemeral/1.1,groupchat/1.1,groupchat/1.2,lime"` is passed to th_mask_encode(). The output it `sip:127.3.4.84;line=sr-if7s1mg7i36PNf0AbdwPpfzlbqWEpLzsSGItpLwyN39ZMY4t1mCTSd6DNo4LWdIOpfpPp5FLpUQscX63Kd47W5EPWO6sNL90pLgoW5p-1fzlSdzO25n3KoIk1vHkWXptc5wOeopsWXi-eo9*`. This is put in a Contact: header. When that last string is passed to th_mask_decode(), e.g. because BYE or ACK have it as R-URI, the output is `sip:test-gnome-calls@bapha.be;gr=urn:uuid:f2f5a3cf-a0fb-0047-be50-740fb9bdc562;alias=87.118.1`. From the initial input the final output misses at least `46.153`.
The attached file contains under `b2` another input, which is passed ot th_mask_decode. This is the actual input Kamailio gets at runtime and passes to th_mask_decode. The result is not a string — callu.b.p...b.;.r...n:s..d..2lQ — where the dots represent unprintable bytes.
The error report is that th_mask_encode() produces output, which th_mask_decode() does not convert to its origin.
N.B.: The above problem happens, when a websocket client calls TCP-client with topoh-module. When a TLS-client calls TCP-client (no websockets involved), topoh does not make problems — BYE is delivered properly.
See also: * https://lists.kamailio.org/mailman3/hyperkitty/list/sr-users@lists.kamailio.... * https://lists.kamailio.org/mailman3/hyperkitty/list/sr-users@lists.kamailio....
This might also be related: * https://lists.kamailio.org/mailman3/hyperkitty/list/sr-users@lists.kamailio....
The test c program is not correct, because the decoding is not with the right value for length (which resulted after encoding, stored in olen), it has 147 instead of 167, that's why the decoding has unexpected result.
I replied a while ago on sr-users mailing list, indicating that you have to grab a pcap file with the sip traffic (e.g., with sipdump) when you reproduce the case. If it concludes to be a bug, we will know where that is, becauseat this moment there is not pointer that it is the encoding/decoding by looking at your test file. The module is used quite extensively for many years, and an eventual encoding/decoding problem should have surfaced very early.
Closed #3358 as completed.
I try here to present the problem as clear as possible.
I make these changes to 5.6, which let me see the input and output of th_mask_encode and th_mask_decode. ```diff diff --git a/src/modules/topoh/th_mask.c b/src/modules/topoh/th_mask.c index 122d0935a5..895864e3c4 100644 --- a/src/modules/topoh/th_mask.c +++ b/src/modules/topoh/th_mask.c @@ -93,6 +93,7 @@ char* th_mask_encode(char *in, int ilen, str *prefix, int *olen) int r; char *p; int block; + LM_ERR("th_mask_encode C in=[%s] ilen=%i prefix=[%.*s]\n", in, ilen, prefix->len, prefix->s);
*olen = (((ilen+2)/3)<<2) + ((prefix!=NULL&&prefix->len>0)?prefix->len:0); out = (char*)pkg_malloc((*olen+1)*sizeof(char)); @@ -121,7 +122,7 @@ char* th_mask_encode(char *in, int ilen, str *prefix, int *olen) *(p++) = (left>0)?_th_EB64[(block >> 6) & 0x3f]:_th_PD64[0]; *(p++) = (left>1)?_th_EB64[block & 0x3f]:_th_PD64[0]; } - + LM_ERR("th_mask_encode D in=[%s] ilen=%i prefix=[%.*s] out=[%s], olen=%i\n", in, ilen, prefix->len, prefix->s, out, *olen); return out; }
@@ -135,6 +136,7 @@ char* th_mask_decode(char *in, int ilen, str *prefix, int extra, int *olen) int j; int end; char c; + LM_ERR("th_mask_decode A in=[%s] ilen=%i prefix=[%.*s] extra=%i\n", in, ilen, prefix->len, prefix->s, extra);
for(n=0,i=ilen-1; in[i]==_th_PD64[0]; i--) n++; @@ -178,7 +180,7 @@ char* th_mask_decode(char *in, int ilen, str *prefix, int extra, int *olen) for(j=0, n=16; j<3 && idx+j< *olen; j++, n-=8) out[idx+j] = (char)((block >> n) & 0xff); } - + LM_ERR("th_mask_decode B in=[%s] ilen=%i prefix=[%.*s] extra=%i out=[%s], olen=%i\n", in, ilen, prefix->len, prefix->s, extra, out, *olen); return out; } ``` I log the traffic using sipdump/KEMI, I believe this is the equivalent of using pcap: ```lua function ksr_sipdump_event(evname) KSR.err("ksr_sipdump_event 1--------- " .. evname .. " src " .. KSR.pv.gete("$sipdump(src_ip)") .. ':' .. KSR.pv.gete("$sipdump(src_port)") .. " dst " .. KSR.pv.gete("$sipdump(dst_ip)") .. ':' .. KSR.pv.gete("$sipdump(dst_port)") .. "\n" .. KSR.pv.gete("$sipdump(buf)") .. "\n") return 1 end ```
The test case is: a websocket client calls Linphone, they talk and finally Linphone hangs up.
Traffic without topoh - [without-topoh.txt](https://github.com/kamailio/kamailio/files/10745403/without-topoh.txt)
Traffic with topoh and the above logging from th_mask_encode/th_mask_decode - [with-topoh.txt](https://github.com/kamailio/kamailio/files/10745414/with-topoh.txt)
As can be seen in the latter file, Linphone receives: ``` INVITE sip:test-gnome-calls@87.118.146.153:33392;transport=tls SIP/2.0 Record-Route: sip:bFdhl3svenkupAWQTI5OE8SQTI5On94=@144.76.142.78:5061;transport=tls;r2=on;lr;ftag=p702o1dak9;did=99d.b2a2;nat=yes Record-Route: sip:127.3.4.84;line=sr-BkHOV3ilcl0v8gmkcFJsLXCCo6YwnboD9b0bwo9imwUAVb7U7WtTm1ygmpyamW.AmQN4LSi0IqmOIgiTDXLQVg.eDFUAVkaeVkcThFBUBWBO83MaclYsVbGK5F7UVbHKu3.ehb.4I3YTDXHHBO** Via: SIP/2.0/TLS 144.76.142.78:5061;branch=z9hG4bK78b4.77ca12d776048c779e71b6216dd967a0.0 Via: SIP/2.0/UDP 127.3.4.84;branch=z9hG4bKsr-wTH7uQ.A81UXw68NmW0QmWoHI3K6B3GAu3HAL3Yv5F74BqCEBq7UmWdJ8zh4B3ozcFHkcF7U8b7TuzBkuztT8pygVWGwnW6K5Xh4hqi0I3mZDXZJ5tBThKvJ8QtaVbhg Max-Forwards: 69 To: sip:test-gnome-calls@bapha.be From: "Online https://sip.bapha.be" sip:online@bapha.be;tag=p702o1dak9 Call-ID: b9kkank0a5398g9odcre CSeq: 134 INVITE Contact: sip:127.3.4.84;line=sr-BkHOV3JKcFosIScv7W7yBQ76cFJjmXisIpJjIqc0IlHKVkYv5FYQDbtTm1ygmpyamW.AmQ02mWdJ8zc2mbGTB3YABgCEBq7ULg84Ik.* ``` and later sends ``` BYE sip:127.3.4.84;line=sr-BkHOV3JKcFosIScv7W7yBQ76cFJjmXisIpJjIqc0IlHKVkYv5FYQDbtTm1ygmpyamW.AmQ02mWdJ8zc2mbGTB3YABgCEBq7ULg84Ik.* SIP/2.0 ``` topoh_decode is called with ``` 22(23) ERROR: topoh [th_mask.c:183]: th_mask_decode(): th_mask_decode B in=[sr-bkhovq9hbg7gckjeifwghkyvismdh3yo5ltah3w4cg.ulxiavqo65f7rc zi3mftqhkhghbc3hpto8w7gufihmbdgmq7oc3.jh39zmbhevkyv5fyqdbnguztav1yamwha8bwqfz8q8qkofz8* SIP/2.0 Route: sip:bFdhl3svenkupAWQTI5OE8SQTI5On94=@144.76.142.78;transport=ws;r2=on;lr;ftag=p702o1dak9;did=99d.b2a2;nat=yes Route: sip:127.3.4.84;line=sr-BkHOV3ilcl0v8gmkcFJsLXCCo6YwnboD9b0bwo9imwUAVb7U7WtTm1ygmpyamW.AmQNRmbdk8bGTB3YABgCEBq7ULlaQVg.eDFUAVkaeV kcThFBUBWBO83MaclYsVbGK5F7UVbHKu3.ehb.4I3YTDXHHBO** Via: SIP/2.0/WSS 48s45eni5rkn.invalid;branch=z9hG4bK1491699 Max-Forwards: 70 To: sip:test-gnome-calls@bapha.be;tag=ulIz8kV From: "Online https://sip.bapha.be" sip:online@bapha.be;tag=p702o1dak9 Call-ID: b9kkank0a5398g9odcre CSeq: 134 ACK Supported: outbound User-Agent: SIP.js/0.7.8 Content-Length: 0
] ilen=147 prefix=[sr-] extra=0 out=[Of^U<B2>tXOt7gjr%<F5>7cn,&<B3>@bn^Uha1be;gr^K^X<A2>q<B2>uui<F4>*f2f5<F1>'cf7a6fb!^U1D7-<F2>X5076t^U fb)bdc562<B3>n,i<FE>'^A4<B7>.11<B0>.15F115'~3'2}<95>~3], olen=107 ``` and the output is garbage: ``` 22(23) ERROR: kemix [kemix_mod.c:229]: ki_kx_get_ruri_attr(): failed to parse the R-URI 22(23) ERROR: rr [loose.c:1011]: loose_route_mode(): failed to parse Request URI ```
The parameters I passed in the sample program above are not arbitrary invented by me, but were taken from real-life occasions.
The file with-topoh.txt contains the input and output of Kamailio, according the sipdump module, and the input and output of the th_mask_decode() and th_mask_encode() functions.
The above input/output is generated by: ``` modparam("topoh", "mask_key", "TEAI32l)- eauiDEUIA!?()") modparam("topoh", "mask_ip", "127.3.4.84") modparam("topoh", "sanity_checks", 0) modparam("topoh", "event_mode", 0) modparam("topoh", "event_callback", "ksr_topoh_event") ``` and there is no function ksr_topoh_event defined.