Hi all!
My team and I are finalizing implementation of STIR/SHAKEN. The flow has
been simplified and is something like: Call comes from SBC to Kamailio,
Kamailio makes an HTTP request to a REST API, response is received by
Kamailio (5.8.2) and depending on the response, it replies back to SBC with
a SIP 300 Multiple Choice of a SIP 4xx error, denying the call.
The INVITEs received by SBC may or may not contain the Identity header.
On Kamailio side, the following code gets the required headers to build the
JSON object sent to REST API:
route[HANDLE_STIRSHAKEN]
{
if (!is_method("INVITE")) {
return;
}
$var(requestTime) = $utimef(%s);
$var(ruri) = "$ru"; #request URI
$var(from) = "$hdr(From)"; #$fU From header
$var(to) = "$hdr(To)"; #$tU; To header
$var(contact) = "$hdr(Contact)"; #Contact header
$var(callID) = "$ci"; # Call ID
$var(identity) = "$hdr(Identity)"; # Identity header
jansson_set("string","from" , $var(from) ,
"$var(post)");
jansson_set("string","to" , $var(to) ,
"$var(post)");
jansson_set("string","r-uri" , $var(ruri) ,
"$var(post)");
jansson_set("string","contact" , $var(contact) ,
"$var(post)");
jansson_set("string","call-id" , $var(callID) ,
"$var(post)");
jansson_set("string","identity" , $var(identity) ,
"$var(post)");
http_connect("api1", "/stsh",
"application/json","$var(post)","$var(result)");
xlog("L_DEBUG", "HANDLE_STIRSHAKEN - Result = $var(result)\n");
[... do some other irrelevant stuff ...]
}
The usual INVITE is similar to this:
INVITE sip:+33142XXXXXX@10.242.XXX.YYY:5060;user=phone SIP/2.0
Via: SIP/2.0/UDP
10.240.AAA.BBB:5064;branch=z9hG4bK+30f178b47ee25dd589f986ed7402b4eb3+sip+6+a64eb889
From: "+493XXXXXXX" <sip:+493XXXXXXX@10.240.AAA.BBB
;user=phone>;tag=10.240.AAA.BBB+6+ffe686f8+614d17a3
To: +33142XXXXXX <sip:+33142XXXXXX@10.242.XXX.YYY>
CSeq: 1 INVITE
Expires: 180
Content-Length: 234
Call-Info:
<sip:10.240.AAA.BBB:5064>;method="NOTIFY;Event=telephone-event;Duration=2000"
Supported: timer, 100rel
Contact: <sip:+493XXXXXXX@10.240.AAA.BBB:5064;user=phone>
Content-Type: application/sdp
Call-ID:
0gQAAC8WAAACBAAALxYAAHRfFdrMLbnN/iMYu2NTT6kvhuhZAFl7MG1V2ozJLUcXg9dxbyQZ/PtoswtdHtcv9g--(a)10.240.AAA.BBB
Min-SE: 90
Session-Expires: 90;refresher=uac
X-dtmf: 5
P-Asserted-Identity: "+493XXXXXXX" <sip:+493XXXXXXX@10.240.AAA.BBB>
Accept: application/sdp
Accept: application/dtmf-relay
Max-Forwards: 66
Allow: INVITE,CANCEL,BYE,ACK, INFO
Identity:
dGhpcyBpcyBzb21lIGR1bW15IGJhc2U2NCBlbmNvZGVkIElkZW50aXR5IGhlYWRlcg==.eW91IHdvdWxkIG5vdCBleHBlY3QgbWUgdG8gbGVhdmUgdGhlIHJlYWwgdmFsdWUgaGVyZSByaWdodD8=.dGhhbmtzIGZvciB5b3VyIGNvbXByZWhlbnNpb24=;info=<
https://someURL.com/with/some/parameter;sc697295b.cer>;alg=ES256;ppt=sha…
P-Origination-Id: 23A16F8B-F9AB-4536-9884-85C96EF3B964
P-Attestation-Indicator: C
has-sdp: present
[SDP stuff]
(I have replaced some of the values for obvious reasons).
- SBC is sending every 70 secs 2 automatically generated INVITEs to kamailio
- 1st call contains the Identity header, the other call does not contain
Identity header.
- Both calls have different Call-IDs and different FROM and TO values, so
they are different calls and can be perfectly found in logs as separated
calls
- Kamailio receives each call and extracts headers, as shown in code above,
and sends the JSON request to HTTP REST API
Here is the weird part.... every now and then, completely random, the JSON
object request sent to the HTTP REST API contains an Identity value,
supposedly extracted from the SIP header **but** the SIP message captured
in SNGrep doesn't have **any* I*dentity header!! In fact, in the kamailio
logs, where I sent the header values extracted from INVITE, the identity is
empty! BUT the JSON object has the identity set with value.
And the worst part is that, when this issue happens, the value of the
Identity set in JSON belongs to a completely different call that was
processed a few minutes before !
So I suspected about some Caching behaviour on the http_connect function
and added the following lines before sending the JSON to REST API:
if ( is_present_hf("Identity") ) {
jansson_set("string","identity",* $var(identity),*
"$var(post)");
} else
jansson_set("string","identity", "",
"$var(post)");
forcing the identity property of the JSON to an empty string, but this did
not work either!
I even added a new property which is the current timestamp making sure
every request was unique, and that did not work either!
The only way I could make it work was replacing the above lines using these
lines:
if ( is_present_hf("Identity") ) {
jansson_set("string","identity", *(a)hf_value2.Identity*,
"$var(post)");
} else
jansson_set("string","identity", "",
"$var(post)");
So, instead of using $hdr(Identity) , Kamailio extracts the Identity header
using @hf_value2.Identity
Question: why is this behaviour? Could this be a bug somewhere?
Atenciosamente / Kind Regards / Cordialement / Un saludo,
*Sérgio Charrua*