kamailio-basic-kemi-lua.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. -- Kamailio - equivalent of routing blocks in Lua
  2. --
  3. -- KSR - the object exporting Kamailio KEMI functions (app_lua module)
  4. -- sr - the old object exporting Kamailio functions (app_lua_sr module)
  5. --
  6. -- Relevant remarks:
  7. -- * do not execute Lua 'exit' - that will kill Lua interpreter which is
  8. -- embedded in Kamailio, resulting in killing Kamailio
  9. -- * use KSR.x.exit() to trigger the stop of executing the script
  10. -- * KSR.drop() is only marking the SIP message for drop, but doesn't stop
  11. -- the execution of the script. Use KSR.x.exit() after it or KSR.x.drop()
  12. --
  13. -- Hints:
  14. -- * Lua syntax check: luac -p /path/to/script.lua
  15. --
  16. -- debug callback function to print details of execution trace
  17. --[[
  18. local ksr_exec_level=0
  19. local function ksr_exec_hook(event)
  20. local s = "";
  21. local t = debug.getinfo(3)
  22. s = s .. ksr_exec_level .. ">>> " .. string.rep(" ", ksr_exec_level);
  23. if t~=nil and t.currentline>=0 then
  24. s = s .. t.short_src .. ":" .. t.currentline .. " ";
  25. end
  26. t=debug.getinfo(2)
  27. if event=="call" then
  28. ksr_exec_level = ksr_exec_level + 1;
  29. else
  30. ksr_exec_level = ksr_exec_level - 1;
  31. if ksr_exec_level < 0 then
  32. ksr_exec_level = 0;
  33. end
  34. end
  35. if t.what=="main" then
  36. if event=="call" then
  37. s = s .. "begin " .. t.short_src;
  38. else
  39. s = s .. "end " .. t.short_src;
  40. end
  41. elseif t.what=="Lua" then
  42. s = s .. event .. " " .. t.name or "(Lua)" .. " <" .. t.linedefined .. ":" .. t.short_src .. ">";
  43. else
  44. s = s .. event .. " " .. t.name or "(C)" .. " [" .. t.what .. "] ";
  45. end
  46. KSR.info(s .. "\n");
  47. end
  48. debug.sethook(ksr_exec_hook, "cr")
  49. ksr_exec_level=0
  50. ]]--
  51. -- global variables corresponding to defined values (e.g., flags) in kamailio.cfg
  52. FLT_ACC=1
  53. FLT_ACCMISSED=2
  54. FLT_ACCFAILED=3
  55. FLT_NATS=5
  56. FLB_NATB=6
  57. FLB_NATSIPPING=7
  58. -- SIP request routing
  59. -- equivalent of request_route{}
  60. function ksr_request_route()
  61. -- per request initial checks
  62. ksr_route_reqinit();
  63. -- NAT detection
  64. ksr_route_natdetect();
  65. -- CANCEL processing
  66. if KSR.is_CANCEL() then
  67. if KSR.tm.t_check_trans()>0 then
  68. ksr_route_relay();
  69. end
  70. return 1;
  71. end
  72. -- handle retransmissions
  73. if not KSR.is_ACK() then
  74. if KSR.tmx.t_precheck_trans()>0 then
  75. KSR.tm.t_check_trans();
  76. return 1;
  77. end
  78. if KSR.tm.t_check_trans()==0 then return 1 end
  79. end
  80. -- handle requests within SIP dialogs
  81. ksr_route_withindlg();
  82. -- -- only initial requests (no To tag)
  83. -- authentication
  84. ksr_route_auth();
  85. -- record routing for dialog forming requests (in case they are routed)
  86. -- - remove preloaded route headers
  87. KSR.hdr.remove("Route");
  88. -- if INVITE or SUBSCRIBE
  89. if KSR.is_method_in("IS") then
  90. KSR.rr.record_route();
  91. end
  92. -- account only INVITEs
  93. if KSR.is_INVITE() then
  94. KSR.setflag(FLT_ACC); -- do accounting
  95. end
  96. -- dispatch requests to foreign domains
  97. ksr_route_sipout();
  98. -- -- requests for my local domains
  99. -- handle registrations
  100. ksr_route_registrar();
  101. if KSR.corex.has_ruri_user() < 0 then
  102. -- request with no Username in RURI
  103. KSR.sl.sl_send_reply(484, "Address Incomplete");
  104. return 1;
  105. end
  106. -- user location service
  107. ksr_route_location();
  108. return 1;
  109. end
  110. -- wrapper around tm relay function
  111. function ksr_route_relay()
  112. -- enable additional event routes for forwarded requests
  113. -- - serial forking, RTP relaying handling, a.s.o.
  114. if KSR.is_method_in("IBSU") then
  115. if KSR.tm.t_is_set("branch_route")<0 then
  116. KSR.tm.t_on_branch("ksr_branch_manage");
  117. end
  118. end
  119. if KSR.is_method_in("ISU") then
  120. if KSR.tm.t_is_set("onreply_route")<0 then
  121. KSR.tm.t_on_reply("ksr_onreply_manage");
  122. end
  123. end
  124. if KSR.is_INVITE() then
  125. if KSR.tm.t_is_set("failure_route")<0 then
  126. KSR.tm.t_on_failure("ksr_failure_manage");
  127. end
  128. end
  129. if KSR.tm.t_relay()<0 then
  130. KSR.sl.sl_reply_error();
  131. end
  132. KSR.x.exit();
  133. end
  134. -- Per SIP request initial checks
  135. function ksr_route_reqinit()
  136. -- no connect for sending replies
  137. KSR.set_reply_no_connect();
  138. -- enforce symmetric signaling
  139. -- send back replies to the source address of request
  140. KSR.force_rport();
  141. if not KSR.is_myself_srcip() then
  142. local srcip = KSR.kx.get_srcip();
  143. if KSR.htable.sht_match_name("ipban", "eq", srcip) > 0 then
  144. -- ip is already blocked
  145. KSR.dbg("request from blocked IP - " .. KSR.kx.get_method()
  146. .. " from " .. KSR.kx.get_furi() .. " (IP:"
  147. .. srcip .. ":" .. KSR.kx.get_srcport() .. ")\n");
  148. KSR.x.exit();
  149. end
  150. if KSR.pike.pike_check_req() < 0 then
  151. KSR.err("ALERT: pike blocking " .. KSR.kx.get_method()
  152. .. " from " .. KSR.kx.get_furi() .. " (IP:"
  153. .. srcip .. ":" .. KSR.kx.get_srcport() .. ")\n");
  154. KSR.htable.sht_seti("ipban", srcip, 1);
  155. KSR.x.exit();
  156. end
  157. end
  158. local ua = KSR.kx.gete_ua();
  159. if string.find(ua, "friendly") or string.find(ua, "scanner")
  160. or string.find(ua, "sipcli") or string.find(ua, "sipvicious")
  161. or string.find(ua, "VaxSIPUserAgent") or string.find(ua, "pplsip") then
  162. KSR.sl.sl_send_reply(200, "OK");
  163. KSR.x.exit();
  164. end
  165. if KSR.maxfwd.process_maxfwd(10) < 0 then
  166. KSR.sl.sl_send_reply(483, "Too Many Hops");
  167. KSR.x.exit();
  168. end
  169. if KSR.is_OPTIONS()
  170. and KSR.is_myself_ruri()
  171. and KSR.corex.has_ruri_user() < 0 then
  172. KSR.sl.sl_send_reply(200, "Keepalive");
  173. KSR.x.exit();
  174. end
  175. if KSR.sanity.sanity_check(17895, 7)<0 then
  176. KSR.err("malformed SIP message from "
  177. .. KSR.kx.get_srcip() .. ":" .. KSR.kx.get_srcport() .."\n");
  178. KSR.x.exit();
  179. end
  180. end
  181. -- Handle requests within SIP dialogs
  182. function ksr_route_withindlg()
  183. if KSR.siputils.has_totag()<0 then return 1; end
  184. -- sequential request within a dialog should
  185. -- take the path determined by record-routing
  186. if KSR.rr.loose_route()>0 then
  187. ksr_route_dlguri();
  188. if KSR.is_BYE() then
  189. KSR.setflag(FLT_ACC); -- do accounting ...
  190. KSR.setflag(FLT_ACCFAILED); -- ... even if the transaction fails
  191. elseif KSR.is_ACK() then
  192. -- ACK is forwarded statelessly
  193. ksr_route_natmanage();
  194. elseif KSR.is_NOTIFY() then
  195. -- Add Record-Route for in-dialog NOTIFY as per RFC 6665.
  196. KSR.rr.record_route();
  197. end
  198. ksr_route_relay();
  199. KSR.x.exit();
  200. end
  201. if KSR.is_ACK() then
  202. if KSR.tm.t_check_trans() >0 then
  203. -- no loose-route, but stateful ACK;
  204. -- must be an ACK after a 487
  205. -- or e.g. 404 from upstream server
  206. ksr_route_relay();
  207. KSR.x.exit();
  208. else
  209. -- ACK without matching transaction ... ignore and discard
  210. KSR.x.exit();
  211. end
  212. end
  213. KSR.sl.sl_send_reply(404, "Not here");
  214. KSR.x.exit();
  215. end
  216. -- Handle SIP registrations
  217. function ksr_route_registrar()
  218. if not KSR.is_REGISTER() then return 1; end
  219. if KSR.isflagset(FLT_NATS) then
  220. KSR.setbflag(FLB_NATB);
  221. -- do SIP NAT pinging
  222. KSR.setbflag(FLB_NATSIPPING);
  223. end
  224. if KSR.registrar.save("location", 0)<0 then
  225. KSR.sl.sl_reply_error();
  226. end
  227. KSR.x.exit();
  228. end
  229. -- User location service
  230. function ksr_route_location()
  231. local rc = KSR.registrar.lookup("location");
  232. if rc<0 then
  233. KSR.tm.t_newtran();
  234. if rc==-1 or rc==-3 then
  235. KSR.sl.send_reply(404, "Not Found");
  236. KSR.x.exit();
  237. elseif rc==-2 then
  238. KSR.sl.send_reply(405, "Method Not Allowed");
  239. KSR.x.exit();
  240. end
  241. end
  242. -- when routing via usrloc, log the missed calls also
  243. if KSR.is_INVITE() then
  244. KSR.setflag(FLT_ACCMISSED);
  245. end
  246. ksr_route_relay();
  247. KSR.x.exit();
  248. end
  249. -- IP authorization and user authentication
  250. function ksr_route_auth()
  251. if not KSR.auth then
  252. return 1;
  253. end
  254. if KSR.permissions and not KSR.is_REGISTER() then
  255. if KSR.permissions.allow_source_address(1)>0 then
  256. -- source IP allowed
  257. return 1;
  258. end
  259. end
  260. if KSR.is_REGISTER() or KSR.is_myself_furi() then
  261. -- authenticate requests
  262. if KSR.auth_db.auth_check(KSR.kx.gete_fhost(), "subscriber", 1)<0 then
  263. KSR.auth.auth_challenge(KSR.kx.gete_fhost(), 0);
  264. KSR.x.exit();
  265. end
  266. -- user authenticated - remove auth header
  267. if not KSR.is_method_in("RP") then
  268. KSR.auth.consume_credentials();
  269. end
  270. end
  271. -- if caller is not local subscriber, then check if it calls
  272. -- a local destination, otherwise deny, not an open relay here
  273. if (not KSR.is_myself_furi())
  274. and (not KSR.is_myself_ruri()) then
  275. KSR.sl.sl_send_reply(403, "Not relaying");
  276. KSR.x.exit();
  277. end
  278. return 1;
  279. end
  280. -- Caller NAT detection
  281. function ksr_route_natdetect()
  282. if not KSR.nathelper then
  283. return 1;
  284. end
  285. if KSR.nathelper.nat_uac_test(19)>0 then
  286. if KSR.is_REGISTER() then
  287. KSR.nathelper.fix_nated_register();
  288. elseif KSR.siputils.is_first_hop()>0 then
  289. KSR.nathelper.set_contact_alias();
  290. end
  291. KSR.setflag(FLT_NATS);
  292. end
  293. return 1;
  294. end
  295. -- RTPProxy control
  296. function ksr_route_natmanage()
  297. if not KSR.rtpproxy and not KSR.rtpengine then
  298. return 1;
  299. end
  300. if KSR.siputils.is_request()>0 then
  301. if KSR.siputils.has_totag()>0 then
  302. if KSR.rr.check_route_param("nat=yes")>0 then
  303. KSR.setbflag(FLB_NATB);
  304. end
  305. end
  306. end
  307. if (not (KSR.isflagset(FLT_NATS) or KSR.isbflagset(FLB_NATB))) then
  308. return 1;
  309. end
  310. if KSR.kx.ifdef('WITH_RTPENGINE') then
  311. if KSR.nathelper.nat_uac_test(8)>0 then
  312. KSR.rtpengine.rtpengine_manage("replace-origin replace-session-connection SIP-source-address");
  313. else
  314. KSR.rtpengine.rtpengine_manage("replace-origin replace-session-connection");
  315. end
  316. else
  317. if KSR.nathelper.nat_uac_test(8)>0 then
  318. KSR.rtpproxy.rtpproxy_manage("co");
  319. else
  320. KSR.rtpproxy.rtpproxy_manage("cor");
  321. end
  322. end
  323. if KSR.siputils.is_request()>0 then
  324. if KSR.siputils.has_totag()<0 then
  325. if KSR.tmx.t_is_branch_route()>0 then
  326. KSR.rr.add_rr_param(";nat=yes");
  327. end
  328. end
  329. end
  330. if KSR.siputils.is_reply()>0 then
  331. if KSR.isbflagset(FLB_NATB) then
  332. KSR.nathelper.set_contact_alias();
  333. end
  334. end
  335. return 1;
  336. end
  337. -- URI update for dialog requests
  338. function ksr_route_dlguri()
  339. if not KSR.nathelper then
  340. return 1;
  341. end
  342. if not KSR.isdsturiset() then
  343. KSR.nathelper.handle_ruri_alias();
  344. end
  345. return 1;
  346. end
  347. -- Routing to foreign domains
  348. function ksr_route_sipout()
  349. if KSR.is_myself_ruri() then return 1; end
  350. KSR.hdr.append("P-Hint: outbound\r\n");
  351. ksr_route_relay();
  352. KSR.x.exit();
  353. end
  354. -- Manage outgoing branches
  355. -- equivalent of branch_route[...]{}
  356. function ksr_branch_manage()
  357. KSR.dbg("new branch [".. KSR.pv.get("$T_branch_idx")
  358. .. "] to " .. KSR.kx.get_ruri() .. "\n");
  359. ksr_route_natmanage();
  360. return 1;
  361. end
  362. -- Manage incoming replies
  363. -- equivalent of onreply_route[...]{}
  364. function ksr_onreply_manage()
  365. KSR.dbg("incoming reply\n");
  366. local scode = KSR.kx.get_status();
  367. if scode>100 and scode<299 then
  368. ksr_route_natmanage();
  369. end
  370. return 1;
  371. end
  372. -- Manage failure routing cases
  373. -- equivalent of failure_route[...]{}
  374. function ksr_failure_manage()
  375. ksr_route_natmanage();
  376. if KSR.tm.t_is_canceled()>0 then
  377. return 1;
  378. end
  379. return 1;
  380. end
  381. -- SIP response handling
  382. -- equivalent of reply_route{}
  383. function ksr_reply_route()
  384. KSR.dbg("response - from kamailio lua script\n");
  385. if KSR.sanity.sanity_check(17604, 6)<0 then
  386. KSR.err("malformed SIP response from "
  387. .. KSR.kx.get_srcip() .. ":" .. KSR.kx.get_srcport() .."\n");
  388. KSR.x.drop();
  389. end
  390. return 1;
  391. end