Hi all!
For testing purposes, while I am waiting for the ST/SH REST API to be
available from other teams, I developed a small python REST API that
returns a mockup of a JSON object with some of the required values.
The kamailio script, completely stateless as I do not need to keep track of
the sessions, iterates through one of the JSON branches and adds the
destination URLs to the Contact header and replies a SIP 300 Multiple
Choices.
This works: the UAC does receive the SIP response with the Contacts , but
it also receives a SIP 500 error message right after, and I can't figure
out why. And i bet this is simple to solve....
Any clue? I'm aware I'm not processing ACK messages, but the sl_send_reply
403 should do the trick right? ... at least while testing....
Also, as this is a stateless script, is there another way of using async
http or making http requests to a REST API without having to use TM Module?
Thanks in advance.
The kamailio script is has follows:
#!KAMAILIO
/* add API http timeout */
#!define HTTP_API_TIMEOUT 5000
#!define HTTP_API_ROUTING_ENDPOINT "http://some_python_rest_api/get_route"
### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR
debug=4
log_stderror=no
memdbg=5
memlog=5
log_facility=LOG_LOCAL0
log_prefix="{$mt $hdr(CSeq) $ci} "
/* number of SIP routing processes */
children=2
/* set paths to location of modules */
loadmodule "tm.so"
loadmodule "jsonrpcs.so"
loadmodule "kex.so"
loadmodule "corex.so"
loadmodule "sl.so"
loadmodule "db_mysql.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "ipops.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "cfg_rpc.so"
loadmodule "uac.so"
loadmodule "counters.so"
loadmodule "http_async_client.so"
loadmodule "jansson.so"
loadmodule "usrloc.so"
/* listen addresses */
listen=udp:10.20.0.2:5060
listen=udp:10.20.0.2:5062
advertised_address="10.20.0.2";
# ----- http_async_client params -----
modparam("http_async_client", "workers", HTTP_ASYNC_CLIENT_WORKERS)
modparam("http_async_client", "connection_timeout", 2000)
request_route {
#route(HANDLE_DMQ);
route(HANDLE_OPTIONS);
if (is_method("INVITE"))
{
xlog("L_INFO","MAIN - calling TO_CARRIER");
route(TO_CARRIER);
exit;
}
else{
sl_send_reply("401","UNAUTHORIZED");
}
}
route[TO_CARRIER]{
xlog("L_INFO","TO_CARRIER - calling RELAY_API");
route(RELAY_API); #Route relay
xlog("L_INFO","TO_CARRIER - return");
return;
}
# Relay request using the API (response)
route[RELAY_API_RESPONSE] {
xlog("L_INFO","RELAY_API_RESPONSE - got response from REST
API");
if ($http_ok==1 && $http_rs==200)
{
xlog("L_INFO","RELAY_API_RESPONSE - HTTP RESPONSE:
$http_rb\n");
if (jansson_get("json", $http_rb, "$var(json)")) {
xlog("L_INFO","RELAY_API_RESPONSE - JSON =
$var(json)");
$var(count) = 0;
jansson_array_size("routes", $var(json),
"$var(size)");
xlog("L_INFO","RELAY_API_RESPONSE -
jansson_array_size");
while ( $var(count) < $var(size) ){
jansson_get("routes[$var(count)].headers.to.uri", $var(rtjson),
"$var(v)");
xlog("L_INFO","JSON - routes[$var(count)]
- $var(v)");
#$(avp(mycontacts)[$var(count)]) =
$avp(mycontacts) + $var(v) + "\r\n";
$avp(mycontacts) = $avp(mycontacts) +
$var(v) + ";";
*append_to_reply("Contact: <" + $var(v)
+">"+ "\r\n"); /* ----
IS THERE A BETTER ?? ..... */*
$var(count) =
$var(count) + 1;
}
xlog("L_INFO","RELAY_API_RESPONSE - RELAY");
xlog("L_INFO","MAIN - calling REPLY_302");
route(REPLY_302);
return;
}
}
send_reply(500, "API Not Available - http response = $http_rs
$http_ok");
exit;
}
route[RELAY_API] {
xlog("L_INFO","RELAY_API - from_ip $si:$sp from_number $fU
to_number $ru");
$http_req(all) = $null;
$http_req(suspend) = 1;
$http_req(timeout) = HTTP_API_TIMEOUT;
$http_req(method) = "POST";
$http_req(hdr) = "Content-Type: application/json";
jansson_set("string","from_ip",$si,
"$var(http_routing_query)");
jansson_set("string","from_port",$sp,
"$var(http_routing_query)");
jansson_set("string","from_number",$fU,
"$var(http_routing_query)");
jansson_set("string","to_number",$ru ,
"$var(http_routing_query)");
xlog("L_INFO","RELAY_API - API ASYNC ROUTING REQUEST:
$var(http_routing_query)\n");
$http_req(body) = $var(http_routing_query);
t_newtran();
http_async_query(HTTP_API_ROUTING_ENDPOINT, "RELAY_API_RESPONSE");
xlog("L_INFO","RELAY_API - Waiting for Response");
}
route[REPLY_302] {
# Sends a 300 Multiple Choices back to the proxy that requested the
routing lookup
xlog("L_INFO","REPLY_302 - send reply");
sl_send_reply("300", "Multiple Choices");
xlog("L_INFO","REPLY_302 - exit");
exit;
}
route[HANDLE_OPTIONS]{
if(is_method("OPTIONS"))
{
sl_send_reply(200, "OK");
exit;
}
if ($fU=="ping")
{
sl_send_reply("200","OK");
exit;
}
}
SNGrep output:
1 - INVITE from UAC to Kamailio
INVITE sip:918228990@10.20.0.2 SIP/2.0
Via: SIP/2.0/UDP
10.20.0.1:5063;branch=z9hG4bK58aa83f4
Max-Forwards: 70
From: "Anonymous" <sip:anonymous@anonymous.invalid:5063>;tag=as192b8891
To: <sip:918228990@10.20.0.2>
Contact: <sip:anonymous@10.20.0.1:5063>
Call-ID: 531668b959674f9f667f1c923d1d6c94@10.20.0.1:5063
CSeq: 102 INVITE
User-Agent: SIPp
Date: Mon, 08 Apr 2024 15:09:51 GMT
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO,
PUBLISH, MESSAGE
Supported: replaces, timer
Content-Type: application/sdp
Content-Length: 270
v=0
o=root 2021555890 2021555890 IN IP4 10.20.0.1
s=SIPp
c=IN IP4 10.20.0.1
t=0 0
m=audio 18422 RTP/AVP 8 0 101
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=maxptime:150
a=sendrecv
2 - Reply from Kamailio to UAC
SIP/2.0 100 trying -- your call is important to us
Via: SIP/2.0/UDP
10.20.0.1:5063;branch=z9hG4bK58aa83f4
From: "Anonymous" <sip:anonymous@anonymous.invalid:5063>;tag=as192b8891
To: <sip:918228990@10.20.0.2>
Call-ID: 531668b959674f9f667f1c923d1d6c94@10.20.0.1:5063
CSeq: 102 INVITE
Server: kamailio (5.7.4 (x86_64/linux))
Content-Length: 0
3 - SIP 300 Multiple Choices from Kamailio to UAC
SIP/2.0 300 Multiple Choices
Via: SIP/2.0/UDP
10.20.0.1:5063;branch=z9hG4bK58aa83f4
From: "Anonymous" <sip:anonymous@anonymous.invalid:5063>;tag=as192b8891
To: <sip:918228990@10.20.0.2
;tag=57c593265e21c2b70aea50cb414df9cd.32679ccd
Call-ID: 531668b959674f9f667f1c923d1d6c94@10.20.0.1:5063
CSeq: 102 INVITE
Contact: <sip:sip:918228990@10.20.0.2@sip.domain.io>
Contact: <sip:+351sip:918228990@10.20.0.2@10.20.0.3>
Server: kamailio (5.7.4 (x86_64/linux))
Content-Length: 0
4 - SIP 500 from Kamailio to UAC
SIP/2.0 500 I'm terribly sorry, server error occurred (1/TM)
Via: SIP/2.0/UDP
10.20.0.1:5063;branch=z9hG4bK58aa83f4
From: "Anonymous" <sip:anonymous@anonymous.invalid:5063>;tag=as192b8891
To: <sip:918228990@10.20.0.2
;tag=4eb2322b7d2b68e6fc3168f503344c21-32679ccd
Call-ID: 531668b959674f9f667f1c923d1d6c94@10.20.0.1:5063
CSeq: 102 INVITE
Server: kamailio (5.7.4 (x86_64/linux))
Content-Length: 0
5 - ACK from UAC to Kamailio
ACK sip:918228990@10.20.0.2 SIP/2.0
Via: SIP/2.0/UDP
10.20.0.1:5063;branch=z9hG4bK58aa83f4
Max-Forwards: 70
From: "Anonymous" <sip:anonymous@anonymous.invalid:5063>;tag=as192b8891
To: <sip:918228990@10.20.0.2
;tag=57c593265e21c2b70aea50cb414df9cd.32679ccd
Contact: <sip:anonymous@10.20.0.1:5063>
Call-ID: 531668b959674f9f667f1c923d1d6c94@10.20.0.1:5063
CSeq: 102 ACK
User-Agent: SIPp
Content-Length: 0
and continues with ACK and repeating SIP 500 above....
*Sérgio Charrua*
.