Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
examples/kemi: added cfg examples of using lua config routing
- based on kamailio-basic.cfg
- Loading branch information
Showing
3 changed files
with
1,049 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,357 @@ | ||
-- Kamailio - equivalent of routing blocks in Lua | ||
-- KSR - the new dynamic object exporting Kamailio functions | ||
-- sr - the old static object exporting Kamailio functions | ||
-- | ||
|
||
FLT_ACC=1 | ||
FLT_ACCMISSED=2 | ||
FLT_ACCFAILED=3 | ||
FLT_NATS=5 | ||
|
||
FLB_NATB=6 | ||
FLB_NATSIPPING=7 | ||
|
||
-- SIP request routing | ||
-- equivalent of request_route{} | ||
function ksr_request_route() | ||
-- KSR.sl.sl_send_reply("100","Intelligent trying"); | ||
-- KSR.info("===== request - from kamailio lua script\n"); | ||
|
||
-- per request initial checks | ||
if ksr_route_reqinit()==-255 then return 1; end | ||
|
||
-- NAT detection | ||
if ksr_route_natdetect()==-255 then return 1; end | ||
|
||
-- CANCEL processing | ||
if KSR.pv.get("$rm") == "CANCEL" then | ||
if KSR.tm.t_check_trans()>0 then | ||
ksr_route_relay(); | ||
end | ||
return 1; | ||
end | ||
|
||
-- handle requests within SIP dialogs | ||
ksr_route_withindlg(); | ||
|
||
-- -- only initial requests (no To tag) | ||
|
||
-- handle retransmissions | ||
if KSR.tmx.t_precheck_trans()>0 then | ||
KSR.tm.t_check_trans(); | ||
return 1; | ||
end | ||
if KSR.tm.t_check_trans()==0 then return 1 end | ||
|
||
-- authentication | ||
if ksr_route_auth()==-255 then return 1 end | ||
|
||
-- record routing for dialog forming requests (in case they are routed) | ||
-- - remove preloaded route headers | ||
KSR.hdr.remove("Route"); | ||
if string.find("INVITE|SUBSCRIBE", KSR.pv.get("$rm")) then | ||
KSR.rr.record_route(); | ||
end | ||
|
||
-- account only INVITEs | ||
if KSR.pv.get("$rm")=="INVITE" then | ||
KSR.setflag(FLT_ACC); -- do accounting | ||
end | ||
|
||
-- dispatch requests to foreign domains | ||
if ksr_route_sipout()==-255 then return 1; end | ||
|
||
-- -- requests for my local domains | ||
|
||
-- handle registrations | ||
if ksr_route_registrar()==-255 then return 1; end | ||
|
||
if KSR.pv.is_null("$rU") then | ||
-- request with no Username in RURI | ||
KSR.sl.sl_send_reply("484","Address Incomplete"); | ||
return 1; | ||
end | ||
|
||
-- user location service | ||
ksr_route_location(); | ||
|
||
return 1; | ||
end | ||
|
||
-- wrapper around tm relay function | ||
function ksr_route_relay() | ||
-- enable additional event routes for forwarded requests | ||
-- - serial forking, RTP relaying handling, a.s.o. | ||
if string.find("INVITE,BYE,SUBSCRIBE,UPDATE", KSR.pv.get("$rm")) then | ||
if KSR.tm.t_is_set("branch_route")<0 then | ||
KSR.tm.t_on_branch("ksr_branch_manage"); | ||
end | ||
end | ||
if string.find("INVITE,SUBSCRIBE,UPDATE", KSR.pv.get("$rm")) then | ||
if KSR.tm.t_is_set("onreply_route")<0 then | ||
KSR.tm.t_on_reply("ksr_onreply_manage"); | ||
end | ||
end | ||
|
||
if KSR.pv.get("$rm")=="INVITE" then | ||
if KSR.tm.t_is_set("failure_route")<0 then | ||
KSR.tm.t_on_failure("MANAGE_FAILURE"); | ||
end | ||
end | ||
|
||
if KSR.tm.t_relay()<0 then | ||
KSR.sl.sl_reply_error(); | ||
end | ||
return -255; | ||
end | ||
|
||
|
||
-- Per SIP request initial checks | ||
function ksr_route_reqinit() | ||
if not KSR.is_myself(KSR.pv.get("$si")) then | ||
if not KSR.pv.is_null("$sht(ipban=>$si)") then | ||
-- ip is already blocked | ||
KSR.dbg("request from blocked IP - " .. KSR.pv.get("$rm") | ||
.. " from " .. KSR.pv.get("$fu") .. " (IP:" | ||
.. KSR.pv.get("$si") .. ":" .. KSR.pv.get("$sp") .. ")\n"); | ||
return -255; | ||
end | ||
if KSR.pike.pike_check_req()<0 then | ||
KSR.err("ALERT: pike blocking " .. KSR.pv.get("$rm") | ||
.. " from " .. KSR.pv.get("$fu") .. " (IP:" | ||
.. KSR.pv.get("$si") .. ":" .. KSR.pv.get("$sp") .. ")\n"); | ||
KSR.pv.seti("$sht(ipban=>$si)", 1); | ||
return -255; | ||
end | ||
end | ||
if (not KSR.pv.is_null("$ua")) | ||
and (string.find(KSR.pv.get("$ua"), "friendly-scanner") | ||
or string.find(KSR.pv.get("$ua"), "sipcli")) then | ||
KSR.sl.sl_send_reply("200", "OK"); | ||
return -255; | ||
end | ||
|
||
if KSR.maxfwd.process_maxfwd(10) < 0 then | ||
KSR.sl.sl_send_reply("483","Too Many Hops"); | ||
return -255; | ||
end | ||
|
||
if KSR.pv.get("$rm")=="OPTIONS" | ||
and KSR.is_myself(KSR.pv.get("$ru")) | ||
and KSR.pv.is_null("$rU") then | ||
KSR.sl.sl_send_reply("200","Keepalive"); | ||
return -255; | ||
end | ||
|
||
if KSR.sanity.sanity_check(1511, 7)<0 then | ||
KSR.err("Malformed SIP message from " | ||
.. KSR.pv.get("$si") .. ":" .. KSR.pv.get("$sp") .."\n"); | ||
return -255; | ||
end | ||
|
||
end | ||
|
||
|
||
-- Handle requests within SIP dialogs | ||
function ksr_route_withindlg() | ||
if KSR.siputils.has_totag()<0 then return -255; end | ||
|
||
-- sequential request withing a dialog should | ||
-- take the path determined by record-routing | ||
if KSR.rr.loose_route()>0 then | ||
if ksr_route_dlguri()==-255 then return -255; end | ||
if KSR.pv.get("$rm")=="BYE" then | ||
KSR.setflag(FLT_ACC); -- do accounting ... | ||
KSR.setflag(FLT_ACCFAILED); -- ... even if the transaction fails | ||
elseif KSR.pv.get("$rm")=="ACK" then | ||
-- ACK is forwarded statelessy | ||
if ksr_route_natmanage()==-255 then return -255; end | ||
elseif KSR.pv.get("$rm")=="NOTIFY" then | ||
-- Add Record-Route for in-dialog NOTIFY as per RFC 6665. | ||
KSR.rr.record_route(); | ||
end | ||
ksr_route_relay(); | ||
return -255; | ||
end | ||
if KSR.pv.get("$rm")=="ACK" then | ||
if KSR.tm.t_check_trans() >0 then | ||
-- no loose-route, but stateful ACK; | ||
-- must be an ACK after a 487 | ||
-- or e.g. 404 from upstream server | ||
ksr_route_relay(); | ||
return -255; | ||
else | ||
-- ACK without matching transaction ... ignore and discard | ||
return -255; | ||
end | ||
end | ||
KSR.sl.sl_send_reply("404", "Not here"); | ||
return -255; | ||
end | ||
|
||
-- Handle SIP registrations | ||
function ksr_route_registrar() | ||
if KSR.pv.get("$rm")~="REGISTER" then return 1; end | ||
if KSR.isflagset(FLT_NATS) then | ||
KSR.setbflag(FLB_NATB); | ||
-- do SIP NAT pinging | ||
KSR.setbflag(FLB_NATSIPPING); | ||
end | ||
if KSR.registrar.save("location", 0)<0 then | ||
KSR.sl.sl_reply_error(); | ||
end | ||
return -255; | ||
end | ||
|
||
-- User location service | ||
function ksr_route_location() | ||
local rc = KSR.registrar.lookup("location"); | ||
if rc<0 then | ||
KSR.tm.t_newtran(); | ||
if rc==-1 or rc==-3 then | ||
KSR.sl.send_reply("404", "Not Found"); | ||
return -255; | ||
elseif rc==-2 then | ||
KSR.sl.send_reply("405", "Method Not Allowed"); | ||
return -255; | ||
end | ||
end | ||
|
||
-- when routing via usrloc, log the missed calls also | ||
if KSR.pv.get("$rm")=="INVITE" then | ||
KSR.setflag(FLT_ACCMISSED); | ||
end | ||
|
||
ksr_route_relay(); | ||
return -255; | ||
end | ||
|
||
|
||
-- IP authorization and user uthentication | ||
function ksr_route_auth() | ||
|
||
if KSR.pv.get("$rm")~="REGISTER" then | ||
if KSR.permissions.allow_source_address("1")>0 then | ||
-- source IP allowed | ||
return 1; | ||
end | ||
end | ||
|
||
if KSR.pv.get("$rm")=="REGISTER" or KSR.is_myself(KSR.pv.get("$fu")) then | ||
-- authenticate requests | ||
if KSR.auth_db.auth_check(KSR.pv.get("$fd"), "subscriber", 1)<0 then | ||
KSR.auth.auth_challenge(KSR.pv.get("$fd"), "0"); | ||
return -255; | ||
end | ||
-- user authenticated - remove auth header | ||
if not string.find("REGISTER,PUBLISH", KSR.pv.get("$rm")) then | ||
KSR.auth.consume_credentials(); | ||
end | ||
end | ||
|
||
-- if caller is not local subscriber, then check if it calls | ||
-- a local destination, otherwise deny, not an open relay here | ||
if (not KSR.is_myself(KSR.pv.get("$fu")) | ||
and (not KSR.is_myself(KSR.pv.get("$ru")))) then | ||
KSR.sl.sl_send_reply("403","Not relaying"); | ||
return -255; | ||
end | ||
|
||
return 1; | ||
end | ||
|
||
-- Caller NAT detection | ||
function ksr_route_natdetect() | ||
KSR.force_rport(); | ||
if KSR.nathelper.nat_uac_test(19)>0 then | ||
if KSR.pv.get("$rm")=="REGISTER" then | ||
KSR.nathelper.fix_nated_register(); | ||
elseif KSR.siputils.is_first_hop()>0 then | ||
KSR.nathelper.set_contact_alias(); | ||
end | ||
KSR.setflag(FLT_NATS); | ||
end | ||
return 1; | ||
end | ||
|
||
-- RTPProxy control | ||
function ksr_route_natmanage() | ||
if KSR.siputils.is_request()>0 then | ||
if KSR.siputils.has_totag()>0 then | ||
if KSR.rr.check_route_param("nat=yes")>0 then | ||
KSR.setbflag(FLB_NATB); | ||
end | ||
end | ||
end | ||
if (not (KSR.isflagset(FLT_NATS) or KSR.isbflagset(FLB_NATB))) then | ||
return 1; | ||
end | ||
|
||
KSR.rtpproxy.rtpproxy_manage("co"); | ||
|
||
if KSR.siputils.is_request()>0 then | ||
if not KSR.siputils.has_totag() then | ||
if KSR.tmx.t_is_branch_route()>0 then | ||
KSR.rr.add_rr_param(";nat=yes"); | ||
end | ||
end | ||
end | ||
if KSR.siputils.is_reply()>0 then | ||
if KSR.isbflagset(FLB_NATB) then | ||
KSR.nathelper.set_contact_alias(); | ||
end | ||
end | ||
return 1; | ||
end | ||
|
||
-- URI update for dialog requests | ||
function ksr_route_dlguri() | ||
if not KSR.isdsturiset() then | ||
KSR.nathelper.handle_ruri_alias(); | ||
end | ||
return 1; | ||
end | ||
|
||
-- Routing to foreign domains | ||
function ksr_route_sipout() | ||
if KSR.is_myself(KSR.pv.get("$ru")) then return 1; end | ||
|
||
KSR.hdr.append_hf("P-Hint: outbound\r\n"); | ||
ksr_route_relay(); | ||
return -255; | ||
end | ||
|
||
-- Manage outgoing branches | ||
function ksr_branch_manage() | ||
KSR.dbg("new branch [".. KSR.pv.get("$T_branch_idx]") | ||
.. " to ".. KSR.pv.get("$ru") .. "\n"); | ||
ksr_route_natmanage(); | ||
return 1; | ||
end | ||
|
||
-- Manage incoming replies | ||
function ksr_onreply_manage() | ||
KSR.dbg("incoming reply\n"); | ||
local scode = KSR.pv.get("$rs"); | ||
if scode>100 and scode<299 then | ||
ksr_route_natmanage(); | ||
end | ||
return 1; | ||
end | ||
|
||
-- Manage failure routing cases | ||
function ksr_failure_manage() | ||
if ksr_route_natmanage()==-255 then return 1; end | ||
|
||
if KSR.tm.t_is_canceled()>0 then | ||
return 1; | ||
end | ||
return 1; | ||
end | ||
|
||
-- SIP response routing | ||
-- equivalent of reply_route{} | ||
function ksr_reply_route() | ||
KSR.info("===== response - from kamailio lua script\n"); | ||
return 1; | ||
end |
Oops, something went wrong.