Hello,
after receiving
INVITE sip:test-gnome-calls@bapha.be SIP/2.0 Via: SIP/2.0/WSS bapha.be;branch=z9hG4bK974100 Max-Forwards: 70 To: sip:test-gnome-calls@bapha.be From: "Online https://sip.bapha.be" sip:online@bapha.be;tag=12q2efc423 Call-ID: fkhe8faq0fh80glmq59i CSeq: 5622 INVITE Contact: sip:4q5ne5no@bapha.be;transport=ws;ob Allow: ACK,CANCEL,INVITE,MESSAGE,BYE,OPTIONS,INFO,NOTIFY,REFER Supported: outbound User-Agent: SIP.js/0.7.8 Content-Type: application/sdp Content-Length: 1964
v=0 o=mozilla...THIS_IS_SDPARTA-99.0 8263261229339246488 0 IN IP4 0.0.0.0 s=- …
kamailio calls
th_mask_encode( char *in = "sip:test-gnome-calls@bapha.be;gr=urn:uuid:f2f5a3cf-a0fb-0047-be50- 740fb9bdc562;alias=87.118.146.153~60722~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\n"\ "Content-Type: application/sdp and so on", int ilen = 107, str prefix = { .len = 23, .s ="sip:127.3.4.84;line=sr-" }, int *olen).
It returns olen=167, and the string "sip:127.3.4.84;line=sr- if7s1mg7i36PNf0AbdwPpfzlbqWEpLzsSGItpLwyN39ZMY4t1mCTSd6DNo4LWdIOpfpPp5FLpUQscX63Kd47W5EPWO6sNL90pLgoW5p-1fzlSdzO25n3KoIk1vHkWXptc5wOeopsWO9-eo9*".
Then Kamailio forwards (sends):
Contact: sip:127.3.4.84;line=sr-if7s1mg7i36PNf0AbdwPpfzlbqWEpLzsSGItpLwyN39ZMY4t1mCTSd6DNo4LWdIOpfpPp5FLpUQscX63Kd47W5EPWO6sNL90pLgoW5p- 1fzlSdzO25n3KoIk1vHkWXptc5wOeopsWO9-eo9*;+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"
which at some point leads to
ACK sip:127.3.4.84;line=sr-if7s1mg7i36pnf0abdwppfzlbqweplzssgitplwyn39zmy4t1mctsd6dno4lwdiopfppp5flpuqscx63kd47w5epwo6snl90plgow5p- 1fzlsdzo25n3koik1vhkwxptc5woeopswo9-eo9* SIP/2.0
and
BYE sip:127.3.4.84;line=sr-if7s1mg7i36pnf0abdwppfzlbqweplzssgitplwyn39zmy4t1mctsd6dno4lwdiopfppp5flpuqscx63kd47w5epwo6snl90plgow5p- 1fzlsdzo25n3koik1vhkwxptc5woeopswo9-eo9* SIP/2.0
Below you can find th_test.c . The functions th_mask_encode() and th_mask_decode() there are identical to the same functions in src/modules/topoh/th_mask.c . main() provides some tests:
Passing «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» to th_mask_encode() returns
sip:127.3.4.84;line=sr-if7s1mg7i36PNf0AbdwPpfzlbqWEpLzsSGItpLwyN39ZMY4t1mCTSd6DNo4LWdIOpfpPp5FLpUQscX63Kd47W5EPWO6sNL90pLgoW5p- 1fzlSdzO25n3KoIk1vHkWXptc5wOeopsWXi-eo9*
(this is what Kamailio does send out). Passing the last string to th_mask_decode() returns
sip:test-gnome-calls@bapha.be;gr=urn:uuid:f2f5a3cf-a0fb-0047-be50-740fb9bdc562;alias=87.118.1
the ;alias= is incomplete, compared to the origin.
The above ACK leads to passing
"sr-if7s1mg7i36pnf0abdwppfzlbqweplzssgitplwyn39zmy4t1mctsd6dno4lwdiopfppp5flpuqscx63kd47w5epwo6snl90plgow5p-1fzlsdzo25n3koik1vhkwxptc5woeopswo9-eo9* SIP/2.0\n"\ "Route: sip:Q+L06HX94DMPtQWQTI5OE8SQTI5O4MY=@144.76.142.78;transport=ws;r2=on;lr;nat=yes\n"\ "Route: sip:127.3.4.84;line=sr-if7s17IB5XEfVzn0WIgWwqggCTzwV5C2g5R5wCg4WwrQ5CuZ6XIQWvH3WUHkWX9tWOnyMq4RbmWsb34Q2YgoiXP-coTAboPlioPtpY6Z8dCO\n"\
to th_mask_decode() and the result is callub.p.b;rn:s.d2lQg#cfa=bA07beQ7R409bcQ62;alac=87718*1P.15#~60R22~2 with the dots being unprintable characters. (result is garbage).
I have seen that callub.p.b in the unparsable R-URI reports from Kamailio.
That is an indication that th_mask_decode() does not decode the Contact encoded by th_mask_encode() correctly.
Valgrind does not report improper memory usage.
Greetings Dilyan
gcc -g -o th-test ./th-test.c && ./th-test
th-test.c
#include <stdio.h> #include <stdlib.h> #include <string.h>
#define TH_EB64I \ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-" char _th_EB64[65] = "EFvXIzGq94xKcW126gV5wCdYpNSbiM8enRUou7LmhajBlPtAsk-OQTf3H0DyrZ.J"; int _th_DB64[256]; char *_th_PD64 = "*";
struct str_ { char* s; /**< Pointer to the first character of the string */ int len; /**< Length of the string */ }; typedef struct str_ str;
str prefix = { .len = 23, .s ="sip:127.3.4.84;line=sr-" };
char* th_mask_encode(char *in, int ilen, const str *prefix, int *olen); char* th_mask_decode(char *in, int ilen, const str *prefix, int extra, int *olen); char* th_mask_encode(char *in, int ilen, const str *prefix, int *olen) { char *out; int left; int idx; int i; int r; char *p; int block; *olen = (((ilen+2)/3)<<2) + ((prefix!=NULL&&prefix->len>0)?prefix->len:0); out = (char*)malloc((*olen+1)*sizeof(char)); if(out==NULL) { fprintf(stderr, "malloc error\n"); *olen = 0; return NULL; } memset(out, 0, (*olen+1)*sizeof(char)); if(prefix!=NULL&&prefix->len>0) memcpy(out, prefix->s, prefix->len);
p = out + (int)((prefix!=NULL&&prefix->len>0)?prefix->len:0); for(idx=0; idx<ilen; idx+=3) { left = ilen - idx - 1 ; left = (left>1)?2:left;
block = 0; for(i=0, r=16; i<=left; i++, r-=8) block += ((unsigned char)in[idx+i]) << r;
*(p++) = _th_EB64[(block >> 18) & 0x3f]; *(p++) = _th_EB64[(block >> 12) & 0x3f]; *(p++) = (left>0)?_th_EB64[(block >> 6) & 0x3f]:_th_PD64[0]; *(p++) = (left>1)?_th_EB64[block & 0x3f]:_th_PD64[0]; }
return out; }
char* th_mask_decode(char *in, int ilen, const str *prefix, int extra, int *olen) { char *out; int n; int block; int idx; int i; int j; int end; char c;
for(n=0,i=ilen-1; in[i]==_th_PD64[0]; i--) n++;
*olen = (((ilen-((prefix!=NULL&&prefix->len>0)?prefix->len:0)) * 6) >> 3) - n;
if (*olen<=0) { return NULL; }
out = (char*)malloc((*olen+1+extra)*sizeof(char)); if(out==NULL) { fprintf(stderr, "malloc error\n"); *olen = 0; return NULL; } memset(out, 0, (*olen+1+extra)*sizeof(char));
end = ilen - n; i = (prefix!=NULL&&prefix->len>0)?prefix->len:0; for(idx=0; i<end; idx+=3) { block = 0; for(j=0; j<4 && i<end ; j++) { c = _th_DB64[(int)in[i++]]; if(c<0) { free(out); *olen = 0; return NULL; } block += c << (18 - 6*j); }
for(j=0, n=16; j<3 && idx+j< *olen; j++, n-=8) out[idx+j] = (char)((block >> n) & 0xff); }
return out; }
int main() { //this is from th_mask_init for(int i=0; i<256; i++) _th_DB64[i] = -1; for(int i=0; i<64; i++) _th_DB64[(int)_th_EB64[i]] = i; int olen, o2; char *end; char *input = "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""; printf("input=[%s]\n", input); char* middle = th_mask_encode (input, 107, &prefix, &olen); printf("olen = %i, middle=[%s]\n", olen, middle); end = th_mask_decode(middle, 147, &prefix, 0, &o2); printf("o2 = %i, end=[%s]\n", o2, end); char * b1 = "sr-if7s1mg7i36pnf0abdwppfzlbqweplzssgitplwyn39zmy4t1mctsd6dno4lwdiopfppp5flpuqscx63kd47w5epwo6snl90plgow5p- 1fzlsdzo25n3koik1vhkwxptc5woeopswo9-eo9*"; o2 = 0; end = th_mask_decode(b1, 147, &prefix, 0, &o2); printf("o2 = %i, end=[%s]\n", o2, end);
char* b2 = "sr-if7s1mg7i36pnf0abdwppfzlbqweplzssgitplwyn39zmy4t1mctsd6dno4lwdiopfppp5flpuqscx63kd47w5epwo6snl90plgow5p-1fzlsdzo25n3koik1vhkwxptc5woeopswo9-eo9* SIP/2.0\n"\ "Route: sip:Q+L06HX94DMPtQWQTI5OE8SQTI5O4MY=@144.76.142.78;transport=ws;r2=on;lr;nat=yes\n"\ "Route: sip:127.3.4.84;line=sr-if7s17IB5XEfVzn0WIgWwqggCTzwV5C2g5R5wCg4WwrQ5CuZ6XIQWvH3WUHkWX9tWOnyMq4RbmWsb34Q2YgoiXP-coTAboPlioPtpY6Z8dCO\n"\ "Via: SIP/2.0/WSS bapha.be;branch=z9hG4bK9069155\n"\ "Max-Forwards: 70\n"\ "To: sip:test-gnome-calls@bapha.be;tag=Pn4npAj\n"\ "From: "Online https://sip.bapha.be%5C" sip:online@bapha.be;tag=12q2efc423\n"\ "Call-ID: fkhe8faq0fh80glmq59i\n"\ "CSeq: 5623 ACK\n"\ "Supported: outbound\n"\ "User-Agent: SIP.js/0.7.8\n"\ "Content-Length: 0\n"\ "\n";
o2 = 0; end = th_mask_decode(b2, 147, &prefix, 0, &o2); printf("o2 = %i, end=[%s]\n", o2, end);
return 0; }