kamailio-basic-kemi-lua.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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") then
  161. KSR.sl.sl_send_reply(200, "OK");
  162. KSR.x.exit();
  163. end
  164. if KSR.maxfwd.process_maxfwd(10) < 0 then
  165. KSR.sl.sl_send_reply(483,"Too Many Hops");
  166. KSR.x.exit();
  167. end
  168. if KSR.is_OPTIONS()
  169. and KSR.is_myself_ruri()
  170. and KSR.corex.has_ruri_user() < 0 then
  171. KSR.sl.sl_send_reply(200,"Keepalive");
  172. KSR.x.exit();
  173. end
  174. if KSR.sanity.sanity_check(17895, 7)<0 then
  175. KSR.err("malformed SIP message from "
  176. .. KSR.kx.get_srcip() .. ":" .. KSR.kx.get_srcport() .."\n");
  177. KSR.x.exit();
  178. end
  179. end
  180. -- Handle requests within SIP dialogs
  181. function ksr_route_withindlg()
  182. if KSR.siputils.has_totag()<0 then return 1; end
  183. -- sequential request withing a dialog should
  184. -- take the path determined by record-routing
  185. if KSR.rr.loose_route()>0 then
  186. ksr_route_dlguri();
  187. if KSR.is_BYE() then
  188. KSR.setflag(FLT_ACC); -- do accounting ...
  189. KSR.setflag(FLT_ACCFAILED); -- ... even if the transaction fails
  190. elseif KSR.is_ACK() then
  191. -- ACK is forwarded statelessly
  192. ksr_route_natmanage();
  193. elseif KSR.is_NOTIFY() then
  194. -- Add Record-Route for in-dialog NOTIFY as per RFC 6665.
  195. KSR.rr.record_route();
  196. end
  197. ksr_route_relay();
  198. KSR.x.exit();
  199. end
  200. if KSR.is_ACK() then
  201. if KSR.tm.t_check_trans() >0 then
  202. -- no loose-route, but stateful ACK;
  203. -- must be an ACK after a 487
  204. -- or e.g. 404 from upstream server
  205. ksr_route_relay();
  206. KSR.x.exit();
  207. else
  208. -- ACK without matching transaction ... ignore and discard
  209. KSR.x.exit();
  210. end
  211. end
  212. KSR.sl.sl_send_reply(404, "Not here");
  213. KSR.x.exit();
  214. end
  215. -- Handle SIP registrations
  216. function ksr_route_registrar()
  217. if not KSR.is_REGISTER() then return 1; end
  218. if KSR.isflagset(FLT_NATS) then
  219. KSR.setbflag(FLB_NATB);
  220. -- do SIP NAT pinging
  221. KSR.setbflag(FLB_NATSIPPING);
  222. end
  223. if KSR.registrar.save("location", 0)<0 then
  224. KSR.sl.sl_reply_error();
  225. end
  226. KSR.x.exit();
  227. end
  228. -- User location service
  229. function ksr_route_location()
  230. local rc = KSR.registrar.lookup("location");
  231. if rc<0 then
  232. KSR.tm.t_newtran();
  233. if rc==-1 or rc==-3 then
  234. KSR.sl.send_reply(404, "Not Found");
  235. KSR.x.exit();
  236. elseif rc==-2 then
  237. KSR.sl.send_reply(405, "Method Not Allowed");
  238. KSR.x.exit();
  239. end
  240. end
  241. -- when routing via usrloc, log the missed calls also
  242. if KSR.is_INVITE() then
  243. KSR.setflag(FLT_ACCMISSED);
  244. end
  245. ksr_route_relay();
  246. KSR.x.exit();
  247. end
  248. -- IP authorization and user authentication
  249. function ksr_route_auth()
  250. if not KSR.auth then
  251. return 1;
  252. end
  253. if KSR.permissions and not KSR.is_REGISTER() then
  254. if KSR.permissions.allow_source_address(1)>0 then
  255. -- source IP allowed
  256. return 1;
  257. end
  258. end
  259. if KSR.is_REGISTER() or KSR.is_myself_furi() then
  260. -- authenticate requests
  261. if KSR.auth_db.auth_check(KSR.kx.gete_fhost(), "subscriber", 1)<0 then
  262. KSR.auth.auth_challenge(KSR.kx.gete_fhost(), 0);
  263. KSR.x.exit();
  264. end
  265. -- user authenticated - remove auth header
  266. if not KSR.is_method_in("RP") then
  267. KSR.auth.consume_credentials();
  268. end
  269. end
  270. -- if caller is not local subscriber, then check if it calls
  271. -- a local destination, otherwise deny, not an open relay here
  272. if (not KSR.is_myself_furi())
  273. and (not KSR.is_myself_ruri()) then
  274. KSR.sl.sl_send_reply(403,"Not relaying");
  275. KSR.x.exit();
  276. end
  277. return 1;
  278. end
  279. -- Caller NAT detection
  280. function ksr_route_natdetect()
  281. if not KSR.nathelper then
  282. return 1;
  283. end
  284. if KSR.nathelper.nat_uac_test(19)>0 then
  285. if KSR.is_REGISTER() then
  286. KSR.nathelper.fix_nated_register();
  287. elseif KSR.siputils.is_first_hop()>0 then
  288. KSR.nathelper.set_contact_alias();
  289. end
  290. KSR.setflag(FLT_NATS);
  291. end
  292. return 1;
  293. end
  294. -- RTPProxy control
  295. function ksr_route_natmanage()
  296. if not KSR.rtpproxy then
  297. return 1;
  298. end
  299. if KSR.siputils.is_request()>0 then
  300. if KSR.siputils.has_totag()>0 then
  301. if KSR.rr.check_route_param("nat=yes")>0 then
  302. KSR.setbflag(FLB_NATB);
  303. end
  304. end
  305. end
  306. if (not (KSR.isflagset(FLT_NATS) or KSR.isbflagset(FLB_NATB))) then
  307. return 1;
  308. end
  309. KSR.rtpproxy.rtpproxy_manage("co");
  310. if KSR.siputils.is_request()>0 then
  311. if KSR.siputils.has_totag()<0 then
  312. if KSR.tmx.t_is_branch_route()>0 then
  313. KSR.rr.add_rr_param(";nat=yes");
  314. end
  315. end
  316. end
  317. if KSR.siputils.is_reply()>0 then
  318. if KSR.isbflagset(FLB_NATB) then
  319. KSR.nathelper.set_contact_alias();
  320. end
  321. end
  322. return 1;
  323. end
  324. -- URI update for dialog requests
  325. function ksr_route_dlguri()
  326. if not KSR.nathelper then
  327. return 1;
  328. end
  329. if not KSR.isdsturiset() then
  330. KSR.nathelper.handle_ruri_alias();
  331. end
  332. return 1;
  333. end
  334. -- Routing to foreign domains
  335. function ksr_route_sipout()
  336. if KSR.is_myself_ruri() then return 1; end
  337. KSR.hdr.append("P-Hint: outbound\r\n");
  338. ksr_route_relay();
  339. KSR.x.exit();
  340. end
  341. -- Manage outgoing branches
  342. -- equivalent of branch_route[...]{}
  343. function ksr_branch_manage()
  344. KSR.dbg("new branch [".. KSR.pv.get("$T_branch_idx")
  345. .. "] to " .. KSR.kx.get_ruri() .. "\n");
  346. ksr_route_natmanage();
  347. return 1;
  348. end
  349. -- Manage incoming replies
  350. -- equivalent of onreply_route[...]{}
  351. function ksr_onreply_manage()
  352. KSR.dbg("incoming reply\n");
  353. local scode = KSR.kx.get_status();
  354. if scode>100 and scode<299 then
  355. ksr_route_natmanage();
  356. end
  357. return 1;
  358. end
  359. -- Manage failure routing cases
  360. -- equivalent of failure_route[...]{}
  361. function ksr_failure_manage()
  362. ksr_route_natmanage();
  363. if KSR.tm.t_is_canceled()>0 then
  364. return 1;
  365. end
  366. return 1;
  367. end
  368. -- SIP response handling
  369. -- equivalent of reply_route{}
  370. function ksr_reply_route()
  371. KSR.dbg("response - from kamailio lua script\n");
  372. if KSR.sanity.sanity_check(17604, 6)<0 then
  373. KSR.err("malformed SIP response from "
  374. .. KSR.kx.get_srcip() .. ":" .. KSR.kx.get_srcport() .."\n");
  375. KSR.x.drop();
  376. end
  377. return 1;
  378. end