Guest User

Untitled

a guest
Jul 16th, 2020
778
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 94.08 KB | None | 0 0
  1. #!KAMAILIO
  2. #!define WITH_MYSQL
  3. #!define WITH_AUTH
  4. #!define WITH_IPAUTH
  5. #!define WITH_UAC
  6. #!define WITH_USRLOCDB
  7. #!define WITH_ACCDB
  8. #!define WITH_DROUTE
  9. #!define WITH_DEBUG
  10. #!define WITH_NAT
  11. #!define WITH_DISPATCHER
  12. #!define WITH_CALLLIMIT
  13. ##!define WITH_SERVERNAT
  14. #!define WITH_MULTIDOMAIN
  15. #!define WITH_TELEBLOCK
  16. #!define WITH_ANTIFLOOD
  17. ##!define WITH_DBCLUSTER
  18. #!define WITH_LCR
  19. #!define WITH_TLS
  20. #!define WITH_WEBSOCKETS
  21. ##!define WITH_DMQ
  22. #!define WITH_MSTEAMS
  23. #
  24. #!substdef "!INTERNAL_IP_ADDR!X.X.X.X!g"
  25. #!substdef "!INTERNAL_IP_NET!X.X.X.*!g"
  26. #!substdef "!EXTERNAL_IP_ADDR!X.X.X.X!g"
  27. #!substdef "!EXTERNAL_FQDN!sbc.yyyyy.com!g"
  28. #!substdef "!SIP_PORT!5060!g"
  29. #!substdef "!SIPS_PORT!5061!g"
  30. #!substdef "!DMQ_PORT!5090!g"
  31. #!substdef "!WSS_PORT!4443!g"
  32.  
  33. ####### Include Local Config If Exists #########
  34. import_file "kamailio-local.cfg"
  35.  
  36. ####### Defined Values #########
  37.  
  38. # - database URL - used to connect to database server by modules
  39. #!ifdef WITH_MYSQL
  40. #!ifdef WITH_DBCLUSTER
  41. #!define DBURL "cluster://dbcluster"
  42. #!define SQLCONN_KAM "kam=>mysql://kamailio:somerandompassword@localhost:3306/kamailio"
  43. #!define SQLCONN_AST "asterisk=>mysql://kamailio:somerandompassword@localhost:3306/kamailio"
  44. #!else
  45. #!define DBURL "mysql://kamailio:somerandompassword@localhost:3306/kamailio"
  46. #!define SQLCONN_KAM "kam=>mysql://kamailio:somerandompassword@localhost:3306/kamailio"
  47. #!define SQLCONN_AST "asterisk=>mysql://kamailio:somerandompassword@localhost:3306/kamailio"
  48. #!endif
  49. #!endif
  50.  
  51. #!ifdef WITH_MULTIDOMAIN
  52. # - the value for 'use_domain' parameters
  53. #!define MULTIDOMAIN 1
  54. #!else
  55. #!define MULTIDOMAIN 0
  56. #!endif
  57.  
  58. # - flags
  59. # FLT_ - per transaction (message) flags
  60. # FLB_ - per branch flags
  61. #!define FLT_ACC 1
  62. #!define FLT_ACCMISSED 2
  63. #!define FLT_ACCFAILED 3
  64. #!define FLT_NATS 5
  65.  
  66. #!define FLB_NATB 6
  67. #!define FLB_NATSIPPING 7
  68.  
  69.  
  70. #!define FLT_CARRIER 8
  71. #!define FLT_PBX 9
  72. #!define FLT_DOMAINROUTING 10
  73. #!define FLT_PBX_AUTH 11
  74. #!define FLT_CARRIER_AUTH 12
  75. #!define FLT_EXTERNAL_AUTH 13
  76. #!define FLT_PASSTHRU_AUTH 14
  77. #!define FLT_FAILOVER 15
  78. #!define FLT_DIALOG 16
  79. #!define FLT_SRC_SIP 17
  80. #!define FLT_SRC_WS 18
  81. #!define FLB_WS_DEVICE 19
  82. #!define FLT_USE_RTPE 20
  83. #!define FLT_SERVERNAT 21
  84. #!define FLT_MSTEAMS 22
  85. #!define FLB_SRC_MSTEAMS 23
  86. #!define FLB_DST_MSTEAMS 24
  87.  
  88.  
  89. #!define FLT_OUTBOUND 8000
  90. #!define FLT_INBOUND 9000
  91.  
  92. #!define NOTIFICATION_OVERLIMIT "0"
  93. #!define NOTIFICATION_GWFAILURE "1"
  94.  
  95. ####### Global Parameters #########
  96.  
  97. ### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR
  98. #!ifdef WITH_DEBUG
  99. debug=3
  100. log_stderror=no
  101. #!else
  102. debug=2
  103. log_stderror=no
  104. #!endif
  105.  
  106. memdbg=5
  107. memlog=5
  108.  
  109. log_facility=LOG_LOCAL0
  110.  
  111. fork=yes
  112. children=1
  113.  
  114. # increase loop limit to allow 10000 DID checks for inbound calls
  115. max_while_loops=10000
  116.  
  117. # uncomment the next line to disable TCP (default on)
  118. #disable_tcp=yes
  119.  
  120. # uncomment the next line to disable the auto discovery of local aliases
  121. # based on reverse DNS on IPs (default on)
  122. #auto_aliases=no
  123.  
  124. # add local domain aliases
  125. #alias="INTERNAL_IP_ADDR:SIP_PORT"
  126.  
  127. # SNGREP
  128. listen=udp:127.0.1.1:9061
  129.  
  130. # configure interface/port/proto kamailio will bind on
  131. #!ifdef WITH_SERVERNAT
  132. listen=udp:INTERNAL_IP_ADDR:SIP_PORT advertise EXTERNAL_IP_ADDR:SIP_PORT
  133. listen=tcp:INTERNAL_IP_ADDR:SIP_PORT advertise EXTERNAL_IP_ADDR:SIP_PORT
  134. listen=udp:127.0.0.1:SIP_PORT
  135. listen=tcp:127.0.0.1:SIP_PORT
  136. #!ifdef WITH_WEBSOCKETS
  137. listen=tls:INTERNAL_IP_ADDR:WSS_PORT advertise EXTERNAL_IP_ADDR:WSS_PORT
  138. #!endif
  139.  
  140. #!else
  141. listen=udp:INTERNAL_IP_ADDR:SIP_PORT
  142. listen=tcp:INTERNAL_IP_ADDR:SIP_PORT advertise EXTERNAL_IP_ADDR:SIP_PORT
  143. listen=udp:127.0.0.1:SIP_PORT
  144. listen=tcp:127.0.0.1:SIP_PORT
  145. #!ifdef WITH_WEBSOCKETS
  146. listen=tls:INTERNAL_IP_ADDR:WSS_PORT
  147. #!endif
  148. #!endif
  149.  
  150. #!ifdef WITH_DMQ
  151. listen=udp:INTERNAL_IP_ADDR:DMQ_PORT
  152. #!endif
  153.  
  154. # port to listen to
  155. # - can be specified more than once if needed to listen on many ports
  156. port=SIP_PORT
  157.  
  158. #!ifdef WITH_TLS
  159. enable_tls=yes
  160. #!ifdef WITH_SERVERNAT
  161. listen=tls:INTERNAL_IP_ADDR:SIPS_PORT advertise EXTERNAL_FQDN:SIPS_PORT
  162. #!else
  163. listen=tls:INTERNAL_IP_ADDR:SIPS_PORT advertise EXTERNAL_FQDN:SIPS_PORT
  164. #!endif
  165. tcp_accept_no_cl=yes
  166. tcp_rd_buf_size=16384
  167. #!endif
  168.  
  169. # life time of TCP connection when there is no traffic
  170. # - a bit higher than registration expires to cope with UA behind NAT
  171. tcp_connection_lifetime=3605
  172.  
  173. # this parameter controls the “Server” header in any locally generated message.
  174. # we disable it by default
  175. server_signature=no
  176.  
  177. ####### Custom Parameters #########
  178.  
  179. # These parameters can be modified runtime via RPC interface
  180. # - see the documentation of 'cfg_rpc' module.
  181. #
  182. # Format: group.id = value 'desc' description
  183. # Access: $sel(cfg_get.group.id) or @cfg_get.group.id
  184. #
  185.  
  186. #!ifdef WITH_PSTN
  187. # PSTN GW Routing
  188. #
  189. # - pstn.gw_ip: valid IP or hostname as string value, example:
  190. # pstn.gw_ip = "10.0.0.101" desc "My PSTN GW Address"
  191. #
  192. # - by default is empty to avoid misrouting
  193. pstn.gw_ip = "" desc "PSTN GW Address"
  194. pstn.gw_port = "" desc "PSTN GW Port"
  195. #!endif
  196.  
  197. #!ifdef WITH_VOICEMAIL
  198. # VoiceMail Routing on offline, busy or no answer
  199. #
  200. # - by default Voicemail server IP is empty to avoid misrouting
  201. voicemail.srv_ip = "" desc "VoiceMail IP Address"
  202. voicemail.srv_port = "5060" desc "VoiceMail Port"
  203. #!endif
  204.  
  205. #!ifdef WITH_TELEBLOCK
  206. teleblock.gw_enabled = 0 desc "Enable Teleblock support"
  207. teleblock.gw_ip = "62.34.24.22" desc "Teleblock IP"
  208. teleblock.gw_port = "5066" desc "Teleblock Port"
  209. teleblock.media_ip = "" desc "Teleblock media ip"
  210. teleblock.media_port = "" desc "Teleblock media port"
  211. #!endif
  212.  
  213. # Define the role of the server
  214. # "" - default behavior
  215. # outbound - outbound only (no domain routing)
  216. # inout - inbound and outbound only (no domain routing)
  217. server.role = "" desc "Role of the server in the topology"
  218.  
  219. # Rename who we are
  220. server_header="dSIPRouter Project"
  221.  
  222. # Local calling maximum digits for the initiating PBX - PBX sending the INVITE
  223. server.pbx_max_local_digits = 5 desc "Maximum digits for local pbx extensions"
  224.  
  225. # PBX INVITE Timeout (msecs) to support having a Primary and Secondary PBX
  226. server.pbx_invite_timeout = 16000 desc "The default PBX INVITE timeout"
  227.  
  228. # PBX INVITE Timeout (msecs) if a SIP 100/180/181/183 message is received
  229. server.pbx_invite_timeout_aftertry = 52000 desc "PBX INVITE timeout value if a SIP 100 message is received"
  230.  
  231. # DSIPRouter API Server Settings
  232. server.api_server = "https://127.0.0.1:5000" desc "URL to the DSIPRouter API Server"
  233. server.api_token = "somerandomtoken" desc "API Token for DSIPRouter API Server"
  234.  
  235. ####### Modules Section ########
  236.  
  237. # set paths to location of modules (to sources or installation folders)
  238. #!ifdef WITH_SRCPATH
  239. mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
  240. #!else
  241. mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
  242. #!endif
  243.  
  244.  
  245. #!ifdef WITH_MYSQL
  246. loadmodule "db_mysql.so"
  247. #!endif
  248.  
  249. loadmodule "kex.so"
  250. loadmodule "corex.so"
  251. loadmodule "tm.so"
  252. loadmodule "tmx.so"
  253. loadmodule "sl.so"
  254. loadmodule "rr.so"
  255. loadmodule "path.so"
  256. loadmodule "pv.so"
  257. loadmodule "maxfwd.so"
  258. loadmodule "usrloc.so"
  259. loadmodule "registrar.so"
  260. loadmodule "dsiprouter.so"
  261. loadmodule "sdpops.so"
  262. loadmodule "textops.so"
  263. loadmodule "textopsx.so"
  264. loadmodule "siputils.so"
  265. loadmodule "xlog.so"
  266. loadmodule "sanity.so"
  267. loadmodule "ctl.so"
  268. loadmodule "cfg_rpc.so"
  269. loadmodule "acc.so"
  270. loadmodule "xhttp.so"
  271. loadmodule "jsonrpcs.so"
  272. loadmodule "http_async_client.so"
  273.  
  274. # Load the SIPTRACE module
  275. loadmodule "siptrace.so"
  276. modparam("siptrace", "duplicate_uri", "sip:127.0.0.1:9061")
  277. modparam("siptrace", "trace_to_database", 0)
  278. modparam("siptrace", "hep_mode_on", 1)
  279. modparam("siptrace", "hep_version", 3)
  280. modparam("siptrace", "trace_flag", 24)
  281. modparam("siptrace", "hep_capture_id", 234)
  282. modparam("siptrace", "trace_mode", 1)
  283.  
  284. #!ifdef WITH_DMQ
  285. loadmodule "dmq.so"
  286. loadmodule "dmq_usrloc.so"
  287. #!endif
  288. # must be loaded after dmq
  289. loadmodule "htable.so"
  290. loadmodule "dialog.so"
  291.  
  292. # -- for siremis CDRs --------------
  293. loadmodule "rtimer.so"
  294. loadmodule "sqlops.so"
  295.  
  296. #!ifdef WITH_AUTH
  297. loadmodule "auth.so"
  298. loadmodule "auth_db.so"
  299. #!ifdef WITH_IPAUTH
  300. loadmodule "permissions.so"
  301. #!endif
  302. #!ifdef WITH_UAC
  303. loadmodule "uac.so"
  304. #!endif
  305. #!endif
  306.  
  307. #!ifdef WITH_ALIASDB
  308. loadmodule "alias_db.so"
  309. #!endif
  310.  
  311. #!ifdef WITH_SPEEDDIAL
  312. loadmodule "speeddial.so"
  313. #!endif
  314.  
  315. #!ifdef WITH_MULTIDOMAIN
  316. loadmodule "domain.so"
  317. #!endif
  318.  
  319. #!ifdef WITH_PRESENCE
  320. loadmodule "presence.so"
  321. loadmodule "presence_xml.so"
  322. #!endif
  323.  
  324. #!ifdef WITH_NAT
  325. loadmodule "nathelper.so"
  326. loadmodule "rtpengine.so"
  327. #!endif
  328.  
  329. #!ifdef WITH_TLS
  330. loadmodule "tls.so"
  331. #!endif
  332.  
  333. #!ifdef WITH_ANTIFLOOD
  334. loadmodule "pike.so"
  335. #!endif
  336.  
  337. #!ifdef WITH_XMLRPC
  338. loadmodule "xmlrpc.so"
  339. #!endif
  340.  
  341. #!ifdef WITH_DEBUG
  342. loadmodule "debugger.so"
  343. #!endif
  344.  
  345. #!ifdef WITH_DROUTE
  346. loadmodule "drouting.so"
  347. #!endif
  348.  
  349. #!ifdef WITH_DBCLUSTER
  350. loadmodule "db_cluster"
  351. #!endif
  352.  
  353. #!ifdef WITH_DISPATCHER
  354. loadmodule "keepalive.so"
  355. loadmodule "dispatcher.so"
  356. #!endif
  357.  
  358. #!ifdef WITH_WEBSOCKETS
  359. loadmodule "websocket.so"
  360. #!endif
  361.  
  362. # ----------------- setting module-specific parameters ---------------
  363.  
  364. # ---- htable global params ----
  365. modparam("htable", "db_url", DBURL)
  366.  
  367. # ---- dispatcher params ----
  368. #!ifdef WITH_DISPATCHER
  369. modparam("dispatcher", "flags", 2)
  370. modparam("dispatcher", "db_url", DBURL)
  371. modparam("dispatcher", "table_name", "dispatcher")
  372. modparam("dispatcher", "ds_probing_mode", 1) # 1 means to probe each gateway
  373. modparam("dispatcher", "ds_ping_latency_stats", 1) # 1 means to provide latency stats
  374. modparam("dispatcher", "ds_ping_method", "OPTIONS")
  375. modparam("dispatcher", "ds_ping_interval", 10) # How often to ping destinations to check status
  376. modparam("dispatcher", "xavp_dst", "dispatcher_dst") # Will contain selected destination info
  377. modparam("dispatcher", "xavp_dst_mode", 0) # What attributes to set in the xavp
  378. modparam("dispatcher", "xavp_ctx", "dispatcher_ctx") # Will contain current dispatcher context info
  379. modparam("dispatcher", "xavp_ctx_mode", 0) # What attributes to set in the xavp
  380. #!endif
  381.  
  382. # ----- db_cluster params ----
  383. # connection: set for each db connection uri
  384. # cluster: s == serial, r == roundrobin, p == parallel (write/only)
  385. #!ifdef WITH_DBCLUSTER
  386. modparam("db_cluster", "connection", "c1=>mysql://kamailio:[email protected]/kamailio")
  387. modparam("db_cluster", "connection", "c2=>mysql://kamailio:[email protected]/kamailio")
  388. modparam("db_cluster", "connection", "c3=>mysql://kamailio:[email protected]/kamailio")
  389. modparam("db_cluster", "connection", "c4=>mysql://kamailio:[email protected]/kamailio")
  390. modparam("db_cluster", "cluster", "dbcluster=>c1=9r9r;c2=9r9r;c3=9r9r;c4=9r9r")
  391. modparam("db_cluster", "inactive_interval", 180)
  392. #!endif
  393.  
  394. # ----- jsonrpcs params -----
  395. modparam("jsonrpcs", "pretty_format", 1)
  396. modparam("jsonrpcs", "fifo_name", "/var/run/kamailio/kamailio_rpc.fifo")
  397. modparam("jsonrpcs", "transport", 3)
  398. #modparam#("jsonrpcs", "dgram_socket", "/var/run/kamailio/kamailio_rpc.sock")
  399.  
  400.  
  401. # ----- ctl params -----
  402. modparam("ctl", "binrpc", "unix:/var/run/kamailio/kamailio_ctl")
  403.  
  404.  
  405. # ----- tm params -----
  406. # auto-discard branches from previous serial forking leg
  407. modparam("tm", "failure_reply_mode", 3)
  408. # default retransmission timeout: 25sec
  409. modparam("tm", "fr_timer", 25000)
  410. # default invite retransmission timeout after 1xx: 120sec
  411. modparam("tm", "fr_inv_timer", 120000)
  412.  
  413.  
  414. # ----- rr params -----
  415. # set next param to 1 to add value to ;lr param (helps with some UAs)
  416. modparam("rr", "enable_full_lr", 0)
  417. # append from tag to the RR (no need for this script)
  418. modparam("rr", "append_fromtag", 0)
  419.  
  420.  
  421. # ----- registrar params -----
  422. modparam("registrar", "method_filtering", 1)
  423. /* uncomment the next line to disable parallel forking via location */
  424. # modparam("registrar", "append_branches", 0)
  425. /* uncomment the next line not to allow more than 10 contacts per AOR */
  426. #modparam("registrar", "max_contacts", 10)
  427. # max value for expires of registrations
  428. modparam("registrar", "max_expires", 3600)
  429. # set it to 1 to enable GRUU
  430. modparam("registrar", "gruu_enabled", 0)
  431.  
  432.  
  433. # ----- acc params -----
  434. # what special events should be accounted?
  435. modparam("acc", "early_media", 0)
  436. modparam("acc", "report_ack", 0)
  437. modparam("acc", "report_cancels", 0)
  438. # by default ww do not adjust the direction of the sequential requests
  439. # if you enable this parameter, be sure the enable "append_fromtag" in "rr" module
  440. modparam("acc", "detect_direction", 0)
  441. modparam("acc", "log_flag", FLT_ACC)
  442. modparam("acc", "log_missed_flag", FLT_ACCMISSED)
  443. modparam("acc", "log_extra",
  444. "src_user=$fU;src_domain=$fd;src_ip=$si;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;"
  445. "calltype=$avp(calltype);src_gwgroupid=$avp(src_gwgroupid);dst_gwgroupid=$avp(dst_gwgroupid)")
  446. modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)
  447. # enhanced DB accounting
  448. #!ifdef WITH_ACCDB
  449. modparam("acc", "db_flag", FLT_ACC)
  450. modparam("acc", "db_missed_flag", FLT_ACCMISSED)
  451. modparam("acc", "db_url", DBURL)
  452. modparam("acc", "db_extra",
  453. "src_user=$fU;src_domain=$fd;src_ip=$si;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;"
  454. "calltype=$avp(calltype);src_gwgroupid=$avp(src_gwgroupid);dst_gwgroupid=$avp(dst_gwgroupid)")
  455. #!endif
  456.  
  457.  
  458. # ----- usrloc params -----
  459. /* enable DB persistency for location entries */
  460. #!ifdef WITH_USRLOCDB
  461. modparam("usrloc", "db_url", DBURL)
  462. modparam("usrloc", "db_mode", 3)
  463. modparam("usrloc", "use_domain", MULTIDOMAIN)
  464. modparam("usrloc", "handle_lost_tcp", 1)
  465. #!endif
  466.  
  467.  
  468. # ----- auth_db params -----
  469. #!ifdef WITH_AUTH
  470. modparam("auth_db", "db_url", DBURL)
  471. modparam("auth_db", "calculate_ha1", yes)
  472. modparam("auth_db", "password_column", "password")
  473. # We use the rpid field of the subscriber table to track the assigned gwgroup (type of endpoint or carrier)
  474. modparam("auth_db", "load_credentials", "$avp(s:src_gwgroupid)=rpid;")
  475. modparam("auth_db", "use_domain", MULTIDOMAIN)
  476.  
  477. # ----- permissions params -----
  478. #!ifdef WITH_IPAUTH
  479. modparam("permissions", "db_url", DBURL)
  480. modparam("permissions", "db_mode", 1)
  481. #!endif
  482. #!endif
  483.  
  484.  
  485. # ----- alias_db params -----
  486. #!ifdef WITH_ALIASDB
  487. modparam("alias_db", "db_url", DBURL)
  488. modparam("alias_db", "use_domain", MULTIDOMAIN)
  489. #!endif
  490.  
  491.  
  492. # ----- speeddial params -----
  493. #!ifdef WITH_SPEEDDIAL
  494. modparam("speeddial", "db_url", DBURL)
  495. modparam("speeddial", "use_domain", MULTIDOMAIN)
  496. #!endif
  497.  
  498.  
  499. # ----- domain params -----
  500. #!ifdef WITH_MULTIDOMAIN
  501. modparam("domain", "db_url", DBURL)
  502. # register callback to match myself condition with domains list
  503. modparam("domain", "register_myself", 0)
  504. #!endif
  505.  
  506.  
  507. #!ifdef WITH_PRESENCE
  508. # ----- presence params -----
  509. modparam("presence", "db_url", DBURL)
  510.  
  511. # ----- presence_xml params -----
  512. modparam("presence_xml", "db_url", DBURL)
  513. modparam("presence_xml", "force_active", 1)
  514. #!endif
  515.  
  516.  
  517. #!ifdef WITH_NAT
  518. # ----- rtpengine params -----
  519. modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:7722")
  520.  
  521. # ----- nathelper params -----
  522. modparam("nathelper", "natping_interval", 30)
  523. modparam("nathelper", "ping_nated_only", 1)
  524. modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
  525. modparam("nathelper", "sipping_from", "sip:[email protected]")
  526.  
  527. # params needed for NAT traversal in other modules
  528. modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
  529. modparam("usrloc", "nat_bflag", FLB_NATB)
  530. #!endif
  531.  
  532.  
  533. #!ifdef WITH_TLS
  534. # ----- tls params -----
  535. modparam("tls", "config", "//etc/kamailio/tls.cfg")
  536. #!endif
  537.  
  538. #!ifdef WITH_ANTIFLOOD
  539. # ----- pike params -----
  540. modparam("pike", "sampling_time_unit", 2)
  541. modparam("pike", "reqs_density_per_unit", 16)
  542. modparam("pike", "remove_latency", 4)
  543.  
  544. # ----- htable params -----
  545. # ip ban htable with autoexpire after 5 minutes
  546. modparam("htable", "htable", "ipban=>size=8;autoexpire=300;dmqreplicate=1;")
  547. #!endif
  548.  
  549.  
  550. #!ifdef WITH_XMLRPC
  551. # ----- xmlrpc params -----
  552. modparam("xmlrpc", "route", "XMLRPC");
  553. modparam("xmlrpc", "url_match", "^/RPC")
  554. #!endif
  555.  
  556. #!ifdef WITH_DEBUG
  557. # ----- debugger params -----
  558. modparam("debugger", "cfgtrace", 1)
  559. modparam("debugger", "log_level_name", "exec")
  560. #!endif
  561.  
  562. #!ifdef WITH_UAC
  563. # ----- uac params -----
  564. modparam("uac", "restore_mode", "none")
  565. modparam("uac", "reg_db_url", DBURL)
  566. modparam("uac", "reg_db_table", "uacreg")
  567. modparam("uac", "reg_timer_interval", 60)
  568. modparam("uac", "reg_retry_interval", 120)
  569. modparam("uac", "reg_keep_callid", 1)
  570. modparam("uac", "reg_gc_interval", 30)
  571. modparam("uac", "credential", "username:domain:password")
  572. modparam("uac", "auth_realm_avp", "$avp(arealm)")
  573. modparam("uac", "auth_username_avp", "$avp(auser)")
  574. modparam("uac", "auth_password_avp", "$avp(apass)")
  575. modparam("uac", "reg_contact_addr", "EXTERNAL_IP_ADDR:5060")
  576. #!endif
  577.  
  578. #!ifdef WITH_DROUTE
  579. # ----- drouting params -----
  580. modparam("drouting", "db_url", DBURL)
  581. modparam("drouting", "ruri_avp", "$avp(dr_ruri)")
  582. # we are storing the gwid,gwtype in the attrs column, so the matched gwid and gwtype is available
  583. modparam("drouting", "attrs_avp", "$avp(dr_attrs)")
  584. # don't match on domain (per group) only use routing group
  585. modparam("drouting", "use_domain", 0)
  586. # do not resolve DNS names during load (will blindly try them)
  587. modparam("drouting", "force_dns", 0)
  588. # a gateway will be randomly selected (from each group delimeted by ';')
  589. modparam("drouting", "sort_order", 2)
  590. # htable for maintenance mode
  591. modparam("htable", "htable", "maintmode=>size=8;autoexpire=0;dmqreplicate=1;dbtable=dsip_maintmode;cols='ipaddr,gwid';")
  592. #modparam("drouting", "enable_keepalive", 1)
  593. #!endif
  594.  
  595. #!ifdef WITH_LCR
  596. # ----- htable params for from/to prefix lookup -----
  597. modparam("htable", "htable", "tofromprefix=>size=8;autoexpire=0;dmqreplicate=1;dbtable=dsip_lcr;cols='pattern,dr_groupid';")
  598. #!endif
  599.  
  600. # ----- rtimer params -----
  601. modparam("rtimer", "timer", "name=cdr;interval=300;mode=1;")
  602. modparam("rtimer", "exec", "timer=cdr;route=CDRS")
  603.  
  604. # ----- sqlops params -----
  605. # Kamailio Connection
  606. modparam("sqlops", "sqlcon", SQLCONN_KAM)
  607. # Asterisk Realtime Connection
  608. modparam("sqlops", "sqlcon", SQLCONN_AST)
  609.  
  610. # ----- dialog params -----
  611. modparam("dialog", "db_url", DBURL)
  612. modparam("dialog", "db_mode", 0)
  613. modparam("dialog", "enable_stats", 1)
  614. modparam("dialog", "dlg_flag", 1)
  615. modparam("dialog", "hash_size", 4096)
  616. modparam("dialog", "detect_spirals", 1)
  617. modparam("dialog", "track_cseq_updates", 1)
  618.  
  619. #!ifdef WITH_DMQ
  620. # ---- dmq params ----
  621. modparam("dmq", "server_address", "sip:INTERNAL_IP_ADDR:DMQ_PORT")
  622. modparam("dmq", "notification_address", "sip:local.cluster:DMQ_PORT")
  623. modparam("dmq", "multi_notify", 1)
  624. modparam("dmq", "num_workers", 4)
  625. modparam("dmq", "ping_interval", 15)
  626. modparam("dmq_usrloc", "enable", 1)
  627. # ---- dmq-related params ----
  628. modparam("dialog", "enable_dmq", 1)
  629. modparam("htable", "enable_dmq", 1)
  630. # only valid for kam ver >= 5.2
  631. modparam("htable", "dmq_init_sync", 1)
  632. #!endif
  633.  
  634. #!ifdef WITH_CALLLIMIT
  635. modparam("dialog", "profiles_with_value", "gwgroup")
  636. modparam("htable", "htable", "calllimit=>size=8;autoexpire=0;dmqreplicate=1;initval=-1;dbtable=dsip_calllimit;cols='gwgroupid,limit';")
  637. #!endif
  638.  
  639. # gw2gwroup is used to lookup gwgroupid
  640. modparam("htable", "htable", "gw2gwgroup=>size=8;autoexpire=0;dmqreplicate=1;dbtable=dsip_gw2gwgroup;cols='gwid,gwgroupid';")
  641. # inbound_hardfwd is used to lookup did and dr_groupid for forwarding calls unconditionally
  642. modparam("htable", "htable", "inbound_hardfwd=>size=8;autoexpire=0;dmqreplicate=1;dbtable=dsip_hardfwd;cols='dr_ruleid,did,dr_groupid';")
  643. # inbound_failfwd is used to lookup did and dr_groupid for forwarding calls on failover
  644. modparam("htable", "htable", "inbound_failfwd=>size=8;autoexpire=0;dmqreplicate=1;dbtable=dsip_failfwd;cols='dr_ruleid,did,dr_groupid';")
  645. # inbound_prefixmap is used to lookup dr_ruleid for a prefix
  646. modparam("htable", "htable", "inbound_prefixmap=>size=8;autoexpire=0;dmqreplicate=1;dbtable=dsip_prefix_mapping;cols='prefix,ruleid,priority';")
  647.  
  648. # ----- http_async_client params -----
  649. modparam("http_async_client", "workers", 1)
  650. modparam("http_async_client", "connection_timeout", 500)
  651. modparam("http_async_client", "hash_size", 2048)
  652. #!ifdef WITH_DEBUG
  653. modparam("http_async_client", "curl_verbose", 1)
  654. #!endif
  655. #!ifdef WITH_TLS
  656. modparam("http_async_client", "tls_client_cert", "/etc/kamailio/certs/client.pem")
  657. modparam("http_async_client", "tls_client_key", "/etc/kamailio/certs/client.key")
  658. modparam("http_async_client", "tls_ca_path", "/etc/kamailio/certs/ca/")
  659. #!endif
  660.  
  661.  
  662. ####### Routing Logic ########
  663.  
  664.  
  665. # Main SIP request routing logic
  666. # - processing of any incoming SIP request starts with this route
  667. # - note: this is the same as route { ... }
  668. request_route {
  669. # handle DMQ messages
  670. route(DMQ);
  671.  
  672. # per request initial checks
  673. route(REQINIT);
  674.  
  675. # NAT detection
  676. route(NATDETECT);
  677.  
  678. if (remove_hf("Allow")){
  679. append_hf("Allow: INVITE,ACK,OPTIONS,CANCEL,BYE,NOTIFY\r\n");
  680. }
  681.  
  682. # CANCEL processing
  683. route(HANDLE_CANCEL);
  684.  
  685. # handle requests within SIP dialogs
  686. route(WITHINDLG);
  687.  
  688. # handle retransmissions
  689. route(HANDLE_RETRANS);
  690.  
  691. # handle unregister requests
  692. route(UNREGISTER);
  693.  
  694. # authentication
  695. route(AUTH);
  696.  
  697. # handle presence related requests
  698. route(PRESENCE);
  699.  
  700. # handle registrations
  701. route(REGISTRAR);
  702.  
  703. # dispatch to local endpoints that registered thru the proxy
  704. route(LOCATION);
  705.  
  706. # Reformat US Based RURI's into a canonical format of 10 digits
  707. #route(REFORMATRURI);
  708.  
  709. # route the call to the next hop
  710. route(NEXTHOP);
  711. }
  712.  
  713. route[HANDLE_CANCEL] {
  714. if (is_method("CANCEL")) {
  715. if (t_check_trans()) {
  716. route(RELAY);
  717. }
  718. exit;
  719. }
  720. }
  721.  
  722. route[HANDLE_RETRANS] {
  723. if (t_precheck_trans()) {
  724. t_check_trans();
  725. exit;
  726. }
  727. t_check_trans();
  728. }
  729.  
  730. route[DMQ] {
  731. #!ifdef WITH_DMQ
  732. if ($rm == "KDMQ" && $rp == DMQ_PORT) {
  733. dmq_handle_message();
  734. exit;
  735. }
  736. #!else
  737. return;
  738. #!endif
  739. }
  740.  
  741. route[REFORMATRURI] {
  742. xlog("L_DBG", "[REFORMATRURI] <$ci> original rU <$rU> and original tU <$tU>\n");
  743.  
  744. # This is to deal with those who are used to dialing 7 digits
  745. # assuming that the 7 digit number being dialed is in the same area code as the FROM number
  746. if ($(rU{s.len}) == 7) {
  747. if ($(fU{s.len}) == 10) {
  748. $rU = $(fU{s.substr,0,3}) + $rU;
  749. }
  750. else {
  751. $rU = $(fU{s.substr,0,4}) + $rU;
  752. }
  753. $tU = $rU;
  754. }
  755. else if ($(rU{s.len}) > 10) {
  756. # Check for +1 and remove it from the RURI and the To header
  757. if ($(rU{s.substr,0,2}) == "+1") {
  758. $rU = $(rU{s.substr,2,0});
  759. $tU = $rU;
  760. }
  761. # Check for 1 and remove it from the RURI and the To header
  762. else if ($(rU{s.substr,0,1}) == "1") {
  763. $rU = $(rU{s.substr,1,0});
  764. $tU = $rU;
  765. }
  766. }
  767.  
  768. xlog("L_DBG", "[REFORMATRURI] <$ci> modified rU <$rU> and modified tU <$tU>\n");
  769. }
  770.  
  771. route[ENRICH_SIPHEADER] {
  772. if (!strempty($xavp(ra=>sipdomain))) {
  773. append_hf("X-SIPDOMAIN: $xavp(ra=>sipdomain)\r\n");
  774. }
  775. }
  776.  
  777. # Route the call to the next hop, which can be a PBX or Carrier
  778. route[NEXTHOP] {
  779.  
  780.  
  781. ######################################
  782. # Endpoint to PBX via Domain Routing #
  783. ######################################
  784.  
  785. # Route to a single PBX with PASS THRU AUTH (aka Acting as a Location Server only)
  786. if (isflagset(FLT_DOMAINROUTING) && !isflagset(FLT_EXTERNAL_AUTH)) {
  787. #Grab the value of the avp that contains the domain_pbx_ip.
  788. #This is where requests for that domain should be routed
  789.  
  790. $rd = $(avp(domain_pbx_ip){s.select,0,:});
  791. $rp = $(avp(domain_pbx_ip){s.select,1,:});
  792.  
  793. xlog("L_INFO", "[NEXTHOP-DOMAINROUTING] <$ci> should be routed to $rd:$rp\n");
  794.  
  795. #We are going to pass this request on to the backend server
  796. record_route();
  797.  
  798. #Fix NAT'd contact so that calls are routed back correctly when a BYE occurs
  799. #fix_nated_contact();
  800. #subst_hf("Contact", "/@.*;/@$si:$sp;/", "f");
  801.  
  802. route(RELAY);
  803. exit;
  804. }
  805.  
  806. #Route to one PBX using an algorithm with External Authentication
  807. #(aka We are acting as a Registration and Location Server)
  808. else if (isflagset(FLT_DOMAINROUTING) && isflagset(FLT_EXTERNAL_AUTH) && !is_method("REGISTER")) {
  809. xlog("L_INFO", "[NEXTHOP-DOMAINROUTING] <$ci> Routing for $fd via dispatcher set $avp(domain_dispatcher_set_id)\n");
  810. if (!strempty($avp(domain_dispatcher_set_id))) {
  811. #Set the algoritm to load balancing if not set
  812. if (strempty($avp(domain_dispatcher_alg))) {
  813. $avp(domain_dispatcher_alg)=4;
  814. }
  815.  
  816. record_route();
  817.  
  818. route(ENRICH_SIPHEADER);
  819. route(DISPATCHER_SELECT);
  820. route(RELAY);
  821. }
  822. exit;
  823. }
  824.  
  825. #!ifdef WITH_DROUTE
  826.  
  827. # Enrich inbound calls from carriers
  828.  
  829. route(ENRICH_CARRIER_INBOUND);
  830.  
  831. # Check if this is coming from carrier
  832. if (allow_source_address(FLT_CARRIER)) {
  833.  
  834. # DEBUG:
  835. xlog("L_INFO", "[NEXTHOP] <$ci> The call coming from $si is from a carrier\n");
  836.  
  837. # Route to PBX
  838. xlog("L_DBG", "[NEXTHOP-DROUTING] <$ci> Logic for routing to PBX\n");
  839. append_hf("P-hint: inbound\r\n");
  840. $avp(calltype) = "inbound";
  841.  
  842. # don't overwrite fwding info if we already set it
  843. if (!isflagset(FLT_FAILOVER)) {
  844. route(SET_CALLFWD_INFO);
  845. }
  846.  
  847. # don't overwrite dr_groupid if this is n'th time in this route
  848. if ($avp(dr_groupid) == $null) {
  849. # check for hard fwd, then set did and dr_groupid accordingly
  850. if ($avp(hardfwdinfo) != $null) {
  851. # allow DID to be unchanged
  852. if (!strempty($(avp(hardfwdinfo){s.select,0,,}))) {
  853. $rU = $(avp(hardfwdinfo){s.select,0,,});
  854. }
  855. $avp(dr_groupid) = $(avp(hardfwdinfo){s.select,1,,}{s.int});
  856. }
  857. # otherwise we are using inbound mapping rules
  858. else {
  859. $avp(dr_groupid) = FLT_INBOUND;
  860. }
  861. }
  862.  
  863. # route based on rules in dr_rules table
  864. if (do_routing($avp(dr_groupid))) {
  865.  
  866. # Check if routing to MSTeams
  867. if ($avp(dr_attrs) != $null) {
  868. $avp(dst_msteams_domain) = $(avp(dr_attrs){s.select,2,,});
  869. if ($(avp(dst_msteams_domain){s.len}) > 0) {
  870. record_route_preset("$avp(dst_msteams_domain):5061;transport=tls", "EXTERNAL_IP_ADDR:SIP_PORT");
  871. setbflag(FLB_DST_MSTEAMS);
  872. }
  873. }
  874. route(MAINTMODE_CHECK);
  875.  
  876. #!ifdef WITH_SERVERNAT
  877. # Create a Record Route based on the destination network
  878. $var(local_subnet) = "INTERNAL_IP_NET";
  879. # Replace the dots with \.
  880. $var(local_subnet) = $(var(local_subnet){s.replace,.,\.});
  881. # Repace the 0 with .*
  882. $var(local_subnet) = $(var(local_subnet){s.replace,*,.*});
  883.  
  884. if ($rd=~$var(local_subnet)) {
  885. record_route_advertised_address("INTERNAL_IP_ADDR");
  886. }
  887. else {
  888. record_route();
  889. }
  890. #!else
  891. record_route();
  892. #!endif
  893. # Set INVITE max lifetime to ensure Primary and Secondary PBX server feature works.
  894. $var(pbx_invite_timeout) = (int)$sel(cfg_get.server.pbx_invite_timeout);
  895. t_set_max_lifetime($var(pbx_invite_timeout), 0);
  896.  
  897. route(RELAY);
  898. exit;
  899. }
  900. # No rules defined for the phone number
  901. else {
  902. xlog("L_WARN", "[NEXTHOP] <$ci> No rules defined for $rU coming from this carrier endpoint: $si\n");
  903. sl_reply("500", "No rules defined for number");
  904. }
  905. }
  906.  
  907. else if (allow_source_address(FLT_PBX) || isflagset(FLT_PBX_AUTH) || allow_source_address(FLT_MSTEAMS)) {
  908.  
  909. # DEBUG:
  910. xlog("L_INFO", "[NEXTHOP] <$ci> The call coming from $si is from a pbx\n");
  911.  
  912. if (allow_source_address(FLT_MSTEAMS))
  913. setbflag(FLB_SRC_MSTEAMS);
  914.  
  915. # Route to Carrier
  916. xlog("L_DBG", "[NEXTHOP-DROUTING] <$ci> Logic for routing to Carriers\n");
  917. append_hf("P-hint: outbound\r\n");
  918. $avp(calltype) = "outbound";
  919.  
  920. #!ifdef WITH_LCR
  921. # LCR Routing
  922. # - route based on from prefix and to prefix
  923. # - match selection is similar to dRouting module from longest to shortest match
  924. # Logic Summary:
  925. # 1. iterate through htable matching entries starting with prefixes
  926. # 2. find diff between match and lookup (must be absolute value)
  927. # 3. if diff is less than previous overwrite match
  928. # 4. if a match is present attempt to set carrier group and relay
  929. # TODO:
  930. # we could store and iterate through all matches if we use dispatcher instead
  931. # this would allow failover in LCR Routing to shorter prefixes (if we wanted that)
  932. $var(lookup) = $(fU{s.unescape.user}) + "-" + $(tU{s.unescape.user});
  933. $avp(lcr_match_group) = $null;
  934. $var(lcr_match_diff) = 1000;
  935. $var(diff) = 1000;
  936.  
  937. sht_iterator_start("iter", "tofromprefix");
  938. while(sht_iterator_next("iter")) {
  939. $var(regex) = $(shtitkey(iter){s.select,0,-}{re.subst,/(\+|\*|\#)/\\\1/g}) + "([0-9])*-" +
  940. $(shtitkey(iter){s.select,-1,-}{re.subst,/(\+|\*|\#)/\\\1/g}) + "([0-9])*";
  941. if ($var(lookup) =~ $var(regex)) {
  942. xlog("L_DBG", "[NEXTHOP-LCR] <$ci> LCR match on $shtitkey(iter)\n");
  943. $var(diff) = $(var(lookup){s.len}) - $(shtitkey(iter){s.len});
  944. # bitwise absolute value: ( mask = n>>31; (mask^n) - mask )
  945. # we are assuming 32 bit integers
  946. $var(mask) = $var(diff) >> 31;
  947. $var(diff) = ($var(mask) ^ $var(diff)) - $var(mask);
  948. if ($var(diff) < $var(lcr_match_diff)) {
  949. xlog("L_DBG", "[NEXTHOP-LCR] <$ci> LCR prefix closer match diff=$var(diff)\n");
  950. $avp(lcr_match_group) = $shtitval(iter);
  951. $var(lcr_match_diff) = $var(diff);
  952. }
  953. }
  954. }
  955. sht_iterator_end("iter");
  956.  
  957.  
  958. if ($avp(lcr_match_group) > 0) {
  959. $avp(carrier_groupid) = $avp(lcr_match_group);
  960. }
  961. else {
  962. $avp(carrier_groupid) = FLT_OUTBOUND;
  963. }
  964.  
  965. #!else
  966. $avp(carrier_groupid) = FLT_OUTBOUND;
  967. #!endif
  968.  
  969. if (do_routing($avp(carrier_groupid))) {
  970.  
  971.  
  972. $avp(dst_gwid) = $(avp(dr_attrs){s.select,0,,});
  973. $avp(dst_gwtype) = $(avp(dr_attrs){s.select,1,,});
  974. $avp(dst_gwgroupid) = $sht(gw2gwgroup=>$avp(dst_gwid));
  975.  
  976. $var(original_rU) = $rU;
  977. # Checking if the carrier is using username/password auth
  978. if (uac_reg_request_to($avp(dst_gwgroupid), 0)) {
  979. xlog("L_INFO", "Found remote user [$fU]. username: $avp(auser)");
  980. }
  981.  
  982. $rU = $var(original_rU);
  983.  
  984. route(ENRICH_CARRIER_OUTBOUND);
  985. record_route();
  986. route(RELAY);
  987. exit;
  988. }
  989. # No rules defined for the phone number
  990. else {
  991. xlog("L_WARN", "[NEXTHOP] <$ci> No rules defined for $fu going to $tu\n");
  992. sl_reply("500", "No rules defined for number");
  993. }
  994. }
  995. else {
  996. sl_send_reply("407", "Proxy Authentication Required. Add the PBX or Carrier IP using GUI");
  997. }
  998.  
  999. #!endif
  1000. }
  1001.  
  1002.  
  1003. # MaintMode Check - recursive function for checking if a number is in maintmode
  1004. route[MAINTMODE_CHECK] {
  1005. xlog("L_DBG", "[MAINTMODE_CHECK] <$ci> The request domain $rd before maintmode check\n");
  1006.  
  1007. if ($sht(maintmode=>$rd)!=$null) {
  1008.  
  1009. xlog("L_DBG", "[MAINTMODE_CHECK] <$ci> $rd is in maintenance mode\n");
  1010. # The selected endpoint is in maintenance mode, try next endpoint
  1011. # If there is only one endpoint then immmediately return Service not Available
  1012. # Otherwise, select the next gateway and see if it is in maintenance mode
  1013. if (!use_next_gw()) {
  1014. xlog("L_DBG", "[MAINTMODE_CHECK] <$ci> $rd no other gateway\n");
  1015. sl_send_reply("503", "Service not available");
  1016. exit;
  1017. }
  1018. else {
  1019. route(MAINTMODE_CHECK);
  1020. }
  1021. }
  1022. }
  1023.  
  1024. # TeleBlock routing
  1025. route[TELEBLOCK] {
  1026. # Only route if is PBX
  1027. if (!allow_source_address(FLT_PBX)) {
  1028. xlog("L_WARN", "[TELEBLOCK] <$ci> $si not in allowed addresses\n");
  1029. return;
  1030. }
  1031.  
  1032. # TODO: This should be dynamic
  1033. # Only route to teleblock if User-to-User header is present
  1034. # if (!is_present_hf("User-to-User")) {
  1035. # xlog("L_DBG", "[TELEBLOCK] <$ci> User-to-User header not found\n");
  1036. # return;
  1037. # }
  1038.  
  1039. # Change source address to this proxy server
  1040. $fu = "sip:" + $fU + "@" + $Ri + ":" + $Rp;
  1041.  
  1042. # Send Invite to TeleBlock with header fields:
  1043. # Number == To Username
  1044. # CPN == From Username
  1045. # BTN == Billing Number (optional)
  1046. # Zipcode == US Postal Code (optional)
  1047. # refkey == Record ID (optional)
  1048.  
  1049. $ru = "sip:" + $rU + "@" + $sel(cfg_get.teleblock.gw_ip) + ":" + $sel(cfg_get.teleblock.gw_port);
  1050.  
  1051. xlog("L_DBG", "[TELEBLOCK] <$ci> From Username: $fU\n");
  1052. xlog("L_DBG", "[TELEBLOCK] <$ci> To Username: $tU\n");
  1053. xlog("L_DBG", "[TELEBLOCK] <$ci> Request URI: $ru\n");
  1054.  
  1055. # set failure route
  1056. if (is_method("INVITE")) {
  1057. t_on_failure("TELEBLOCK_FAILURE");
  1058. }
  1059. }
  1060.  
  1061.  
  1062. failure_route[TELEBLOCK_FAILURE] {
  1063. if (t_is_canceled()) {
  1064. exit;
  1065. }
  1066.  
  1067. xlog("L_DBG", "[TELEBLOCK_FAILURE] <$ci> Processing reply for: $rU\n");
  1068.  
  1069.  
  1070. # Check if a media server is setup for teleblock
  1071. if (strempty($sel(cfg_get.teleblock.media_ip)) || strempty($sel(cfg_get.teleblock.media_port))){
  1072. $avp(s:teleblock_media_enabled) = "0";
  1073. }
  1074. else {
  1075. $avp(s:teleblock_media_enabled) = "1";
  1076. }
  1077.  
  1078. # interpret teleblock response
  1079. if (t_check_status("499")) {
  1080. $rU = $tU;
  1081. if (do_routing(FLT_OUTBOUND)) {
  1082. record_route();
  1083. t_relay();
  1084. }
  1085. }
  1086. else {
  1087. xlog("L_DBG", "[TELEBLOCK_FAILURE] <$ci> Relaying to: $sel(cfg_get.teleblock.media_ip):$sel(cfg_get.teleblock.media_port)\n");
  1088.  
  1089. if (t_check_status("403|433")) {
  1090. if ($avp(s:teleblock_media_enabled) == "1") {
  1091. # make sure media server can route back to kamailio
  1092. record_route();
  1093. $ru = "sip:" + $rU + "@" + $sel(cfg_get.teleblock.media_ip) + ":" + $sel(cfg_get.teleblock.media_port);
  1094. if (!t_relay()) {
  1095. t_reply("403", "Do-Not-Contact");
  1096. }
  1097. }
  1098. else {
  1099. if (!t_relay()) {
  1100. t_reply("403", "Do-Not-Contact");
  1101. }
  1102. }
  1103. }
  1104. else {
  1105. if ($avp(s:teleblock_media_enabled) == "1") {
  1106. # make sure media server can route back to kamailio
  1107. record_route();
  1108. $ru = "sip:" + $rU + "@" + $sel(cfg_get.teleblock.media_ip) + ":" + $sel(cfg_get.teleblock.media_port);
  1109. if (!t_relay()) {
  1110. t_reply("500", "Connection Failure");
  1111. }
  1112. }
  1113. }
  1114. }
  1115. exit;
  1116. }
  1117.  
  1118.  
  1119. # Wrapper for relaying requests
  1120. route[RELAY] {
  1121. # Enable the RTPEngine if required
  1122. route(IS_RTPE_REQUIRED);
  1123.  
  1124. # Check TeleBlock Blacklist
  1125. #!ifdef WITH_TELEBLOCK
  1126.  
  1127. # Check if Teleblock is enabled
  1128. if ($sel(cfg_get.teleblock.gw_enabled) == 1)
  1129. route(TELEBLOCK);
  1130. #!endif
  1131. # enable additional event routes for forwarded requests
  1132. # - serial forking, RTP relaying handling, a.s.o.
  1133. if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
  1134. if (!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
  1135. }
  1136. if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
  1137. if((sdp_get_line_startswith("$avp(active)", "a=inactive")) && !t_is_set("onreply_route")) {
  1138. xlog("inactive-line: $avp(active)\n");
  1139. t_on_reply("MANAGE_INACTIVE_SDP");
  1140. }
  1141. else if !t_is_set("onreply_route"){
  1142. t_on_reply("MANAGE_REPLY");
  1143. }
  1144. }
  1145. if (is_method("INVITE")) {
  1146. if (!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
  1147. }
  1148.  
  1149. #!ifdef WITH_CALLLIMIT
  1150. # Manage call limits for gwgroups
  1151.  
  1152. # check if dst gwgroup could be an endpoint and set values for call limit checking
  1153. # TODO: we only support checking dst gwgroup if drouting was used
  1154. # we need to support other routing methods such as domain routing, dispatcher routing, etc..
  1155. if ($avp(dr_attrs) != $null) {
  1156. $avp(dst_gwid) = $(avp(dr_attrs){s.select,0,,});
  1157. $avp(dst_gwtype) = $(avp(dr_attrs){s.select,1,,});
  1158. $avp(dst_gwgroupid) = $sht(gw2gwgroup=>$avp(dst_gwid));
  1159. }
  1160. xlog("L_DBG", "[RELAY-CALLLIMIT] dst_gwtype: $avp(dst_gwtype), dst_gwid: $avp(dst_gwid), dst_gwgroupid: $avp(dst_gwgroupid) src_gwtype: $avp(src_gwtype), src_gwid: $avp(src_gwid), src_gwgroupid: $avp(src_gwgroupid)\n");
  1161.  
  1162. # if src and dst gwgroup is the same only increment one call
  1163. if (($avp(src_gwtype) == FLT_PBX) && ($avp(dst_gwtype) == FLT_PBX) && ($avp(src_gwgroupid) == $avp(dst_gwgroupid))) {
  1164. $avp(gwgroups_equivalent) = 1;
  1165. }
  1166. else {
  1167. $avp(gwgroups_equivalent) = 0;
  1168. }
  1169.  
  1170. if (($avp(src_gwtype) == FLT_PBX) || ($avp(gwgroups_equivalent) == 1)) {
  1171. $var(limit) = $sht(calllimit=>$avp(src_gwgroupid));
  1172. xlog("L_INFO", "[RELAY-CALLLIMIT] <$ci> Call limit for src endpoint group $avp(src_gwgroupid) is $var(limit)\n");
  1173. if ($var(limit) != -1 && get_profile_size("gwgroup","$avp(src_gwgroupid)","$avp(size)")) {
  1174. if ($avp(size) < $var(limit)) {
  1175. set_dlg_profile("gwgroup","$avp(src_gwgroupid)");
  1176. dlg_manage();
  1177. }
  1178. else {
  1179. sl_reply("480","Over call limit");
  1180. $avp(notification_type) = NOTIFICATION_OVERLIMIT;
  1181. $avp(notification_gwid) = $avp(src_gwid);
  1182. $avp(notification_gwgroupid) = $avp(src_gwgroupid);
  1183. route(SEND_NOTIFICATION);
  1184. exit;
  1185. }
  1186. }
  1187. }
  1188. if (($avp(dst_gwtype) == FLT_PBX) && ($avp(gwgroups_equivalent) == 0)) {
  1189. $var(limit) = $sht(calllimit=>$avp(dst_gwgroupid));
  1190. xlog("L_INFO", "[RELAY-CALLLIMIT] <$ci> Call limit for dst endpoint group $avp(dst_gwgroupid) is $var(limit)\n");
  1191. if ($var(limit) != -1 && get_profile_size("gwgroup","$avp(dst_gwgroupid)","$avp(size)")) {
  1192. if ($avp(size) < $var(limit)) {
  1193. set_dlg_profile("gwgroup","$avp(dst_gwgroupid)");
  1194. dlg_manage();
  1195. }
  1196. else {
  1197. sl_reply("480","Over call limit");
  1198. $avp(notification_type) = NOTIFICATION_OVERLIMIT;
  1199. $avp(notification_gwid) = $avp(dst_gwid);
  1200. $avp(notification_gwgroupid) = $avp(dst_gwgroupid);
  1201. route(SEND_NOTIFICATION);
  1202. exit;
  1203. }
  1204. }
  1205. }
  1206. #!endif
  1207.  
  1208. # do accounting only for INVITE's
  1209. if (is_method("INVITE")) {
  1210. setflag(FLT_ACC);
  1211. }
  1212.  
  1213. xlog("L_INFO","[RELAY] <$ci> Attempting to route call to $ru\n");
  1214. if (!t_relay()) {
  1215. sl_reply_error();
  1216. }
  1217. exit;
  1218. }
  1219.  
  1220. # Per SIP request initial checks
  1221. route[REQINIT] {
  1222. # Enable tracing for SNGREP
  1223. sip_trace();
  1224. setflag(24);
  1225.  
  1226. #!ifdef WITH_ANTIFLOOD
  1227. # flood dection from same IP and traffic ban for a while
  1228. # be sure you exclude checking trusted peers, such as pstn gateways
  1229. # - local host excluded (e.g., loop to self)
  1230. if ((src_ip != myself) && !allow_source_address_group()) {
  1231. if ($sht(ipban=>$si) != $null) {
  1232. # ip is already blocked
  1233. xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");
  1234. exit;
  1235. }
  1236. if (!pike_check_req()) {
  1237. xlog("L_ALERT", "[REQINIT] <$ci> pike blocking $rm from $fu (IP:$si:$sp)\n");
  1238. $sht(ipban=>$si) = 1;
  1239. exit;
  1240. }
  1241. }
  1242. if ($ua =~ "friendly-scanner") {
  1243. sl_send_reply("200", "OK");
  1244. exit;
  1245. }
  1246. #!endif
  1247.  
  1248. if (!mf_process_maxfwd_header("10")) {
  1249. sl_send_reply("483","Too Many Hops");
  1250. exit;
  1251. }
  1252.  
  1253. # Only reply to option messages if the endpoint or the carrier is defined
  1254. if (is_method("OPTIONS") && allow_source_address_group()) {
  1255. sl_send_reply("200","Keepalive");
  1256. exit;
  1257. }
  1258.  
  1259. if (!sanity_check("1511", "7")) {
  1260. xlog("L_WARN", "[REQINIT] <$ci> Malformed SIP message from $si:$sp\n");
  1261. exit;
  1262. }
  1263.  
  1264. # request with no Username in RURI
  1265. if ($rU == $null) && is_method("INVITE") {
  1266. sl_send_reply("484","Address Incomplete");
  1267. exit;
  1268. }
  1269.  
  1270. # Check the type of UAC
  1271. if ($pr == "ws" || $pr == "wss"){
  1272. setflag(FLT_SRC_WS);
  1273. }
  1274. else {
  1275. setflag(FLT_SRC_SIP);
  1276. }
  1277. }
  1278.  
  1279. # Handle requests within SIP dialogs
  1280. route[WITHINDLG] {
  1281. if (!has_totag()) return;
  1282.  
  1283. # sequential request withing a dialog should
  1284. # take the path determined by record-routing
  1285. if (loose_route()) {
  1286. route(DLGURI);
  1287.  
  1288.  
  1289. if (is_method("REFER|SUBSCRIBE")) {
  1290. # record routing for dialog-forming requests
  1291. # INVITE | REFER | SUBSCRIBE --> RFC 4538, Section 1
  1292. # and remove preloaded route headers
  1293. remove_hf("Route");
  1294. record_route();
  1295. }
  1296. #else
  1297. if (is_method("BYE")) {
  1298. # do accounting even if the transaction fails
  1299. # we grab the gwgroup info from the initiating INVITE's record
  1300. sql_xquery("kam", "select src_gwgroupid, dst_gwgroupid from acc where callid = '$ci' and method = 'INVITE' limit 1", "rb");
  1301. if (!strempty($xavp(rb=>src_gwgroupid))) {
  1302. $avp(src_gwgroupid) = $xavp(rb=>src_gwgroupid);
  1303. $avp(dst_gwgroupid) = $xavp(rb=>dst_gwgroupid);
  1304. }
  1305. sql_result_free("rb");
  1306.  
  1307. setflag(FLT_ACC);
  1308. setflag(FLT_ACCFAILED);
  1309. }
  1310. else if (is_method("ACK")) {
  1311. # ACK is forwarded statelessy
  1312. xlog("L_DBG", "[WITHINDLG] <$ci> Method is: ACK|UPDATE\n");
  1313. route(NATMANAGE);
  1314. }
  1315. else if (is_method("NOTIFY")) {
  1316. # Add Record-Route for in-dialog NOTIFY as per RFC 6665.
  1317. record_route();
  1318. }
  1319.  
  1320. route(RELAY);
  1321. exit;
  1322. }
  1323.  
  1324. if (is_method("SUBSCRIBE") && uri == myself) {
  1325. # in-dialog subscribe requests
  1326. route(PRESENCE);
  1327. exit;
  1328. }
  1329.  
  1330. if ( is_method("ACK|UPDATE|INVITE|BYE") ) {
  1331. #!ifdef WITH_NAT
  1332. if ( is_method("BYE|INVITE") ) {
  1333. handle_ruri_alias();
  1334. }
  1335. #!endif
  1336. if ( t_check_trans() ) {
  1337. # no loose-route, but stateful ACK;
  1338. # must be an ACK after a 487
  1339. # or e.g. 404 from upstream server
  1340. route(RELAY);
  1341. exit;
  1342. }
  1343. else {
  1344. # ACK without matching transaction. Try to route anyway - being optimistic
  1345. # since it has at least a To Tag
  1346. route(RELAY);
  1347. exit;
  1348. }
  1349. }
  1350.  
  1351. sl_send_reply("404","Not here");
  1352. exit;
  1353. }
  1354.  
  1355. # Handle SIP registrations
  1356. route[REGISTRAR] {
  1357. if (!is_method("REGISTER"))
  1358. return;
  1359.  
  1360. # Set the device type if a WS device
  1361. if (isflagset(FLT_SRC_WS))
  1362. setbflag(FLB_WS_DEVICE);
  1363.  
  1364. if (isflagset(FLT_NATS)) {
  1365. setbflag(FLB_NATB);
  1366. #!ifdef WITH_NATSIPPING
  1367. # do SIP NAT pinging
  1368. setbflag(FLB_NATSIPPING);
  1369. #!endif
  1370. }
  1371.  
  1372. if (isflagset(FLT_PBX_AUTH)) {
  1373. # Handle Register Event - We are now acting as a REGISTRAR.
  1374. if (!save("location"))
  1375. sl_reply_error();
  1376.  
  1377. xlog("L_DBG","[REGISTRAR] <$ci> update the gwgroup $avp(src_gwgroupid) to use the register ip:port:transport of $su\n");
  1378. # Remove the sip: from the front of the $su
  1379. $var(su) = $(su{s.substr,4,0});
  1380. sql_query("kam","select gwid from dr_gateways where address='$var(su)' and description like '%gwgroup:$avp(src_gwgroupid)%'","rb");
  1381. if ($dbr(rb=>rows) == 0) {
  1382. sql_query("kam","insert into dr_gateways values (null,9,'$var(su)',0,'','','name:autoregister,gwgroup:$avp(src_gwgroupid)')");
  1383. sql_query("kam","update dr_gw_lists set gwlist=concat(LAST_INSERT_ID(),',',gwlist) where id=$avp(src_gwgroupid)");
  1384. }
  1385.  
  1386. jsonrpc_exec('{"jsonrpc": "2.0", "method": "drouting.reload", "id": 1}');
  1387. sql_result_free("rb");
  1388. exit;
  1389. }
  1390.  
  1391. if (isflagset(FLT_DOMAINROUTING) && !isflagset(FLT_EXTERNAL_AUTH)) {
  1392. # Save the location, but DON'T send a 200 reply back.
  1393. # Let the upstream PBX authenticate the UAC (aka endpont)
  1394.  
  1395. if (!save("location", "0x02"))
  1396. sl_reply_error();
  1397.  
  1398. #Grab the value of the avp that contains the domain_pbx_ip.
  1399. #This is where requests for that domain should be routed
  1400.  
  1401. $var(rd) = $(avp(domain_pbx_ip){s.select,0,:});
  1402. $var(rp) = $(avp(domain_pbx_ip){s.select,1,:});
  1403.  
  1404. $rd = $var(rd);
  1405. $rp = $var(rp);
  1406.  
  1407. #Rewrite Contact based on the domain being routed to
  1408. #sips:[email protected];rtcweb-breaker=no;transport=wss
  1409. if ( subst_hf("Contact", "/(.*)?<(sips?):([0-9]+)@(.*)/<\2:\3@$fd>/", "f") ) {
  1410. xlog("L_INFO", "[REGISTRAR] <$ci> changed contact to match From domain\n");
  1411. msg_apply_changes();
  1412. };
  1413.  
  1414. if (isbflagset(FLB_WS_DEVICE)) {
  1415. add_path();
  1416. }
  1417. else {
  1418. #Add the Path header for SIP UAC's - so that we know how to route back
  1419. add_path_received($fU);
  1420. }
  1421.  
  1422. #We are going to pass this request on to the backend server
  1423. route(RELAY);
  1424. exit;
  1425. }
  1426. else if (isflagset(FLT_DOMAINROUTING) && isflagset(FLT_EXTERNAL_AUTH)) {
  1427. if (!save("location")) {
  1428. sl_reply_error();
  1429. }
  1430. exit;
  1431. }
  1432. # #Forward the registration onto one of the servers in the cluster
  1433. # if (!strempty($avp(domain_dispatcher_set_id))) {
  1434. # if (!strempty($avp(domain_dispatcher_reg_alg))) {
  1435. # #Set the registration algoritm
  1436. # $avp(domain_dispatcher_alg)=$avp(domain_dispatcher_reg_alg);
  1437. # }
  1438. # else {
  1439. # #Set the dispatcher algorthim to round robin by default
  1440. # $avp(domain_dispatcher_alg)=4;
  1441. # }
  1442. #
  1443. # route(DISPATCHER_SELECT);
  1444. # route(RELAY);
  1445. # }
  1446. # exit;
  1447. #}
  1448. }
  1449.  
  1450.  
  1451.  
  1452. route[UNREGISTER] {
  1453. if (!is_method("REGISTER")) return;
  1454.  
  1455. # Check if this is a Register Expire request
  1456. if ($sel(contact.expires) == "0" ) {
  1457. route(REGISTRAR);
  1458. }
  1459. }
  1460.  
  1461. #route[UNREGISTER] {
  1462. # if (!is_method("REGISTER")) return;
  1463. #
  1464. # # Check if this is a Register Expire request
  1465. # if ($sel(contact.expires) == "0" ) {
  1466. #
  1467. # unregister("location","$tu");
  1468. # xlog("L_DBG", "[UNREGISTER] <$ci> Unregistering $su\n");
  1469. #
  1470. # # Remove from dr_routing module
  1471. # $var(su) = $(su{s.substr,4,0});
  1472. #
  1473. # if (sql_xquery("kam","select gwid from dr_gateways where address='$var(su)'","ra") == 1) {
  1474. # xlog("L_DBG","[UNREGISTER] <$ci> num of rows: $sqlrows(kam)\n");
  1475. #
  1476. # while($xavp(ra) != $null) {
  1477. # # Get the Gateway Group ID
  1478. # if (sql_xquery("kam","select id from dr_gw_lists where gwlist like '%$xavp(ra=>gwid)%'","rb") == 1) {
  1479. # while($xavp(rb) != $null) {
  1480. # xlog("L_DBG","[UNREGISTER] <$ci> gwgroupid: $xavp(rb=>id)\n");
  1481. # # Remove gwid with from gwlist in dr_gw_lists
  1482. # sql_query("kam","update dr_gw_lists set gwlist=TRIM(LEADING ',' FROM REGEXP_REPLACE(gwlist, '([,\s])?$xavp(ra=>gwid)', '')) where id=$xavp(rb=>id)");
  1483. # # Delete the gateway
  1484. # sql_query("kam","delete from dr_gateways where address='$var(su)'");
  1485. # pv_unset("$xavp(rb)");
  1486. # }
  1487. # }
  1488. # pv_unset("$xavp(ra)");
  1489. # }
  1490. # jsonrpc_exec('{"jsonrpc": "2.0", "method": "drouting.reload", "id": 1}');
  1491. # }
  1492. #
  1493. # sl_send_reply("200","OK");
  1494. # exit();
  1495. # }
  1496. #}
  1497.  
  1498.  
  1499.  
  1500.  
  1501. # Dispatcher request load balancing (we don't route here)
  1502. route[DISPATCHER_SELECT] {
  1503. # round robin dispatching on dispatcher gateways set
  1504. if (!ds_select_dst($avp(domain_dispatcher_set_id),$avp(domain_dispatcher_alg))) {
  1505. xlog("L_INFO", "[DISPATCHER_SELECT] <$ci> no destination selected for domain: $fd\n");
  1506. send_reply("404", "No destination");
  1507. exit;
  1508. }
  1509.  
  1510. if (strempty($xavp(dispatcher_dst>uri)) && $avp(domain_dispatcher_alg) == 12)
  1511. xlog("L_DBG", "[DISPATCHER_SELECT] <$ci> sending to multiple servers in parallel\n");
  1512. else if (!strempty($xavp(dispatcher_dst>uri)))
  1513. xlog("L_DBG", "[DISPATCHER_SELECT] <$ci> dispatcher selected $xavp(dispatcher_dst>uri)\n");
  1514.  
  1515. t_on_failure("DISPATCHER_NEXT");
  1516. return;
  1517. }
  1518.  
  1519. failure_route[DISPATCHER_NEXT] {
  1520. # try next destionations in failure route
  1521. if (t_is_canceled()) {
  1522. exit;
  1523. }
  1524. # next DST - only for 500 or local timeout
  1525. if (t_check_status("4[0-9][0-9]|5[0-9][0-9]") or (t_branch_timeout() and !t_branch_replied())) {
  1526. if (ds_next_dst()) {
  1527. xlog("L_DBG", "[DISPATCHER_NEXT] <$ci> dispatcher selected $xavp(dispatcher_dst>uri)\n");
  1528. t_on_failure("DISPATCHER_NEXT");
  1529. t_reset_retr();
  1530. route(RELAY);
  1531. return;
  1532. }
  1533. else {
  1534. # Drop the replies if this is a REGISTER
  1535. if (is_method('REGISTER')) {
  1536. t_drop_replies();
  1537. t_reply("401", "Unauthorized");
  1538. }
  1539. }
  1540. }
  1541. }
  1542.  
  1543.  
  1544. # User location service
  1545. route[LOCATION] {
  1546.  
  1547. # Return immediately if the source address if not a PBX. Only PBX's should be trying to route to endpoints
  1548. if !(allow_source_address(FLT_PBX))
  1549. return;
  1550.  
  1551. # Emergency calls should return immediately so that it can be routed to a carrier
  1552. # The regular expression will call the North American (911), UK(999) and any number in between
  1553. if ($rU=~"^9[1-9][1-9]$")
  1554. return;
  1555.  
  1556. # Return if the rU is more then local calling maximum digits for the initiating PBX
  1557. if ($(rU{s.len}) > $sel(cfg_get.server.pbx_max_local_digits))
  1558. return;
  1559.  
  1560. $avp(oexten) = $rU;
  1561. # Lookup the location of the endpoint by username@from_domain
  1562. if (!lookup("location","sip:$rU@$rd")) {
  1563. $var(rc) = $rc;
  1564. route(TOVOICEMAIL);
  1565. t_newtran();
  1566. switch ($var(rc)) {
  1567. case -1:
  1568. case -3:
  1569. send_reply("404", "Not Found");
  1570. exit;
  1571. case -2:
  1572. send_reply("405", "Method Not Allowed");
  1573. exit;
  1574. }
  1575. }
  1576.  
  1577. if ($rU == "2000") {
  1578. if (isflagset(FLB_WS_DEVICE))
  1579. $var(WS_DEVICE)=1;
  1580. else
  1581. $var(WS_DEVICE)=0;
  1582.  
  1583. xlog("L_INFO","[LOCATION] ru: $ru, nh(u): $nh(u), WS:$var(WS_DEVICE)");
  1584. }
  1585.  
  1586. # when routing via usrloc, log the missed calls also
  1587. if (is_method("INVITE")) {
  1588. setflag(FLT_ACCMISSED);
  1589. }
  1590. #Set the INVITE timeout for sending calls to invites
  1591. t_set_fr(120000,10000);
  1592.  
  1593. #Add record_route to ensure that extensions know how to route back thru the proxy
  1594. record_route();
  1595.  
  1596. route(RELAY);
  1597. exit;
  1598. }
  1599.  
  1600. # Presence server processing
  1601. route[PRESENCE] {
  1602. if (!is_method("PUBLISH|SUBSCRIBE"))
  1603. return;
  1604.  
  1605. if (is_method("SUBSCRIBE") && $hdr(Event)=="message-summary") {
  1606. route(TOVOICEMAIL);
  1607. # returns here if no voicemail server is configured
  1608. sl_send_reply("404", "No voicemail service");
  1609. exit;
  1610. }
  1611.  
  1612. #!ifdef WITH_PRESENCE
  1613. if (!t_newtran()) {
  1614. sl_reply_error();
  1615. exit;
  1616. }
  1617.  
  1618. if (is_method("PUBLISH")) {
  1619. handle_publish();
  1620. t_release();
  1621. }
  1622. else if (is_method("SUBSCRIBE")) {
  1623. handle_subscribe();
  1624. t_release();
  1625. }
  1626. exit;
  1627. #!endif
  1628.  
  1629. # if presence enabled, this part will not be executed
  1630. if (is_method("PUBLISH") || $rU==$null) {
  1631. sl_send_reply("404", "Not here");
  1632. exit;
  1633. }
  1634. return;
  1635. }
  1636.  
  1637. # IP authorization and user authentication
  1638. route[AUTH] {
  1639. #!ifdef WITH_AUTH
  1640.  
  1641. # AUTH route logic summary:
  1642. # 1) attempt domain auth
  1643. # 2) Check if request is coming from a carrier that's using username/password auth (remote or local)
  1644. # 3) attempt IP auth
  1645. # 4) attempt username/password auth against local subscriber database
  1646.  
  1647. ###############
  1648. # Domain AUTH #
  1649. ###############
  1650. # Check if this is any type of SIP request from a known domain only if the role of the server is not "inout".
  1651. # The role of "inout" means that the role of this Kamailio instance is to just route calls inbound and outbound
  1652. # using only IP auth or username/password auth
  1653.  
  1654. if (lookup_domain("$fd", "domain_") && ($sel(cfg_get.server.role) != 'inout')) {
  1655. # Turn on domain routing by setting the FLT_DOMAINROUTING flag
  1656. setflag(FLT_DOMAINROUTING);
  1657.  
  1658. if (!strempty($avp(domain_pbx_ip))) {
  1659. # If the domain is mapped to single PBX then route to the PBX IP for authentication
  1660. setflag(FLT_PASSTHRU_AUTH);
  1661. xlog("L_INFO", "[AUTH-DOMAIN_AUTH] <$ci> $tU@$fd will be routed to $avp(domain_pbx_ip)\n");
  1662. return;
  1663. }
  1664.  
  1665. #Check if the domain is configured to route to a cluster of PBX's by checking if the dispatcher set_id is set
  1666. #If so, we need to auth the user against an external database or local subscriber database
  1667. #This will allow INVITE requests to be sent to any backend PBX's because we have validated the user
  1668. #Hence, the backend PBX's should be setup only to trust SIP connections from dSIPRouter instances
  1669.  
  1670. else if (!strempty($avp(domain_dispatcher_set_id))) {
  1671.  
  1672. if (is_method("REGISTER|INVITE") || from_uri==myself) {
  1673. # Each domain has a auth type thats external to the backend destination server
  1674. # 1 = Kamailo Subscriber table
  1675. # 2 = Asterisk DB
  1676.  
  1677. setflag(FLT_EXTERNAL_AUTH);
  1678.  
  1679. xlog("L_INFO", "[AUTH-DOMAIN_AUTH] <$ci> Generic Domain Routing for $tU@$fd - the defined auth type for $fd is $avp(domain_domain_auth)\n");
  1680.  
  1681. if ($avp(domain_domain_auth) == "realtime") {
  1682. xlog("L_INFO","[AUTH-DOMAIN_AUTH] <$ci> Asterisk Realtime auth is being used\n");
  1683. # Load data needed for custom SIP headers
  1684. if ($avp(domain_enrich_headers) == 1)
  1685. $var(query) = "select sippasswd,sipdomain from sipusers where name=$fU";
  1686. else
  1687. $var(query) = "select sippasswd from sipusers where name=$fU";
  1688.  
  1689. #Let's auth against the database defined by the domain attributes
  1690. sql_xquery("asterisk","$var(query)","ra");
  1691. xlog("L_DBG","[AUTH: DOMAIN AUTH]: The password for user $fU@$fd is $xavp(ra=>sippasswd)\n");
  1692.  
  1693. if (!pv_auth_check("$fd", "$xavp(ra=>sippasswd)", "2","0")) {
  1694. auth_challenge("$fd", "0");
  1695. exit;
  1696. }
  1697. }
  1698. if ($avp(domain_domain_auth) == "local") {
  1699. xlog("L_INFO", "[AUTH-DOMAIN_AUTH] <$ci> Local auth is being used\n");
  1700. if (!auth_check("$fd", "subscriber", "3")) {
  1701. auth_challenge("$fd", "0");
  1702. exit;
  1703. }
  1704. }
  1705. }
  1706. # user authenticated - remove auth header
  1707. if (!is_method("REGISTER|PUBLISH")) {
  1708. xlog("L_INFO", "[AUTH-DOMAIN_AUTH] <$ci> $tU@$fd was authenticated\n");
  1709. consume_credentials();
  1710. }
  1711.  
  1712. return;
  1713. }
  1714. }
  1715.  
  1716.  
  1717. #!ifdef WITH_IPAUTH
  1718. # If domain not known, then check IP AUTH to see if the user if allowed to connect
  1719. # Changed from allow_source_address to allow_source_addess_group because it will allow any addresses within any address group.
  1720. # This means that both carriers and pbx's will be allowed to access the proxy with one function call
  1721. if ((!is_method("REGISTER")) && allow_source_address_group()) {
  1722. # source IP allowed
  1723. route(SET_CALLINFO);
  1724. return;
  1725. }
  1726. #!endif
  1727.  
  1728. if (is_method("REGISTER|INVITE") || from_uri==myself) {
  1729. # authenticate requests
  1730. if (!auth_check("$fd", "subscriber", "3")) {
  1731. auth_challenge("$fd", "0");
  1732. exit;
  1733. }
  1734. # user authenticated - remove auth header
  1735. if (!is_method("REGISTER|PUBLISH")) {
  1736. consume_credentials();
  1737. }
  1738. # Set a flag denoting that a PBX has authenticated with username/password
  1739. setflag(FLT_PBX_AUTH);
  1740.  
  1741. route(SET_CALLINFO);
  1742. }
  1743.  
  1744. #!endif
  1745. return;
  1746. }
  1747.  
  1748. route[SET_CALLINFO] {
  1749. # defaults to null
  1750. $avp(src_gwid) = $null;
  1751. $avp(src_gwtype) = $null;
  1752. $avp(src_gwgroupid) = $null;
  1753.  
  1754. # Set call info for tracking call limits for username/pass auth
  1755. if (isflagset(FLT_PBX_AUTH)) {
  1756. sql_xquery("kam","select rpid as gwgroupid from subscriber where username='$au'","rb");
  1757. if (!strempty($xavp(rb=>gwgroupid))) {
  1758. sql_xquery("kam","select gwid from dr_gateways where address = '$si:$sp'","rc");
  1759. if (!strempty($xavp(rc=>gwid))) {
  1760. $avp(src_gwid) = $xavp(rc=>gwid);
  1761. }
  1762. $avp(src_gwtype) = FLT_PBX;
  1763. $avp(src_gwgroupid) = $xavp(rb=>gwgroupid);
  1764. xlog("L_INFO", "[SET_CALLINFO] <$ci> user/pass - gwgroupid: $avp(src_gwgroupid), gatewaytype: $avp(src_gwtype)\n");
  1765. sql_result_free("rc");
  1766. }
  1767. }
  1768. # Set call info for tracking call limits for ip auth
  1769. else {
  1770. sql_xquery("kam","select type, gwid from dr_gateways where address like '$si%'","rb");
  1771. if (!strempty($xavp(rb=>gwid))) {
  1772. $avp(src_gwid) = $xavp(rb=>gwid);
  1773. $avp(src_gwtype) = $xavp(rb=>type);
  1774. $avp(src_gwgroupid) = $sht(gw2gwgroup=>$avp(src_gwid));
  1775. xlog("L_INFO", "[SET_CALLINFO] <$ci> ip auth - gwgroupid: $avp(src_gwgroupid), gatewaytype: $avp(src_gwtype)\n");
  1776. }
  1777. }
  1778.  
  1779. # dst gateway info is unknown until routed
  1780. $avp(dst_gwid) = $null;
  1781. $avp(dst_gwtype) = $null;
  1782. $avp(dst_gwgroupid) = $null;
  1783. $avp(inbound_gwgroupid) = $null;
  1784.  
  1785. # set call forwarding info to null by default
  1786. $avp(hardfwdinfo) = $null;
  1787. $avp(failfwdinfo) = $null;
  1788.  
  1789. sql_result_free("rb");
  1790. return;
  1791. }
  1792.  
  1793. # TODO: we should avoid recreating the drouting algo here and instead check hardfwd and failfwd dr_group by default
  1794. # drouting would be called 3 times by default in this case, satisfying the following logic:
  1795. # 1. check hardfwd dr_group for prefix matches
  1796. # 2. check default dr_group for prefix matches (pbx or carrier)
  1797. # 3. check failfwd dr_group for prefix matches
  1798. # this would avoid prefix match prediction as we do below and support time criteria by default
  1799. route[SET_CALLFWD_INFO] {
  1800. # we need to know what prefix drouting will match before it runs
  1801. # this only checks against inbound rules, this shouldn't be used for outbound
  1802. # TODO: this algorithm ignores time criteria of the dr_rule
  1803. # which could lead to false positives if using this setting in drouting
  1804. $avp(dr_ruleid) = $null; # dr_ruleid matched
  1805. $var(prefix_match_diff) = 1000; # last match prefix diff
  1806. $var(diff) = 1000; # current entry prefix diff
  1807. $var(prefix_match_priority) = 0; # last match priority
  1808. $var(priority) = 0; # current entry priority
  1809. $var(lookup) = $(rU{s.unescape.user}); # dnid to match against
  1810.  
  1811. sht_iterator_start("iter", "inbound_prefixmap");
  1812. while(sht_iterator_next("iter")) {
  1813. # TODO: for now we use a literal prefix but we should change to supporting patterns
  1814. # this would require updating drouting module to support pattern matching
  1815. $var(regex) = $(shtitkey(iter){re.subst,/(\+|\*|\#)/\\\1/g}) + "([0-9])*";
  1816. if ($var(lookup) =~ $var(regex)) {
  1817. xlog("L_DBG", "[SET_CALLFWD_INFO] <$ci> prefix match on $shtitkey(iter)\n");
  1818. # if priority is less than last match we don't update match
  1819. $var(priority) = $(shtitval(iter){s.select,1,,}{s.int});
  1820. if ($var(priority) >= $var(prefix_match_priority)) {
  1821. # get the difference between prefix and match
  1822. $var(diff) = $(var(lookup){s.len}) - $(shtitkey(iter){s.len});
  1823. # bitwise absolute value: ( mask = n>>31; (mask^n) - mask )
  1824. # we are assuming 32 bit integers
  1825. $var(mask) = $var(diff) >> 31;
  1826. $var(diff) = ($var(mask) ^ $var(diff)) - $var(mask);
  1827. # if priority is greater than last match or priority is equal and
  1828. # diff is less than last match (closer match) we update match
  1829. if ($var(priority) > $var(prefix_match_priority) || $var(diff) < $var(prefix_match_diff)) {
  1830. xlog("L_DBG", "[SET_CALLFWD_INFO] <$ci> prefix closer match priority=$var(priority) diff=$var(diff)\n");
  1831. $avp(dr_ruleid) = $(shtitval(iter){s.select,0,,});
  1832. $var(prefix_match_priority) = $var(priority);
  1833. $var(prefix_match_diff) = $var(diff);
  1834. }
  1835. }
  1836. }
  1837. }
  1838. sht_iterator_end("iter");
  1839.  
  1840. if ($avp(dr_ruleid) != $null) {
  1841. $avp(hardfwdinfo) = $sht(inbound_hardfwd=>$avp(dr_ruleid));
  1842. $avp(failfwdinfo) = $sht(inbound_failfwd=>$avp(dr_ruleid));
  1843. }
  1844.  
  1845. return;
  1846. }
  1847.  
  1848. # Caller NAT detection
  1849. route[NATDETECT] {
  1850. #!ifdef WITH_NAT
  1851. if (nat_uac_test("19")) {
  1852. if (isflagset(FLT_SRC_SIP))
  1853. #fix_nated_contact();
  1854. force_rport();
  1855.  
  1856. if (is_method("REGISTER") && isflagset(FLT_SRC_WS)) {
  1857. t_on_reply("WS_REPLY");
  1858. fix_nated_register();
  1859. }
  1860. else
  1861. fix_nated_register();
  1862. #else {
  1863. # if (is_first_hop()) {
  1864. # set_contact_alias();
  1865. # }
  1866. #}
  1867.  
  1868. setflag(FLT_NATS);
  1869. }
  1870. #!endif
  1871. #!ifdef WITH_SERVERNAT
  1872. setflag(FLT_NATS);
  1873. #!endif
  1874.  
  1875. return;
  1876. }
  1877.  
  1878.  
  1879. route[SERVERNATDETECT] {
  1880. #!ifdef WITH_SERVERNAT
  1881. # Detect if Kamailio is configured behind NAT
  1882. if ("INTERNAL_IP_ADDR" != "EXTERNAL_IP_ADDR") {
  1883. setflag(FLT_SERVERNAT);
  1884. }
  1885. else {
  1886. return;
  1887. }
  1888.  
  1889. # If so, calculate the Local Subnet
  1890. #Build a regular expression for figuring out if the request is going towards a local machine
  1891. $var(local_subnet) = "INTERNAL_IP_NET";
  1892. # Replace the dots with \.
  1893. $var(local_subnet) = $(var(local_subnet){s.replace,.,\.});
  1894. # Replace the 0 with .*
  1895. $avp(local_subnet) = $(var(local_subnet){s.replace,*,.*});
  1896. #!endif
  1897.  
  1898. return;
  1899. }
  1900.  
  1901. route[IS_RTPE_REQUIRED] {
  1902. # Sets the flag to show if RTPEngine is required
  1903. if (isbflagset(FLB_WS_DEVICE) || isbflagset(FLB_SRC_MSTEAMS) || isbflagset(FLB_DST_MSTEAMS)) {
  1904. # WebRTC destination or MSTEAMS source
  1905. setflag(FLT_USE_RTPE);
  1906. }
  1907. else if (allow_source_address(FLT_MSTEAMS)) {
  1908. setbflag(FLB_SRC_MSTEAMS);
  1909. setflag(FLT_USE_RTPE);
  1910. }
  1911. else if (isflagset(FLT_SRC_SIP)) {
  1912. # Turn on NAT if behind NAT
  1913. # Check SDP for rfc1918 addresses - some natted SIP user devices need RTPEngine
  1914. #if (nat_uac_test("8") || isbflagset(FLT_NATS))
  1915. setflag(FLT_USE_RTPE);
  1916. }
  1917. else {
  1918. setflag(FLT_USE_RTPE);
  1919. }
  1920. }
  1921.  
  1922. route[RTPENGINEOFFER] {
  1923. if (isflagset(FLT_SRC_WS) && isbflagset(FLB_WS_DEVICE)) {
  1924. # - Web to web
  1925. $var(reflags) = "trust-address replace-origin replace-session-connection SDES-off ICE=force";
  1926. }
  1927. else if (isflagset(FLT_SRC_WS)) {
  1928. # - Web to SIP
  1929. $var(reflags) = "trust-address replace-origin replace-session-connection rtcp-mux-demux ICE=remove RTP/AVP";
  1930. }
  1931. else if (isbflagset(FLB_WS_DEVICE)) {
  1932. # - SIP to web
  1933. $var(reflags) = "trust-address replace-origin replace-session-connection rtcp-mux-offer ICE=force transcode-PCMU transcode-G722 SDES-off UDP/TLS/RTP/SAVP";
  1934. }
  1935. else if (isbflagset(FLB_SRC_MSTEAMS)) {
  1936. # - MSTEAMS to SIP using RTP/AVP
  1937. $var(reflags) = "trust-address replace-origin replace-session-connection rtcp-mux-offer ICE=remove RTP/AVP";
  1938. }
  1939. else if (isbflagset(FLB_DST_MSTEAMS)) {
  1940. # - SIP to MSTEAMS
  1941. $var(reflags) = "trust-address replace-origin replace-session-connection rtcp-mux-offer ICE=force transcode-PCMU transcode-G722 RTP/SAVP";
  1942. }
  1943. else {
  1944. # - SIP to SIP
  1945. $var(reflags) = "trust-address replace-origin replace-session-connection rtcp-mux-demux ICE=remove RTP/AVP";
  1946. }
  1947.  
  1948. rtpengine_offer("$var(reflags)");
  1949. }
  1950.  
  1951. route [RTPENGINEANSWER] {
  1952. if (isflagset(FLT_SRC_WS) && isbflagset(FLB_WS_DEVICE)) {
  1953. $var(reflags) = "trust-address replace-origin replace-session-connection SDES-off ICE=force";
  1954. }
  1955. else if (isflagset(FLT_SRC_WS)) {
  1956. $var(reflags) = "trust-address replace-origin replace-session-connection rtcp-mux-require ICE=force RTP/SAVPF";
  1957. }
  1958. else if (isbflagset(FLB_DST_MSTEAMS)) {
  1959. # - MSTEAMS to SIP using RTP/AVP
  1960. $var(reflags) = "trust-address replace-origin replace-session-connection rtcp-mux-offer ICE=remove RTP/AVP";
  1961. }
  1962. else if (isbflagset(FLB_SRC_MSTEAMS)) {
  1963. # - SIP to MSTEAMS
  1964. $var(reflags) = "trust-address replace-origin replace-session-connection rtcp-mux-require ICE=remove SDES-off RTP/SAVP";
  1965. #$var(reflags) = "trust-address replace-origin replace-session-connection rtcp-mux-offer ICE=force SDES-off RTP/SAVP";
  1966. }
  1967. else {
  1968. # - SIP to SIP
  1969. $var(reflags) = "trust-address replace-origin replace-session-connection rtcp-mux-demux ICE=remove RTP/AVP";
  1970. }
  1971.  
  1972. rtpengine_answer("$var(reflags)");
  1973. }
  1974.  
  1975. # RTPProxy control and signaling updates for NAT traversal
  1976. route[NATMANAGE] {
  1977. #!ifdef WITH_NAT
  1978. if (is_request()) {
  1979. if (has_totag() && check_route_param("nat=yes")) {
  1980. setbflag(FLB_NATB);
  1981. }
  1982. }
  1983. else if (has_body("application/sdp") && is_reply()) {
  1984. if (nat_uac_test("8")) {
  1985. fix_nated_sdp("10");
  1986. setflag(FLB_NATB);
  1987. }
  1988. }
  1989.  
  1990. if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB)))
  1991. return;
  1992.  
  1993. if (is_request()) {
  1994. if (!has_totag()) {
  1995. if(t_is_branch_route()) {
  1996. add_rr_param(";nat=yes");
  1997. }
  1998. }
  1999. }
  2000.  
  2001. if (is_reply()) {
  2002. if(isbflagset(FLB_NATB)) {
  2003. if(is_first_hop())
  2004. set_contact_alias();
  2005. }
  2006. }
  2007. return;
  2008. #!endif
  2009. }
  2010.  
  2011. # URI update for dialog requests
  2012. route[DLGURI] {
  2013. #!ifdef WITH_NAT
  2014. if(!isdsturiset()) {
  2015. handle_ruri_alias();
  2016. }
  2017. #!endif
  2018. return;
  2019. }
  2020.  
  2021. # Routing to foreign domains
  2022. route[SIPOUT] {
  2023. if (uri==myself) return;
  2024.  
  2025. append_hf("P-hint: outbound\r\n");
  2026. route(RELAY);
  2027. exit;
  2028. }
  2029.  
  2030. # PSTN GW routing
  2031. route[PSTN] {
  2032. #!ifdef WITH_PSTN
  2033. # check if PSTN GW IP is defined
  2034. if (strempty($sel(cfg_get.pstn.gw_ip))) {
  2035. xlog("L_ERR", "[PSTN] <$ci> pstn routing enabled but pstn.gw_ip not defined\n");
  2036. return;
  2037. }
  2038.  
  2039. # route to PSTN dialed numbers starting with '+' or '00' (international format)
  2040. # - update the condition to match your dialing rules for PSTN routing
  2041. if (!($rU=~"^(\+|00)[1-9][0-9]{3,20}$"))
  2042. return;
  2043.  
  2044. # only local users allowed to call
  2045. if (from_uri!=myself) {
  2046. sl_send_reply("403", "Not Allowed");
  2047. exit;
  2048. }
  2049.  
  2050. if (strempty($sel(cfg_get.pstn.gw_port))) {
  2051. $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);
  2052. }
  2053. else {
  2054. $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip) + ":"
  2055. + $sel(cfg_get.pstn.gw_port);
  2056. }
  2057.  
  2058. route(RELAY);
  2059. exit;
  2060. #!endif
  2061.  
  2062. return;
  2063. }
  2064.  
  2065. # XMLRPC routing
  2066. #!ifdef WITH_XMLRPC
  2067. route[XMLRPC] {
  2068. # allow XMLRPC from localhost
  2069. if ((method=="POST" || method=="GET") && (src_ip==127.0.0.1)) {
  2070. # close connection only for xmlrpclib user agents (there is a bug in
  2071. # xmlrpclib: it waits for EOF before interpreting the response).
  2072. if ($hdr(User-Agent) =~ "xmlrpclib")
  2073. set_reply_close();
  2074. set_reply_no_connect();
  2075. dispatch_rpc();
  2076. exit;
  2077. }
  2078.  
  2079. send_reply("403", "Forbidden");
  2080. exit;
  2081. }
  2082. #!endif
  2083.  
  2084. # Routing to voicemail server
  2085. route[TOVOICEMAIL] {
  2086. #!ifdef WITH_VOICEMAIL
  2087. if (!is_method("INVITE|SUBSCRIBE"))
  2088. return;
  2089.  
  2090. # check if VoiceMail server IP is defined
  2091. if (strempty($sel(cfg_get.voicemail.srv_ip))) {
  2092. xlog("L_ERR", "[TOVOICEMAIL] <$ci> VoiceMail routing enabled but IP not defined\n");
  2093. return;
  2094. }
  2095.  
  2096. if (is_method("INVITE")) {
  2097. if ($avp(oexten)==$null)
  2098. return;
  2099. $ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip)
  2100. + ":" + $sel(cfg_get.voicemail.srv_port);
  2101. }
  2102. else {
  2103. if ($rU==$null)
  2104. return;
  2105. $ru = "sip:" + $rU + "@" + $sel(cfg_get.voicemail.srv_ip)
  2106. + ":" + $sel(cfg_get.voicemail.srv_port);
  2107. }
  2108.  
  2109. route(RELAY);
  2110. exit;
  2111. #!endif
  2112.  
  2113. return;
  2114. }
  2115.  
  2116. # ======================================================
  2117. # Populate CDRs Table of Siremis
  2118. # ======================================================
  2119. route[CDRS] {
  2120. sql_query("kam","call kamailio_cdrs()","rb");
  2121. # we are not using billing features
  2122. #sql_query("kam","call kamailio_rating('default')","rb");
  2123. }
  2124.  
  2125. # send async http request for notifications
  2126. # required: $avp(notification_type)
  2127. # required: $avp(notification_gwgroupid)
  2128. # optional: $avp(notification_gwid)
  2129. route[SEND_NOTIFICATION] {
  2130. if ($avp(notification_type) != $null && $avp(notification_gwgroupid) != $null) {
  2131. $http_req(method) = "POST";
  2132. $http_req(hdr) = "User-Agent: http_async_client";
  2133. $http_req(hdr) = "Authorization: Bearer " + $sel(cfg_get.server.api_token);
  2134. $http_req(body) = '{"gwgroupid":' + $avp(notification_gwgroupid) + ', "type":' + $avp(notification_type) +
  2135. ', "gwid":' + $avp(notification_gwid) + ', "text_body":"Gateway Group [' + $avp(notification_gwgroupid) +
  2136. '] triggered the following notification for Gateway [' + $avp(notification_gwid) + ']"}';
  2137. $http_req(suspend) = 0;
  2138.  
  2139. xlog("L_INFO","[SEND_NOTIFICATION] <$ci> Sending request to $sel(cfg_get.server.api_server)/api/vi/notification/gwgroup for type $avp(notification_type)\n");
  2140. http_async_query("$sel(cfg_get.server.api_server)/api/v1/notification/gwgroup", "HTTP_REPLY");
  2141. }
  2142. else {
  2143. xlog("L_ERR", "[SEND_NOTIFICATION] <$ci> avp 'notification_type' and 'notification_gwgroupid' are required for notification sending\n");
  2144. }
  2145.  
  2146. $avp(notification_type) = $null;
  2147. $avp(notification_gwgroupid) = $null;
  2148. $avp(notification_gwid) = $null;
  2149. }
  2150.  
  2151. route[HTTP_REPLY] {
  2152. if ($http_ok) {
  2153. xlog("L_INFO", "[HTTP_REPLY] <$ci> status $http_rs\n");
  2154. xlog("L_DBG", "[HTTP_REPLY] <$ci> body $http_rb\n");
  2155. }
  2156. else {
  2157. xlog("L_ERR", "[HTTP_REPLY] <$ci> error $http_err)\n");
  2158. }
  2159. }
  2160.  
  2161. event_route[uac:reply] {
  2162. xlog("L_DBG", "[uac:reply] <$ci> Request sent to $uac_req(ruri) [$uac_req(evcode)]\n");
  2163. }
  2164.  
  2165. event_route[xhttp:request] {
  2166. if ($hu =~ "^/api/kamailio" && dst_ip==127.0.0.1) {
  2167. jsonrpc_dispatch();
  2168. }
  2169. #!ifdef WITH_WEBSOCKETS
  2170. else if ($Rp == WSS_PORT ) {
  2171. if ($hdr(Upgrade)=~"websocket" && $hdr(Connection)=~"Upgrade" && $rm=~"GET") {
  2172. if (ws_handle_handshake()) {
  2173. # Optional... cache some information about the
  2174. # successful connection
  2175. exit;
  2176. }
  2177. }
  2178. }
  2179. else {
  2180. xhttp_reply("403", "Forbidden", "text/html",
  2181. "<html><body>Will only communicate on the local interface or WebSocket Port WSS_PORT</body></html>");
  2182. exit;
  2183. }
  2184. #!endif
  2185. return;
  2186. }
  2187.  
  2188. #!ifdef WITH_MSTEAMS
  2189. event_route[tm:local-request] {
  2190.  
  2191. if(is_method("OPTIONS") && $ru =~ "pstnhub.microsoft.com") {
  2192. #append_hf("Contact: <sip:EXTERNAL_FQDN:SIPS_PORT;transport=tls>\r\n");
  2193. append_hf("Contact: <sip:$fd:SIPS_PORT;transport=tls>\r\n");
  2194. xlog("L_DBG", "Sent out tm request: $mb\n");
  2195. }
  2196.  
  2197.  
  2198. }
  2199. #!endif
  2200.  
  2201. # Manage outgoing branches
  2202. branch_route[MANAGE_BRANCH] {
  2203. if (isbflagset(FLB_WS_DEVICE))
  2204. $var(FLB_WS_DEVICE)=1;
  2205. else
  2206. $var(FLB_WS_DEVICE)=0;
  2207.  
  2208. xdbg("new branch [$T_branch_idx] to $ru with WS:$var(FLB_WS_DEVICE)\n");
  2209. #route(NATMANAGE);
  2210. if (isflagset(FLT_USE_RTPE) && $rm=="INVITE" && has_body("application/sdp"))
  2211. route(RTPENGINEOFFER);
  2212. }
  2213.  
  2214. # Manage incoming replies with a=inactive in SDP
  2215. onreply_route[MANAGE_INACTIVE_SDP] {
  2216. xlog("L_DBG","[MANAGE_INACTIVE_SDP_REPLY] In the reply\n");
  2217. xdbg("incoming reply $si\n");
  2218. if (remove_hf("Allow")){
  2219. append_hf("Allow: INVITE,ACK,OPTIONS,CANCEL,BYE,NOTIFY\r\n");
  2220. }
  2221.  
  2222.  
  2223. # Rewrite the SDP on incoming replies
  2224. if (t_check_status("183|180|200") && has_body("application/sdp")) {
  2225.  
  2226. if(search_body("a=sendrecv")) {
  2227. subst_body('/^a=sendrecv/a=inactive/');
  2228. msg_apply_changes();
  2229. }
  2230.  
  2231.  
  2232. route(RTPENGINEANSWER);
  2233. }
  2234. if (t_check_status("100|180|181|183") && $avp(calltype) == "inbound") {
  2235. # Increase the lifetime of the current INVITE to pbx_invite_timeout_aftertry if endpoint returns 100/180/181/183.
  2236. # This means that the endpoint is at least trying to establish the call. So, we will extend the timeout.
  2237.  
  2238. $var(pbx_invite_timeout) = (int)$sel(cfg_get.server.pbx_invite_timeout_aftertry);
  2239. t_set_max_lifetime($var(pbx_invite_timeout), 0);
  2240. xlog("L_DBG","[MANAGE_REPLY] Increasing the Invite Timeout for <$ci> to <$var(pbx_invite_timeout)>\n");
  2241. }
  2242. }
  2243.  
  2244. # Manage incoming replies
  2245. onreply_route[MANAGE_REPLY] {
  2246. xdbg("incoming reply $si\n");
  2247. if (remove_hf("Allow")){
  2248. append_hf("Allow: INVITE,ACK,OPTIONS,CANCEL,BYE,NOTIFY\r\n");
  2249. }
  2250.  
  2251.  
  2252. # Rewrite the SDP on incoming replies
  2253. if (t_check_status("183|180|200") && has_body("application/sdp")) {
  2254. route(RTPENGINEANSWER);
  2255. }
  2256.  
  2257. ##!ifdef WITH_NAT
  2258. # if (status=="200" && !allow_source_address(FLT_CARRIER)) {
  2259. # fix_nated_contact();
  2260. # }
  2261. ##!endif
  2262. # TODO: rewriting to external ip should be the default
  2263. # we should only rewrite to internal on servernat
  2264. #!ifdef WITH_SERVERNAT
  2265. #TODO: Need to evaluate this when running in AWS with an External SIP UAC
  2266. #if (status=="200" && allow_source_address(FLT_CARRIER)) {
  2267. # subst_hf("Record-Route","/EXTERNAL_IP_ADDR/INTERNAL_IP_ADDR/","f");
  2268. #}
  2269. if (status=="200" && allow_source_address(FLT_PBX)) {
  2270. subst_hf("Record-Route","/INTERNAL_IP_ADDR/EXTERNAL_IP_ADDR/","f");
  2271. }
  2272. #!endif
  2273.  
  2274. #TODO: Marked for removal
  2275. #if (status=~"[12][0-9][0-9]") {
  2276. # Invoke NATMANAGE when it's not a UPDATE
  2277. # if (!is_method("UPDATE")) {
  2278. # route(NATMANAGE);
  2279. # }
  2280. #}
  2281.  
  2282. if (t_check_status("100|180|181|183") && $avp(calltype) == "inbound") {
  2283. # Increase the lifetime of the current INVITE to pbx_invite_timeout_aftertry if endpoint returns 100/180/181/183.
  2284. # This means that the endpoint is at least trying to establish the call. So, we will extend the timeout.
  2285.  
  2286. $var(pbx_invite_timeout) = (int)$sel(cfg_get.server.pbx_invite_timeout_aftertry);
  2287. t_set_max_lifetime($var(pbx_invite_timeout), 0);
  2288. xlog("L_DBG","[MANAGE_REPLY] Increasing the Invite Timeout for <$ci> to <$var(pbx_invite_timeout)>\n");
  2289. }
  2290. }
  2291.  
  2292. # Manage failure routing cases
  2293. failure_route[MANAGE_FAILURE] {
  2294. route(NATMANAGE);
  2295.  
  2296. if (t_is_canceled()) {
  2297. exit;
  2298. }
  2299.  
  2300. if (t_branch_timeout()) {
  2301. t_drop_replies();
  2302. }
  2303.  
  2304.  
  2305. if (t_check_status("401|407") && !strempty($avp(carrier_groupid))) {
  2306. t_drop_replies();
  2307. xlog("L_INFO", "[MANAGE_FAILURE-PROXY_AUTH] Remote asked for authentication");
  2308.  
  2309. rtpengine_offer("ICE=remove");
  2310. uac_auth();
  2311. if (!t_relay()) {
  2312. xlog("L_INFO", "[MANAGE_FAILURE-PROXY_AUTH] Authentication failed. Sending back 503 to UA");
  2313. t_reply("503","Service not available");
  2314. }
  2315. exit;
  2316. }
  2317.  
  2318. # if using pass thru auth relay the reply
  2319. if (t_check_status("401|407") && isflagset(FLT_PASSTHRU_AUTH)) {
  2320. t_relay();
  2321. exit;
  2322. }
  2323.  
  2324. #!ifdef WITH_DROUTE
  2325. if (t_check_status("[0-6][0-9][0-9]")) {
  2326.  
  2327. #!ifdef WITH_CALLLIMIT
  2328. # Remove the existing call from the dialog before trying another gateway
  2329. if (($avp(src_gwtype) == FLT_PBX) || ($avp(gwgroups_equivalent) == 1)) {
  2330. unset_dlg_profile("gwgroup","$avp(src_gwgroupid)");
  2331. }
  2332. if (($avp(dst_gwtype) == FLT_PBX) && ($avp(gwgroups_equivalent) == 0)) {
  2333. unset_dlg_profile("gwgroup","$avp(dst_gwgroupid)");
  2334. }
  2335. #!endif
  2336.  
  2337. if (use_next_gw()) {
  2338. # Set INVITE max lifetime to ensure Primary and Secondary PBX server feature works.
  2339. if (allow_source_address(FLT_CARRIER)) {
  2340. $var(pbx_invite_timeout) = (int)$sel(cfg_get.server.pbx_invite_timeout);
  2341. t_set_max_lifetime($var(pbx_invite_timeout), 0);
  2342. }
  2343.  
  2344. route(RELAY);
  2345. exit;
  2346. }
  2347. else {
  2348. # Only intervene on a request from the Carrier
  2349. if (allow_source_address(FLT_CARRIER)) {
  2350. # check for failover fwd, then set did and dr_groupid accordingly
  2351. if (($avp(failfwdinfo) != $null) && !isflagset(FLT_FAILOVER)) {
  2352. # flag to make sure we don't loop endlessly
  2353. setflag(FLT_FAILOVER);
  2354.  
  2355. # allow DID to be unchanged
  2356. if (!strempty($(avp(failfwdinfo){s.select,0,,}))) {
  2357. $rU = $(avp(failfwdinfo){s.select,0,,});
  2358. }
  2359. $avp(dr_groupid) = $(avp(failfwdinfo){s.select,1,,}{s.int});
  2360. route(NEXTHOP);
  2361. }
  2362. # none of the routes worked, send back error
  2363. else {
  2364. t_reply("503","Service not available");
  2365.  
  2366. # we can only send notification if mapped to endpoint group
  2367. if ($avp(src_gwtype) == FLT_PBX) {
  2368. $avp(notification_type) = NOTIFICATION_GWFAILURE;
  2369. $avp(notification_gwgroupid) = $avp(src_gwgroupid);
  2370. $avp(notification_gwid) = $avp(src_gwid);
  2371. route(SEND_NOTIFICATION);
  2372. }
  2373. else if ($avp(dst_gwtype) == FLT_PBX) {
  2374. $avp(notification_type) = NOTIFICATION_GWFAILURE;
  2375. $avp(notification_gwgroupid) = $avp(dst_gwgroupid);
  2376. $avp(notification_gwid) = $avp(dst_gwid);
  2377. route(SEND_NOTIFICATION);
  2378. }
  2379. }
  2380. }
  2381. exit;
  2382. }
  2383. }
  2384. #!endif
  2385.  
  2386. #!ifdef WITH_BLOCK3XX
  2387. # block call redirect based on 3xx replies.
  2388. if (t_check_status("3[0-9][0-9]")) {
  2389. t_reply("404","Not found");
  2390. exit;
  2391. }
  2392. #!endif
  2393.  
  2394. #!ifdef WITH_VOICEMAIL
  2395. # serial forking
  2396. # - route to voicemail on busy or no answer (timeout)
  2397. if (t_check_status("486|408")) {
  2398. $du = $null;
  2399. route(TOVOICEMAIL);
  2400. exit;
  2401. }
  2402. #!endif
  2403. }
  2404.  
  2405. onreply_route[WS_REPLY] {
  2406. if (nat_uac_test(64)) {
  2407. # Do NAT traversal stuff for replies to a WebSocket connection
  2408. # - even if it is not behind a NAT!
  2409. # This won't be needed in the future if Kamailio and the
  2410. # WebSocket client support Outbound and Path.
  2411. add_contact_alias();
  2412. }
  2413. }
  2414.  
  2415. # TODO: dynamically get user_tn / pilot_tn from user configs
  2416. # Carrier Enrichment for CenturyLink
  2417. # validated SIP carriers:
  2418. # voip.centurylink.com
  2419. # 65.149.22.7, 65.149.23.7, 65.149.24.7, 65.149.25.7
  2420. # 216.206.64.7, 216.206.64.71, 216.206.64.91
  2421. # 216.206.66.7, 216.206.66.71, 216.206.66.91
  2422. route[ENRICH_CARRIER_CENTURYLINK_OUTBOUND] {
  2423. $var(domain) = "voip.centurylink.com";
  2424. $var(user_tn) = "6467687570";
  2425. $var(pilot_tn) = "6467687572";
  2426.  
  2427. if ($rd =~ "$var(domain).*|65.149.22.7.*|65.149.23.7.*|65.149.24.7.*|65.149.25.7.*|216.206.64.7.*|216.206.64.71.*|216.206.64.91.*|216.206.66.7.*|216.206.66.71.*|216.206.66.91.*") {
  2428. xlog("L_INFO", "[ENRICH_CARRIER_CENTURYLINK] centurylink carrier match\n");
  2429. $du = $ru;
  2430. $rd = $var(domain);
  2431. # Remove the port
  2432. $rp = "";
  2433. # Change the from and to domain to match the carrier domain name
  2434. $td = $var(domain);
  2435. $fd = $var(domain);
  2436. # Uncomment this line if you need to change the from user to the user_tn
  2437. #$fU = $var(user_tn);
  2438. # Uncomment this line if you need to change the domain of the contact - this is not recommended
  2439. #subst('/^Contact: <sip:([0-9]+)@(.*)$/Contact: <sip:\[email protected]>/ig')
  2440. # Add P-Asserted-Identity per the carriers requirement
  2441. append_hf("P-Asserted-Identity: <sip:$var(pilot_tn)@$var(domain)>\r\n");
  2442. msg_apply_changes();
  2443. }
  2444. }
  2445.  
  2446. route[ENRICH_CARRIER_SIGNALWIRE_INBOUND] {
  2447.  
  2448. $var(domain) = ".+sip.signalwire.com";
  2449.  
  2450. xlog("L_DBG", "[ENRICH_CARRIER_SIGNALWIRE] before transform:\n$mb\n");
  2451.  
  2452. if ($td =~".+sip.signalwire.com") {
  2453. xlog("L_INFO", "[ENRICH_CARRIER_SIGNALWIRE] signalwire carrier match\n");
  2454. # Change the "request username" to "to username"
  2455. $rU = $tU;
  2456.  
  2457. msg_apply_changes();
  2458.  
  2459. xlog("L_DBG", "[ENRICH_CARRIER_SIGNALWIRE] after transform:\n$mb\n");
  2460.  
  2461. }
  2462.  
  2463. }
  2464.  
  2465. route[ENRICH_CARRIER_SIGNALWIRE_OUTBOUND] {
  2466.  
  2467. $var(domain) = "sip.signalwire.com";
  2468. $var(user) = $fU;
  2469.  
  2470. xlog("L_DBG", "[ENRICH_CARRIER_SIGNALWIRE_OUTBOUND] before transform:\n$mb\n");
  2471.  
  2472. if ($rd =~".+sip.signalwire.com") {
  2473. xlog("L_INFO", "[ENRICH_CARRIER_SIGNALWIRE_OUTBOUND] signalwire carrier match\n");
  2474. # Change the from domain to the request domain
  2475. $fd = $rd;
  2476.  
  2477. # Change the from user to the authenticated user
  2478. $fU = $avp(auser);
  2479.  
  2480. # Add the callerid
  2481.  
  2482. append_hf("P-Asserted-Identity: <sip:$var(user)@$var(domain)>\r\n");
  2483.  
  2484. msg_apply_changes();
  2485.  
  2486. xlog("L_DBG", "[ENRICH_CARRIER_SIGNALWIRE_OUTBOUND] after transform:\n$mb\n");
  2487.  
  2488. }
  2489.  
  2490. }
  2491.  
  2492. route[ENRICH_CARRIER_INBOUND] {
  2493. route(ENRICH_CARRIER_SIGNALWIRE_INBOUND);
  2494.  
  2495. }
  2496.  
  2497. # Carrier Enrichment
  2498. route[ENRICH_CARRIER_OUTBOUND] {
  2499. route(ENRICH_CARRIER_CENTURYLINK_OUTBOUND);
  2500. route(ENRICH_CARRIER_SIGNALWIRE_OUTBOUND);
  2501. }
  2502.  
  2503.  
  2504.  
  2505. ####### CUSTOM_ROUTING_START #########
  2506. # add custom routes here
  2507.  
  2508. ####### CUSTOM_ROUTING_END #########
Add Comment
Please, Sign In to add comment