Edge脚本

  1. # VERSION=20.05.06.1
  2. #-------------------------------------------------
  3. # variables
  4. # - CF_INNER_IP x.x.x.x
  5. # - CF_PUBLIC_IP x.x.x.x
  6. # - CF_DB mysql://root@xxx:3306/db
  7. # - CF_HOMER x.x.x.x:9060
  8. # - CF_INFLUXDB_URL http://x.x.x.x:port/write?db=dbName
  9. #------------------------------------------------
  10. log_level=3 #log输出等级
  11. log_stderror=no #将opensips的标准错误写入日志yes no
  12. log_facility=LOG_LOCAL0 #控制记录工具 默认工具LOG_LOCAL0
  13. children=4 #定义UDP 或者SCTP接口工作子进程
  14. dns_try_ipv6=no #对ipv6进行查找
  15. auto_aliases=no #自动别名 默认值on
  16. server_header="Server:WSS" #公司的sip代理
  17. user_agent_header="User-Agent:WSS" #以UAC发送请求时生成的User-Agent标头字段的主体
  18. listen=udp:192.168.60.101:18627 as 192.168.60.101:18627
  19. listen=tcp:192.168.60.101:18627 as 192.168.60.101:18627
  20. listen=hep_udp:192.168.60.101:9061
  21. #监听以上端口
  22. #设置模块默认加载地址
  23. mpath="/usr/local/lib64/opensips/modules/"
  24. #基于TCPSIP通信传输模块,仅提供tcp读取和写入
  25. loadmodule "proto_tcp.so"
  26. #基于udpsip通信传输模块,仅提供udp
  27. loadmodule="proto_udp.so"
  28. #对数据库进行连接
  29. loadmodule="db_mysql.so"
  30. #SIP信令模块
  31. loadmodule="signaling.so"
  32. #无状态回复
  33. loadmodule="sl.so"
  34. #事务
  35. loadmodule="tm.so"
  36. #如果没有最终的请求答复或否定的INVITE答复的ACK到达,则触发超时
  37. modparam("tm", "fr_timeout", 2)
  38. #记录路由和路由模块
  39. loadmodule "rr.so"
  40. #允许插入两条record-route 默认值1
  41. modparam("rr", "enable_double_rr", 1)
  42. #如果打开,则请求的from-tag会附加到record-route 默认值1
  43. modparam("rr", "append_fromtag", 1)
  44. #通过uri操作模块
  45. loadmodule "uri.so"
  46. #对话框支持模块
  47. loadmodule "dialog.so"
  48. #将对话框的信息从内存中推入数据库 0-no_db ,1-实时任何对话信息更爱理科反映到数据库中,2-延时基于定时器返回数据库,3-仅对话框关闭时才刷新到db
  49. modparam("dialog", "db_mode", 0)
  50. #读取数据库
  51. modparam("dialog", "db_url", "mysql://root:wellcloud@192.168.60.132:3306/core_2_4")
  52. #设置与对话框匹配,0-仅基于DID进行匹配,1-先根据DID尝试匹配,2-基于SIP元素匹配
  53. modparam("dialog","dlg_match_mode",1)
  54. #默认对话框超时时间,毫秒
  55. modparam("dialog","default_timeout",21600)
  56. #设置名称列表默认值为空
  57. modparam("dialog","profiles_with_value","domain")
  58. #最大转接处理器模块
  59. loadmodule "maxfwd.so"
  60. #文本操作模块
  61. loadmodule "textops.so"
  62. #管理接口fifo支持
  63. loadmodule "mi_fifo.so"
  64. #创建用于监听和读取外部命令的FIFO文件名称
  65. modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
  66. #分发器模块
  67. loadmodule "dispatcher.so"
  68. #设置数据库
  69. modparam("dispatcher", "db_url", "mysql://root:wellcloud@192.168.60.132:3306/core_2_4")
  70. #ping的方式,默认值options
  71. modparam("dispatcher", "ds_ping_method", "OPTIONS")
  72. #定义将请求发送到故障网关的时间间隔
  73. modparam("dispatcher", "ds_ping_interval", 5)
  74. #网关设置探测模式时的探测次数
  75. modparam("dispatcher", "ds_probing_threshhold", 2)
  76. #控制测试哪些网关以查看它们是否可访问
  77. modparam("dispatcher", "ds_probing_mode", 1)
  78. #SIP操作模块
  79. loadmodule "sipmsgops.so"
  80. #NAT遍历help模块
  81. loadmodule "nathelper.so"
  82. #AVP操作模块
  83. loadmodule "avpops.so"
  84. #设置avp数据库
  85. modparam("avpops", "db_url", "mysql://root:wellcloud@192.168.60.132:3306/core_2_4")
  86. #设置avp所在表名
  87. modparam("avpops", "avp_table", "dbaliases")
  88. #rtp代理模块
  89. #loadmodule "rtpproxy.so"
  90. #modparam("rtpproxy","rtpproxy_sock","udp:CF_INNER_IP:7890")
  91. #rtpengine外部rtp继电器连接器
  92. loadmodule "rtpengine.so"
  93. #连接rtp代理套接字定义
  94. modparam("rtpengine", "rtpengine_sock", "udp:192.168.60.101:7890")
  95. #SIP前端路径支持
  96. loadmodule "path.so"
  97. #评估第一个Route URI 默认值0
  98. modparam("path", "use_received", 1)
  99. #嵌入式HTTP服务器
  100. loadmodule "httpd.so"
  101. #管理接口的http支持
  102. loadmodule "mi_http.so"
  103. #多域支持模块
  104. loadmodule "domain.so"
  105. #数据库支持
  106. modparam("domain", "db_url","mysql://root:wellcloud@192.168.60.132:3306/core_2_4")
  107. #数据库模式:0表示不缓存,1表示缓存 默认值0
  108. modparam("domain", "db_mode", 0)
  109. #动态路由
  110. loadmodule "drouting.so"
  111. #是否使用域匹配,默认值是1
  112. modparam("drouting", "use_domain", 1)
  113. #数据库支持
  114. modparam("drouting", "db_url","mysql://root:wellcloud@192.168.60.132:3306/core_2_4")
  115. #HTTP客户端实现
  116. loadmodule "rest_client.so"
  117. #允许最长时间(秒),默认20
  118. modparam("rest_client", "curl_timeout", 5)
  119. #最大连接时间(秒),默认20
  120. modparam("rest_client", "connection_timeout", 3)
  121. #emmm,没找到该模块?
  122. loadmodule "statistics.so"
  123. #HEP协议模块
  124. loadmodule "proto_hep.so"
  125. #指定HEP数据包的目的地和所使用的HEP协议的版本
  126. modparam("proto_hep", "hep_id","[hep_dst] 192.168.40.79:9060;transport=udp;version=3")
  127. #SIPTrace模块
  128. loadmodule "siptrace.so"
  129. #指定跟踪的目的地
  130. modparam("siptrace", "trace_id","[tid]uri=hep:hep_dst")
  131. #设置use_domain域是1
  132. modparam("auth_db|usrloc|uri", "use_domain", 1)
  133. route[r_invite_to_core]{
  134. if(is_method("INVITE")){
  135. #$cfg_line当前脚本运行行;$cs CSeq number;$rm request method;$fu From Uri,$tu To Uri
  136. xlog("$cfg_line-$cs $rm $fu->$tu r_invite_from_out");
  137. #该函数为当前处理的请求创建对话框。该请求必须是初始请求。B是超时再见
  138. #如果创建失败,返回500,超时发送bye
  139. if(!create_dialog("B")){
  140. xlog("$cfg_line-$cs $rm $fu->$tu exec send_reply 500 Internal Server Error");
  141. send_reply("500","Internal Server Error");
  142. exit;
  143. }
  144. #如果含有sdp
  145. if(has_body("application/sdp")){
  146. xlog("$cfg_line-$cs $rm $fu->$tu exec rtpproxy_offer!");
  147. #rtpproxy_offer("oc","CF_INNER_IP");
  148. #重写sdp,使媒体能通过rtp传递。ICE=remove丢弃并且不插入任何ice
  149. rtpengine_offer("ICE=remove");
  150. #记录rtp
  151. rtpengine_start_recording();
  152. t_on_reply();
  153. }
  154. #为当前处理的消息设置一个标志
  155. setflag(10);
  156. #通过dispatch查找组1,运用0的计算方法
  157. if(!ds_select_dst("1","0")){
  158. send_reply("502","Service Unavailable");
  159. exit;
  160. }
  161. }
  162. #判断invite请求是否来自core
  163. route[r_invite_from_core]{
  164. if(ds_is_in_list("$si","$sp","1")){
  165. xlog(" enter in fs callout >>>");
  166. #just select gateway by request_url
  167. if(is_method("INVITE") && has_body("appkication/sdp")){
  168. xlog("exec rtpproxy_offer!");
  169. #rtpproxy_offer("ro","CF_PUBLIC_IP");
  170. #重写sdp,使媒体能通过rtp传递。ICE=remove丢弃并且不插入任何ice
  171. rtpengine_offer("ICE=remove");
  172. #记录rtp
  173. rtpengine_start_recording();
  174. t_on_reply("r_rw_sdp");
  175. }
  176. #交由opensips处理
  177. t_relay();
  178. exit;
  179. }
  180. }
  181. #这部分有点问题
  182. route[r_seq_request]{
  183. #是否有tag标签,是否不是notify 通知所有用户
  184. if(has_totag()&&!is_method("NOtIFY")){
  185. #失去了route,不清楚
  186. if(loose_route()){
  187. #没找到,有application/sdp
  188. if(has_body("application/sdp")){
  189. #通过dispatch判断
  190. if(ds_is_in_list("$si","$sp","1")){
  191. #rtpproxy_offer("ro","CF_PUBLIC_IP");
  192. rtpengine_offer("ICE=remove");
  193. }else{
  194. #rtpproxy_offer("oc","CF_INNER_IP");
  195. #重写sdp,使媒体能通过rtp传递。ICE=remove丢弃并且不插入任何ice
  196. rtpengine_offer("ICE_reomver");
  197. }
  198. #记录
  199. rtpengine_start_recording();
  200. if(is_method("INVITE")){
  201. t_on_reply("r_rw_sdp");
  202. }
  203. }
  204. #如果是bye,结束rtp代理
  205. if(is_method("BYE")){
  206. #rtpproxy_unforce();
  207. rtpengine_delete();
  208. }
  209. #该功能对照其所属的对话框(内部数据)检查当前收到的请求。
  210. #$DLG_status==null说明没有dialog
  211. if($DLG_status!=NULL && !validate_dialog()){
  212. xlog("In-Dialog $rm from $si (callid=$ci) is not valid according to dialog\n")
  213. #该函数强制对话框中的SIP消息包含ruri,路由头和dst_uri,防止虚假注入的恶意请求如bye
  214. fix_route_dialog();
  215. }
  216. t_relay();
  217. exit;
  218. }else{
  219. #ACK|BYE方法判段;判段当前是否与事务关联
  220. if(is_method("ACK|BYE") && t_check_trans()){
  221. t_relay();
  222. exit;
  223. }
  224. #stateless无状态回复
  225. sl_send_reply("404","Not here");
  226. }
  227. exit;
  228. }
  229. }
  230. route[r_fix_nat_contact]{
  231. #19表示1+2+16,其中1216分别代表了不同的NAT检测条件,重要参考地址
  232. #https://www.yuque.com/wangdd/opensips/olt40x
  233. #测试请求是否源于nat
  234. if(nat_uac_test("19")){
  235. xlog("find a NAT address,fix it...si=$si sp=$sp rm=$rm");
  236. #重写URI Contact HF以包含请求的源地址
  237. #Rewrites the URI Contact HF to contain request's source address
  238. fix_nated_contact();
  239. }
  240. route[r_check_ip]{
  241. #对invite判断;是否来自domain表;
  242. if(is_method("INVITE")&&!is_from_local()&&!ds_is_in_list("$si","$sp","1")){
  243. #是否来自某个网关 gateway,-1全部检查,n忽略端口
  244. if(!is_from_gw("-1","n")){
  245. xlog("L_ERR","caller is not local and Not in whrite list!");
  246. #SIP信令模块发送reply403
  247. send_reply("403","Forbidden IP");
  248. }
  249. }
  250. }
  251. route[r_cancel]{
  252. #对cancel方法进行判断
  253. if(is_method("CANCEL")){
  254. #判断当前是否与事物transaction关联
  255. if(t_check_trans()){
  256. #交由opensips处理
  257. t_relay();
  258. }
  259. exit;
  260. }
  261. }
  262. route[r_notify]{
  263. #方法为notify,通知所有用户事件;根据domain表查询;通过dispatcher表查询source IP,source port,组号
  264. if(is_method("NOTIFY")&&!is_from_local()&&!ds_is_in_list("$si","$sp","1")){
  265. #是否来自某个网关 gateway,-1全部检查,n忽略端口
  266. if(!is_from_gw("-1","n")){
  267. xlog("L_ERR","caller is not local and Not in whrite list!");
  268. #SIP信令模块发送reply403
  269. send_reply("403","Forbidden IP");
  270. }
  271. }
  272. }
  273. #对options进行判断,查询服务器的能力
  274. route[r_options]{
  275. if(is_method("OPTIONS")){
  276. #stateless 无状态回复
  277. sl_send_reply("200","ok");
  278. exit();
  279. }
  280. }
  281. #修改User-Agent防止被攻击
  282. route[r_hide_fs_ua]{
  283. #User-Agent header
  284. if($ua=~'^FreeSWITCH'){
  285. #remove head from
  286. remove_hf("User-Agent");
  287. #添加头
  288. append_hf("User-Agent:WSS\r\n","CSeq");
  289. }
  290. }
  291. route[r_check_maxfwd]{
  292. #判断最大转接数
  293. if(!mf_prcess_maxfwd_head("10")){
  294. #483 过多转接退出opensips
  295. sl_send_reply("483","Too Many Hops");
  296. exit;
  297. }
  298. }
  299. #对确定地址的数据进行写入数据库操作
  300. rout[r_homer_capture]{
  301. if(is_method("INVITE|ACK|BYE")){
  302. xlog("<<<<<<<<<<welcome new request>>>>>>>>>>>>>>");
  303. #$rm request method, $fu from uri,$tu to uri,$cs Csq number
  304. xlog("$rm $fu->$tu $cs");
  305. #sip capture
  306. $var(enableHomer)="192.168.40.79:9060";
  307. #has_totag确定是否有头,是否为初始请求
  308. if($var(enableHomer) && !has_totag()){
  309. #https://opensips.org/docs/modules/2.4.x/siptrace.html#func_sip_trace
  310. #在数据库中存储或重新部署当前已处理的SIP消息,事务或对话框
  311. #指定跟踪位置 trace_id的名称,
  312. #d'/'D'跟踪对话框(m'/'M'跟踪消息,'t'/'T'跟踪交易。),
  313. #sip-启用sip消息跟踪;xlog-启用在当前范围内(日志,事务或消息)的xlog消息跟踪;休息-启用休息消息跟踪;
  314. sip_trace("tid","d,"sip|xlog|rest");
  315. }
  316. }
  317. }
  318. #回复路由
  319. onreply_route[r_rw_sdp]{
  320. #修复nat contact
  321. fix_nated_contact();
  322. #如果是bye或者cancel 卸下rtp代理
  323. if(is_method("BYE|CANCEL")){
  324. #rtpproxy_unforce();
  325. rtpengine_delete();
  326. }
  327. #如果带有sdp信息
  328. if(has_body("application/sdp")){
  329. xlog("onreply_route1 rtpproxy_answer----si=$si");
  330. #如果源地址在记录中
  331. if(ds_is_in_list("$si","$sp","1")){
  332. #rtpproxy_answer("ro","CF_PUBLIC_IP");
  333. #重写sdp头,使信息能通过rtp代理
  334. rtpengine_answer();
  335. #这句代码不知道什么意义
  336. replace_all("sip:192.168.60.101","sip:192.168.60.101");
  337. }else{
  338. #rtpproxy_answer("oc","CF_INNER_IP");
  339. #这里ifelse好像没什么意义
  340. rtpengine_answer();
  341. replace_all("sip:192.168.60.101","sip:192.168.60.101");
  342. }
  343. }
  344. }
  345. onreply_route{
  346. route(r_hide_fs_ua);
  347. }
  348. route{
  349. #将rport参数添加到第一个Via标头(使sip消息能够正确返回)
  350. force_rport();
  351. #对确定的地址进行消息跟踪
  352. route(r_homer_capture);
  353. #确定转接是否超过界限,是,退出opensips主机
  354. route(r_check_maxfwd);
  355. #修改User-Agent防止被攻击
  356. route(r_hide_fs_ua);
  357. #对options进行无状态回复
  358. route(r_options);
  359. #通知所有事件
  360. route(r_notify);
  361. #对cancel(取消任何悬而未决的请求)
  362. route(r_cancel);
  363. #对invite请求判断是否来自fs
  364. route(r_check_ip);
  365. #修复contact头,实现sip信息的nat穿透
  366. route(r_fix_nat_contact);
  367. #请求判断?
  368. route(r_seq_request);
  369. #记录返回地址
  370. record_route();
  371. #判断invite请求是否来自core
  372. route(r_invite_from_core);
  373. #处理发送coreinvite请求
  374. route(r_invite_to_core);
  375. #
  376. route(r_register);
  377. #是否进入opensips操作
  378. if(!t_relay()){
  379. xlog("L_ERROR","reply error!!");
  380. #stateless无协议回复错误
  381. sl_reply_error();
  382. }
  383. }

core脚本问题

  1. # VERSION=core-2.4.7.21
  2. log_level=3
  3. log_stderror=yes
  4. log_facility=LOG_LOCAL0
  5. children=4
  6. auto_aliases=no
  7. server_header="Server:WSS"
  8. user_agent_header="User-Agent:WMS"
  9. listen=udp:192.168.40.20:18627
  10. listen=hep_udp:192.168.40.20:9060
  11. mpath="/usr/local/lib64/opensips/modules/"
  12. loadmodule "proto_udp.so"
  13. loadmodule "proto_tcp.so"
  14. loadmodule "signaling.so"
  15. loadmodule "regex.so"
  16. loadmodule "sl.so"
  17. loadmodule "tm.so"
  18. loadmodule "rr.so"
  19. loadmodule "uac.so"
  20. loadmodule "maxfwd.so"
  21. loadmodule "sipmsgops.so"
  22. loadmodule "mi_fifo.so"
  23. loadmodule "dispatcher.so"
  24. loadmodule "rest_client.so"
  25. loadmodule "uri.so"
  26. loadmodule "db_mysql.so"
  27. loadmodule "textops.so"
  28. loadmodule "usrloc.so"
  29. loadmodule "registrar.so"
  30. loadmodule "acc.so"
  31. loadmodule "auth.so"
  32. loadmodule "auth_db.so"
  33. loadmodule "alias_db.so"
  34. loadmodule "domain.so"
  35. loadmodule "topology_hiding.so"
  36. loadmodule "dialog.so"
  37. loadmodule "nathelper.so"
  38. loadmodule "carrierroute.so"
  39. loadmodule "avpops.so"
  40. loadmodule "dialplan.so"
  41. loadmodule "permissions.so"
  42. loadmodule "drouting.so"
  43. loadmodule "group.so"
  44. loadmodule "load_balancer.so"
  45. loadmodule "httpd.so"
  46. loadmodule "mi_http.so"
  47. loadmodule "mi_json.so"
  48. loadmodule "path.so"
  49. loadmodule "exec.so"
  50. loadmodule "statistics.so"
  51. loadmodule "cachedb_local.so"
  52. #loadmodule "cachedb_redis.so"
  53. loadmodule "proto_hep.so"
  54. loadmodule "siptrace.so"
  55. modparam("tm", "fr_timeout", 5)
  56. modparam("tm", "fr_inv_timeout", 60)
  57. modparam("tm", "restart_fr_on_each_reply", 0)
  58. modparam("tm", "onreply_avp_mode", 1)
  59. modparam("dispatcher", "db_url", "mysql://root:111111@192.168.40.191:3306/core_2_4")
  60. modparam("dispatcher", "ds_ping_method", "OPTIONS")
  61. modparam("dispatcher", "ds_ping_interval", 5)
  62. modparam("dispatcher", "ds_probing_threshhold", 2)
  63. modparam("dispatcher", "hash_pvar", "$avp(select_fs_strategy_hash)")
  64. modparam("dispatcher", "ds_probing_mode", 1)
  65. modparam("rr", "append_fromtag", 1)
  66. modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
  67. modparam("mi_fifo", "fifo_mode", 0666)
  68. modparam("uri", "use_uri_table", 0)
  69. modparam("uri", "db_url","mysql://root:111111@192.168.40.191:3306/core_2_4")
  70. modparam("usrloc", "nat_bflag", "NAT")
  71. modparam("usrloc", "working_mode_preset","sql-only")
  72. modparam("usrloc", "db_url","mysql://root:111111@192.168.40.191:3306/core_2_4") # CUSTOMIZE ME
  73. modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
  74. modparam("registrar", "received_avp", "$avp(received_nh)")
  75. modparam("registrar", "max_contacts", 1)
  76. modparam("registrar", "min_expires", 120)
  77. modparam("registrar", "max_expires", 180)
  78. modparam("registrar", "default_expires", 150)
  79. modparam("registrar", "attr_avp", "$avp(attr)")
  80. modparam("acc", "early_media", 0)
  81. modparam("acc", "report_cancels", 1)
  82. modparam("acc", "detect_direction", 1)
  83. modparam("acc", "db_url","mysql://root:111111@192.168.40.191:3306/core_2_4") # CUSTOMIZE ME
  84. modparam("auth_db", "calculate_ha1", yes)
  85. modparam("auth_db", "password_column", "password")
  86. modparam("auth_db", "db_url","mysql://root:111111@192.168.40.191:3306/core_2_4") # CUSTOMIZE ME
  87. modparam("auth_db", "load_credentials", "")
  88. modparam("alias_db", "db_url","mysql://root:111111@192.168.40.191:3306/core_2_4") # CUSTOMIZE ME
  89. modparam("domain", "db_url","mysql://root:111111@192.168.40.191:3306/core_2_4") # CUSTOMIZE ME
  90. modparam("domain", "db_mode", 0) # 0: witchout cache, 1: Use caching
  91. modparam("auth_db|usrloc|uri", "use_domain", 1)
  92. modparam("dialog", "dlg_match_mode", 1)
  93. modparam("dialog", "default_timeout", 7200)
  94. modparam("dialog", "db_mode", 0) # 0:no_db, 1:realtime, 2:delayed, 3:shutdown
  95. modparam("dialog", "profiles_with_value", "domain")
  96. modparam("dialog", "db_url","mysql://root:111111@192.168.40.191:3306/core_2_4") # CUSTOMIZE ME
  97. #modparam("dialog", "cachedb_url", "redis://CF_REDIS_DB/")
  98. modparam("nathelper", "natping_interval", 10)
  99. modparam("nathelper", "ping_nated_only", 1)
  100. modparam("nathelper", "received_avp", "$avp(received_nh)")
  101. modparam("carrierroute", "db_url", "mysql://root:111111@192.168.40.191:3306/core_2_4")
  102. modparam("carrierroute", "config_source", "db")
  103. modparam("carrierroute", "use_domain", 1)
  104. modparam("carrierroute", "db_failure_table", "carrierfailureroute")
  105. modparam("avpops", "db_url", "mysql://root:111111@192.168.40.191:3306/core_2_4")
  106. modparam("avpops", "avp_table", "dbaliases")
  107. modparam("dialplan", "db_url", "mysql://root:111111@192.168.40.191:3306/core_2_4")
  108. modparam("drouting", "use_domain", 1)
  109. modparam("drouting", "db_url","mysql://root:111111@192.168.40.191:3306/core_2_4")
  110. modparam("group", "use_domain", 1)
  111. modparam("group", "db_url", "mysql://root:111111@192.168.40.191:3306/core_2_4")
  112. modparam("load_balancer", "db_url", "mysql://root:111111@192.168.40.191:3306/core_2_4")
  113. modparam("load_balancer", "probing_reply_codes", "501, 403")
  114. modparam("load_balancer", "probing_interval", 30)
  115. modparam("rr", "enable_double_rr", 1)
  116. modparam("path", "use_received", 1)
  117. modparam("exec", "time_to_kill", 10)
  118. modparam("rest_client", "curl_timeout", 5)
  119. modparam("statistics", "stat_groups", "wj")
  120. modparam("proto_hep", "hep_id","[hep_dst] 192.168.60.228:9060;transport=udp;version=3")
  121. modparam("siptrace", "trace_id","[tid]uri=hep:hep_dst")
  122. modparam("cachedb_local", "cachedb_url", "local://")
  123. modparam("cachedb_local", "cache_clean_period", 120)
  124. route{
  125. #在Via头中添加rport参数使sip消息能够正确返回
  126. force_rport();
  127. #跟踪记录注册的sip信息
  128. route(r_siphub_capture);
  129. #不支持PUBLISH|SUBSCRIBE方法进行
  130. route(r_not_support);
  131. #内存溢出提示
  132. route(r_options);
  133. #修复notify请求下$rU request username 为空的情况
  134. route(r_fix_notify);
  135. #修复nat问题,
  136. route(r_nat_uac_test);
  137. #过滤回环
  138. route(r_max_fwd);
  139. #匹配现有对话,如果存在对话使用t_repley并结束
  140. route(r_fix_route_dialog);
  141. xlog("$cfg_line-$cs $rm $fu->$tu processing \n");
  142. #处理消息
  143. route(r_relay_seq_request);
  144. #为cancel方法,
  145. if (is_method("CANCEL")) {
  146. if (t_check_trans())
  147. t_relay();
  148. exit;
  149. }
  150. #如果过是重传请求则中断脚本
  151. t_check_trans();
  152. if (!is_method("REGISTER")) {
  153. if (is_from_local()) {
  154. #使用子路由,本地请求入口
  155. route(r_author_request_from_edge);
  156. } else {
  157. # is not from fs, may be from edge
  158. #非本地请求,调用子路由
  159. if (!lb_is_destination("$si","$sp","1") ) {
  160. route(r_did);
  161. }
  162. }
  163. }
  164. #抛弃表头
  165. loose_route();
  166. #方法是REGISTER|MESSAGE记录返回地址
  167. if (!is_method("REGISTER|MESSAGE")){
  168. record_route();
  169. }
  170. #方法是INVITE发送消息退出
  171. if (is_method("INVITE")) {
  172. if ( !create_dialog("B") ) {
  173. xlog("create dialog Error \n");
  174. send_reply("500","Internal Server Error");
  175. exit;
  176. }
  177. route(r_do_accounting);
  178. }
  179. #方法是PUBLIST|SUBSCRIBE
  180. if (is_method("PUBLISH|SUBSCRIBE")){
  181. sl_send_reply("503", "Service Unavailable");
  182. exit;
  183. }
  184. # handle registerr_registerr_register
  185. route(r_register);
  186. if ($rU==NULL) {
  187. xlog("rU is null \n");
  188. sl_send_reply("484","Address Incomplete");
  189. exit;
  190. }
  191. #是本地domain
  192. if (is_from_local()){
  193. avp_db_query("SELECT limit_num,trunk_group FROM domain WHERE domain='$fd'","$avp(t_limit);$avp(t_trunk_group)");
  194. if(is_avp_set("$avp(t_limit)") && $avp(t_limit)>0 ){
  195. xlog("$fd limit $avp(t_limit) !\n");
  196. $var(t_domain) = $fd;
  197. route(r_do_limit, $var(t_domain), $avp(t_limit));
  198. }
  199. #记录返回头
  200. if (is_method("INVITE") && has_body("application/sdp")){
  201. record_route();
  202. }
  203. #回复路由
  204. t_on_reply("r_delete_trunk_info");
  205. #平衡配置
  206. if (!load_balance("1","trunk")) {
  207. xlog("load_balance failed: check fs is ok\n");
  208. #无状发送消息
  209. sl_send_reply("500","Service full.");
  210. exit;
  211. }
  212. t_relay();
  213. } else {
  214. $rd = $td;
  215. #查询本地路由
  216. if (!lookup("location","m")) {
  217. #判断数据库中是否存在
  218. if (!db_does_uri_exist()) {
  219. # -1 outbound reg: [56789][0-9]*
  220. if($rU=~'^[56789][0-9]+$'){
  221. $avp(call_origin_rU)=$rU;
  222. route(r_query_route);
  223. if(!is_avp_set("$avp(trunk_group)")) {
  224. sl_send_reply("402", "no trunk group");
  225. exit();
  226. }
  227. #移除标头
  228. remove_hf("P-Preferred-Identity");
  229. remove_hf("P-Asserted-Identity");
  230. xlog("begin route... carrier=$avp(carrier) trunk_group=$avp(trunk_group) request_username=$rU host=$avp(host)\n");
  231. #通过在初始请求上调用此函数,模块将隐藏拓扑,这意味着它将剥离并还原所有ViaRecord-RouteRoute标头,并将联系人替换为请求所在接口的IP地址。收到。
  232. topology_hiding();
  233. #将所有"WSS"替换为Freeswitch
  234. replace_all("FreeSWITCH", "WMS");
  235. #此函数在给定的载波树中的给定域中搜索在prefix_matching中给定的用户的最长匹配项
  236. if(!cr_route("carrier1","$avp(trunk_group)", "$rU", "$rU", "call_id", "$avp(host)")){
  237. xlog("L_ERR","cr_route failed! send reply 485.\n");
  238. sl_send_reply("485", "route ambiguous!");
  239. }
  240. else {
  241. #setflag(ACC_DO);
  242. #setflag(ACC_MISSED);
  243. # In case of failure, re-route the request
  244. $avp(outbound_rU) = $rU;
  245. route(r_find_real_rU);
  246. $var(new_to_same) = "sip:"+ $rU + "@" + $td;
  247. #替换to标头中的uri
  248. uac_replace_to("$rU", "$var(new_to_same)");
  249. #使用failure,reply的分支路由
  250. t_on_failure("missed_call");
  251. t_on_reply("r_add_trunk_info");
  252. route(r_set_edge_ip);
  253. t_relay();
  254. }
  255. exit;
  256. }
  257. else{
  258. xlog("L_WARN","send reply 420 Bad Extension ! $ru\n");
  259. send_reply("420","Bad Extension");
  260. exit;
  261. }
  262. }
  263. else{
  264. if (is_method("INVITE")) {
  265. route(r_ext_bind_phone);
  266. }
  267. #为当前处理的SIP请求创建SIP事务
  268. t_newtran();
  269. xlog("L_WARN","404 not found !\n");
  270. t_reply("404", "Not Found");
  271. exit;
  272. }
  273. }
  274. #
  275. if (isbflagset(10))
  276. setflag(10);
  277. #如果没有tag
  278. if(!has_totag() && is_method("INVITE")) {
  279. #隐藏拓扑
  280. topology_hiding();
  281. }
  282. replace_all("FreeSWITCH", "WMS");
  283. route(relay);
  284. }
  285. }
  286. onreply_route[r_add_trunk_info]{
  287. if($avp(trunk_group)){
  288. append_hf("X-trunk-name: $avp(trunk_group)\r\n");
  289. append_hf("X-calltype: callout\r\n");
  290. }
  291. if($avp(host)){
  292. append_hf("X-th: $avp(host)\r\n");
  293. }
  294. if($avp(outbound_tU)){
  295. append_hf("X-tu: $avp(outbound_tU)\r\n");
  296. }
  297. if($avp(x_r_rU)){
  298. append_hf("X-ru: $avp(x_r_rU)\r\n");
  299. }
  300. }
  301. route[r_fix_notify]{
  302. #request Uri username
  303. if (is_method("NOTIFY") && $rU==NULL) {
  304. $rU=$tU;
  305. }
  306. }
  307. route[r_options]{
  308. #内存超过10M,返回503提示
  309. if(is_method("OPTIONS")) {
  310. if ($stat(free_size) < 10240000) {
  311. sl_send_reply("503", "free_size_limit");
  312. } else {
  313. sl_send_reply("200", "ok");
  314. }
  315. exit();
  316. }
  317. }
  318. route[r_nat_uac_test]{
  319. #解决信令问题,符合1216情况,参考https://www.yuque.com/wangdd/opensips/olt40x
  320. if (nat_uac_test("19")) {
  321. if (is_method("REGISTER")) {
  322. fix_nated_register();
  323. setbflag(10);
  324. } else {
  325. # this function will cause ext cannot drop
  326. # fix_nated_contact();
  327. setflag(10);
  328. }
  329. }
  330. }
  331. route [r_fix_route_dialog] {
  332. #是否含有tag标签,是否是本地,是否属于以下方法
  333. if (has_totag() && is_myself("$rd") && is_method("INFO|INVITE|ACK|BYE|UPDATE|REFER")){
  334. #匹配现有对话
  335. if(match_dialog()){
  336. #会话存在且合法
  337. if ( $DLG_status!=NULL && !validate_dialog() ){
  338. #强制对话框,防止虚假注入的对话请求
  339. fix_route_dialog();
  340. }
  341. #发送请求
  342. t_relay();
  343. exit;
  344. }
  345. }
  346. }
  347. #判断数据跳过多
  348. route [r_max_fwd] {
  349. if (!mf_process_maxfwd_header("10")) {
  350. sl_send_reply("483","Too Many Hops");
  351. exit;
  352. }
  353. }
  354. route [r_relay_seq_request] {
  355. #是否有tag标签,并且不是notify请求
  356. if (has_totag() && !is_method("NOTIFY")) {
  357. #将所有WMS替换为FreeSwitch
  358. replace_all("FreeSWITCH", "WMS");
  359. #判断route请求是否丢失
  360. if (loose_route()) {
  361. xlog("L_INFO","r_relay_seq_request: $rm $ru enter loose route");
  362. if (is_method("INVITE")) {
  363. record_route();
  364. } else {
  365. t_relay();
  366. exit;
  367. }
  368. #检查route头是否与给定正则表达式匹配,判断nat是否开启,开启设置flag10
  369. if (check_route_param("nat=yes")){
  370. setflag(10);
  371. }
  372. #调用relay子路由
  373. route(relay);
  374. } else {
  375. #判断是否存在invite事务,且方法为ACKBYE,发送请求
  376. if(t_check_trans() && is_method("ACK|BYE")){
  377. t_relay();
  378. } else {
  379. exit;
  380. }
  381. sl_send_reply("404","Not here");
  382. }
  383. exit;
  384. }
  385. }
  386. #
  387. route[r_author_request_from_edge]{
  388. route(r_not_register_h5);
  389. #检查给定的IPPORT是否属于负载均衡器列表中配置的目标
  390. if(!lb_is_destination("$si","0","1")){
  391. if (!proxy_authorize("", "subscriber")) {
  392. xlog("$cfg_line-$cs $rm $fu->$tu start authorize\n");
  393. proxy_challenge("", "0");
  394. exit;
  395. }
  396. #Auth whole username
  397. if($aU =~'^gateway'){
  398. #删除认证头
  399. consume_credentials();
  400. if (!load_balance("1","trunk")) {
  401. xlog("L_ERR","load_balance:1,trunk is failed !!,exec sl_send_reply:500 Service full\n");
  402. sl_send_reply("500","Service full");
  403. exit;
  404. }
  405. record_route();
  406. t_relay();
  407. exit();
  408. }else{
  409. if (!db_check_from()) {
  410. sl_send_reply("403","Forbidden auth ID");
  411. exit;
  412. }
  413. consume_credentials();
  414. }
  415. }
  416. }
  417. route[r_did]{
  418. #对数据库进行查询赋值给三个数据
  419. avp_db_query("SELECT username,domain,select_fs_strategy FROM dbaliases WHERE alias_username='$rU'","$avp(t_username);$avp(t_domain);$avp(select_fs_strategy)");
  420. # is did number from edge
  421. #检查是否设置了t_username
  422. if(is_avp_set("$avp(t_username)")){
  423. # this will exit
  424. #赋值
  425. $avp(select_fs_strategy_hash) = $rU;
  426. $rU = $avp(t_username);
  427. xlog("find did corrt_username $avp(t_username) $avp(t_domain) $fu $tu ru=$ru\n");
  428. #$ru request uri设置该地址
  429. $ru = "sip:"+$avp(t_username) + "@" + $avp(t_domain) + ";transport="+ $pr;
  430. xlog("repair after: ru=$ru\n");
  431. $avp(from_ru) = "sip:"+ $fU + "@" + $avp(t_domain);
  432. $avp(to_ru) = "sip:"+ $tU + "@" + $avp(t_domain);
  433. xlog("from_ru=$avp(from_ru) to_ru=$avp(to_ru)\n");
  434. #替换from标头中的uri部分
  435. uac_replace_from("$fU" , "$avp(from_ru)");
  436. #替换to标头红的uri部分
  437. uac_replace_to("$tU" , "$avp(to_ru)");
  438. # ces user x-trunkgroup header to set calltype for inbound
  439. # so do't remove it
  440. #添加表头
  441. append_hf("X-trunk-name: $si\r\n");
  442. append_hf("X-calltype: callin\r\n");
  443. #记录返回地址
  444. record_route();
  445. if ($avp(select_fs_strategy) == "d") {
  446. # 3 meaning fs group
  447. # 7 hash over hash_pvar
  448. xlog("$cfg_line <r_did> $rm $fu->$tu selec fs use dispatcher\n");
  449. #dispatch查找组名中为3的地址
  450. if (!ds_select_dst("3","7")) {
  451. send_reply("502","Service Unavailable");
  452. exit;
  453. }
  454. t_relay();
  455. exit;
  456. }
  457. xlog("$cfg_line <r_did> $rm $fu->$tu selec fs use load_balance\n");
  458. #平衡配置
  459. if (!load_balance("1","trunk")) {
  460. xlog("L_ERR","load_balance:1,trunk is failed !!,exec sl_send_reply:500 Service full\n");
  461. sl_send_reply("500","Service full");
  462. exit;
  463. }
  464. t_relay();
  465. exit();
  466. }
  467. # invite from fs will continue route
  468. }
  469. route [r_register] {
  470. if (is_method("REGISTER")){
  471. #?
  472. route(r_register_h5);
  473. #认证auth_code
  474. $var(auth_code) = www_authorize("", "subscriber");
  475. if ( $var(auth_code) == -1 || $var(auth_code) == -2 ) {
  476. xlog("L_NOTICE","Auth error for $fU@$fd from $si cause $var(auth_code)\n");
  477. }
  478. if ( $var(auth_code) < 0 ) {
  479. www_challenge("", "0");
  480. exit;
  481. }
  482. #根据uri表检查数据库
  483. if (!db_check_to()) {
  484. xlog("exec sl_send_reply:403 Forbidden auth ID\n");
  485. sl_send_reply("403","Forbidden auth ID");
  486. exit;
  487. }
  488. #设置一个标签
  489. if ( $pr=="TCP" || 0 ) setflag(TCP_PERSISTENT);
  490. $avp(attr)="sip:"+$si+":"+$sp;
  491. #如果一个文件中存在邮箱present
  492. if(is_present_hf("X-Enable-Kickout")){
  493. #移除head from
  494. remove_hf("X-Enable-Kickout");
  495. #保存于location表中
  496. if (!save("location","p1vf")){
  497. xlog("exec sl_reply_error\n");
  498. sl_send_reply("503","too many registered");
  499. }
  500. }
  501. #如果过注册了来自某个AOR的联系人
  502. else if (is_contact_registered("location","$fu",,"$ci")) {
  503. xlog("[r_register] $fu is already, use force register");
  504. if (!save("location","p1vf")){
  505. sl_send_reply("503","failed");
  506. }
  507. }
  508. else{
  509. if (!save("location","p1v")){
  510. xlog("exec sl_reply_error\n");
  511. sl_send_reply("503","too many registered");
  512. }
  513. }
  514. #$fU ffrom URI username
  515. if($fU =~"^gateway"){
  516. xlog("gateway>> update , $ct.fields(uri) si=$si sp=$sp fu=$fu tu=$tu ru=$ru\n");
  517. $var(rw_uri)=$ct.fields(uri);
  518. $var(ipstr)=$(var(rw_uri){s.select,1,@});
  519. $avp(ctip)=$(var(ipstr){s.select,0,;});
  520. xlog("gateway>> SELECT id, rewrite_host FROM carrierroute WHERE uri_username='$fU' and uri_domain='$fd' and rewrite_host!='$avp(ctip)'\n");
  521. #数据库查询语句
  522. avp_db_query("SELECT id, rewrite_host FROM carrierroute WHERE uri_username='$fU' and uri_domain='$fd' and rewrite_host!='$avp(ctip)'","$avp(lid);$avp(old_rh)");
  523. xlog("gateway>> update $avp(ctip) fU=$fU uri_domain=$fd lid=$avp(lid), $var(old_rh)\n");
  524. #avp是否设置
  525. if(is_avp_set("$avp(lid)")){
  526. xlog("gateway>> update rewrite_host : $avp(old_rh) > $avp(ctip)\n");
  527. avp_db_query("update carrierroute set rewrite_host='$avp(ctip)' WHERE uri_username='$fU' and uri_domain='$fd' ");
  528. update_stat("wj:update_gateway_count", "+1");
  529. }
  530. }
  531. exit;
  532. }
  533. }
  534. route[r_do_limit] {
  535. #将当前对话框插入配置文件
  536. set_dlg_profile("domain","$param(1)");
  537. #返回属于配置文件的对话框数
  538. get_profile_size("domain","$param(1)","$var(domain)");
  539. xlog("L_INFO","r_do_limit: User $param(1) has $var(domain) ongoing calls so far, limit is $param(2)\n");
  540. # check within limit
  541. if( $var(domain)>$param(2) ) {
  542. xlog("L_WARN","do_limit: user $param(1) exceeded number of calls [$var(domain)/$param(2)]\n");
  543. sl_send_reply("487", "Request Terminated: Channel limit exceeded\n");
  544. exit;
  545. # terminating this call will automatically remove the call from the profile
  546. }
  547. # call was added to the profile without exceeding the limit, simply continue
  548. }
  549. route[r_query_route]{
  550. xlog("L_INFO","query route fU=$fU rd=$rd\n");
  551. $var(extNumber)="";
  552. $var(extRE)="^8[0-9]{3,7}$";
  553. if ($fU=~$var(extRE)) {
  554. $var(extNumber)=$fU;
  555. } else if ($tU=~$var(extRE)) {
  556. $var(extNumber)=$tU;
  557. # fix no condition transfer 302 aws vos
  558. #uac_replace_to("$tU" , "$rU");
  559. }
  560. if ($var(extNumber)) {
  561. avp_db_query("SELECT id,caller_id_dpid,callee_id_dpid,trunk_group FROM wj_v_exten_route WHERE username='$var(extNumber)' and domain='$rd'","$avp(r_id);$avp(caller_id_dpid);$avp(callee_id_dpid);$avp(trunk_group)");
  562. }
  563. # query ext route
  564. xlog("db_query_ext_route_result: $var(extNumber) $avp(r_id);$avp(caller_id_dpid);$avp(callee_id_dpid);$avp(trunk_group)\n");
  565. # query ext route by tu@t
  566. if(!is_avp_set("$avp(r_id)")){
  567. #对数据库进行查询
  568. avp_db_query("SELECT id,caller_id_dpid,callee_id_dpid,trunk_group FROM wj_v_domain_route WHERE domain='$rd'","$avp(r_id);$avp(caller_id_dpid);$avp(callee_id_dpid);$avp(trunk_group)");
  569. xlog("db_query_domain_route_result: $avp(r_id);$avp(caller_id_dpid);$avp(callee_id_dpid);$avp(trunk_group)\n");
  570. }
  571. xlog("db_query_route_result : $avp(r_id);$avp(caller_id_dpid);$avp(callee_id_dpid);$avp(trunk_group)\n");
  572. if(is_avp_set("$avp(r_id)")){
  573. $var(nto)="";
  574. $var(nfrom)="";
  575. # change to header
  576. if ($hdr(bindPhone)) {
  577. #将尝试根据拨号规则ID等于id的转换规则将src字符串转换为dest字符串
  578. dp_translate("$avp(callee_id_dpid)","$hdr(bindPhone)/$var(nto)");
  579. } else if ($tU=~$var(extRE)) {
  580. dp_translate("$avp(callee_id_dpid)", "$rU/$var(nto)");
  581. }else {
  582. dp_translate("$avp(callee_id_dpid)","$tU/$var(nto)");
  583. }
  584. xlog("$cfg_line-$cs $rm $fu->$tu in request nto=$var(nto)\n");
  585. if($var(nto)){
  586. $var(new_to) = "sip:"+ $var(nto) + "@" + $rd;
  587. $avp(outbound_tU) = $var(nto);
  588. xlog("$cfg_line-$cs $rm $fu->$tu in request outbound_tU=$avp(outbound_tU)\n");
  589. #uac_replace_to("$tU" , "$var(new_to)");
  590. }
  591. # change from header
  592. if ($hdr(displayOrigin)) {
  593. $var(nfrom)=$hdr(displayOrigin);
  594. } else {
  595. dp_translate("$avp(caller_id_dpid)","$fU/$var(nfrom)");
  596. }
  597. if($var(nfrom)){
  598. $var(new_uri) = "sip:" +$var(nfrom)+ "@" + $fd;
  599. #对fromuri进行替换
  600. uac_replace_from("$var(nfrom)" , "$var(new_uri)");
  601. }
  602. remove_hf("Remote-Party-ID");
  603. remove_hf("displayOrigin");
  604. remove_hf("bindPhone");
  605. }
  606. }
  607. route [r_set_edge_ip] {
  608. #该函数从类似于存储器高速缓存的存储系统中获取属性的值
  609. cache_fetch("local","cache_$avp(host)", $avp(edge));
  610. #是否判断函数是否存在
  611. if(is_avp_set("$avp(edge)")){
  612. xlog("L_INFO","cache_fetch find host $avp(host) $avp(edge), no need sql query");
  613. }else {
  614. xlog("L_INFO","cache_fetch host not find, need sql query");
  615. avp_db_query("SELECT edge_ip FROM carrierroute WHERE rewrite_host='$avp(host)' and edge_ip is not null order by rand() limit 1","$avp(edge)");
  616. }
  617. if(is_avp_set("$avp(edge)")){
  618. xlog("L_INFO","r_set_edge_ip $ci edge addr is $avp(edge)");
  619. cache_store("local","cache_$avp(host)", "$avp(edge)");
  620. if ($avp(edge)=~'^sip') {
  621. $du=$avp(edge);
  622. } else {
  623. # use dispatcher send to edge just for trunk
  624. xlog("L_INFO", "r_set_edge_ip $ci use dipatcher to select edge");
  625. if (!ds_select_dst("$avp(edge)","0")) {
  626. send_reply("502","Service Unavailable");
  627. cache_remove("loacal","cache_$avp(host)");
  628. exit;
  629. }
  630. }
  631. }
  632. else{
  633. avp_db_query("SELECT attr FROM location WHERE username='$fU' and domain='$td'","$avp(edge)");
  634. if(is_avp_set("$avp(edge)")){
  635. $du=$avp(edge);
  636. }else{
  637. xlog("L_ERR","$fU@$td is Not Registed!!\n");
  638. }
  639. }
  640. }
  641. route[r_ext_bind_phone]{
  642. $avp(transfer_num) = $hdr(bindPhone);
  643. if (!$avp(transfer_num)) {
  644. avp_db_query("SELECT bind_mobile,bind_mobile_type from subscriber WHERE username='$tU' and domain='$td'","$avp(transfer_num);$avp(bmt)");
  645. xlog("L_INFO","r_ext_bind_phone bind_mobile=$avp(transfer_num)\n");
  646. }
  647. if($avp(bmt)=="disabled"){
  648. $avp(transfer_num):="";
  649. }
  650. if($avp(transfer_num) != "" ){
  651. $du="sip:"+$si+":"+$sp;
  652. $ru="sip:"+$avp(transfer_num)+"@"+$Ri+":"+$Rp;
  653. sl_send_reply("302","LCR Redirect");
  654. exit;
  655. }
  656. }
  657. route[relay] {
  658. xlog("L_INFO","$cfg_line-$cs $rm $fu->$tu: enter route relay \n");
  659. replace_all("FreeSWITCH", "WMS");
  660. if(is_present_hf("Remote-Party-ID")){
  661. remove_hf("Remote-Party-ID");
  662. }
  663. if (is_method("INVITE")) {
  664. t_on_reply("handle_nat");
  665. t_on_failure("missed_call");
  666. }
  667. if (isflagset(10)) {
  668. add_rr_param(";nat=yes");
  669. }
  670. if ($avp(attr)) {
  671. $du=$avp(attr);
  672. xlog("L_INFO","$cfg_line-$cs $rm $fu->$tu: get edge address from attr\n");
  673. } else {
  674. xlog("L_INFO", "$cfg_line-$cs $rm $fu->$tu: get edge address from database\n");
  675. avp_db_query("SELECT attr FROM location WHERE username='$tU' and domain='$td'","$avp(edge)");
  676. if ($avp(edge)) {
  677. $du=$avp(edge);
  678. } else {
  679. xlog("$cfg_line-$cs $rm $fu->$tu: can not get edge address\n");
  680. }
  681. }
  682. if (!t_relay()) {
  683. xlog("send reply 500 Internal Error!\n");
  684. send_reply("500","Internal Error");
  685. };
  686. exit;
  687. }
  688. onreply_route[handle_nat] {
  689. route(r_delete_sip_header_to_ext);
  690. if($rs==302){
  691. remove_hf("contact");
  692. $var(movedNum)=$(ct.fields(uri){uri.user});
  693. $var(new_contact)=$var(movedNum)+"@"+"192.168.40.20:18627";
  694. append_hf("Contact: <sip:$var(new_contact)>\r\n", "Call-ID");
  695. exit;
  696. }
  697. }
  698. failure_route[missed_call] {
  699. if (t_was_cancelled()) {
  700. exit;
  701. }
  702. xlog("L_ERR","failure_route reply $(err.rcode) - $(err.rreason) -$(err.info) -$(err.class) \n");
  703. if (isflagset(12)) {
  704. xlog("L_ERR","t_reply: 503 Service not available, no more gateways\n");
  705. t_reply("503", "Service not available, no more gateways");
  706. exit;
  707. }
  708. }
  709. local_route {
  710. if (is_method("BYE") && $DLG_dir=="UPSTREAM") {
  711. #根据请求进行报告
  712. acc_db_request("200 Dialog Timeout", "acc");
  713. }
  714. }
  715. route [r_not_support] {
  716. if (is_method("PUBLISH|SUBSCRIBE")){
  717. sl_send_reply("503", "Service Unavailable");
  718. exit;
  719. }
  720. }
  721. #记录消息
  722. route[r_do_accounting] {
  723. $var(enableAcc)=0;
  724. if($var(enableAcc)){
  725. do_accounting("db|log", "cdr|missed");
  726. }
  727. }
  728. route[r_find_real_rU]{
  729. xlog("L_INFO","r_find_real_rU $avp(ru_strip)\n");
  730. $avp(ru_strip)=$(ru{uri.param,s});
  731. switch ($avp(ru_strip)) {
  732. case "1":
  733. $avp(x_r_rU)=$(avp(call_origin_rU){s.substr,1,0});
  734. break;
  735. case "2":
  736. $avp(x_r_rU)=$(avp(call_origin_rU){s.substr,2,0});
  737. break;
  738. case "3":
  739. $avp(x_r_rU)=$(avp(call_origin_rU){s.substr,3,0});
  740. break;
  741. case "4":
  742. $avp(x_r_rU)=$(avp(call_origin_rU){s.substr,4,0});
  743. break;
  744. case "5":
  745. $avp(x_r_rU)=$(avp(call_origin_rU){s.substr,5,0});
  746. break;
  747. case "6":
  748. $avp(x_r_rU)=$(avp(call_origin_rU){s.substr,6,0});
  749. break;
  750. case "7":
  751. $avp(x_r_rU)=$(avp(call_origin_rU){s.substr,7,0});
  752. break;
  753. case "8":
  754. $avp(x_r_rU)=$(avp(call_origin_rU){s.substr,8,0});
  755. break;
  756. case "9":
  757. $avp(x_r_rU)=$(avp(call_origin_rU){s.substr,9,0});
  758. break;
  759. default:
  760. xlog("strip $avp(ru_strip) it not support\n");
  761. }
  762. }
  763. timer_route[wj_cr_reload, 600]{
  764. if (0 && $stat(wj:update_gateway_count) > 0) {
  765. xlog("L_INFO", "update_gateway_count: $stat(wj:update_gateway_count)\n");
  766. #执行外部命令
  767. exec("opensipsctl fifo cr_reload_routes");
  768. $stat(wj:update_gateway_count) = 0;
  769. }
  770. }
  771. timer_route[r_influxdb_monitor, 5] {
  772. $var(db_url)="";
  773. if ($var(db_url)) {
  774. $var(reqbody)="opensips,type=core,ip=192.168.40.20 real_used_size=" + $stat(real_used_size)
  775. + ",active_dialogs=" + $stat(active_dialogs)
  776. + ",inuse_transactions=" + $stat(inuse_transactions)
  777. + ",waiting_udp=" + $stat(waiting_udp)
  778. + ",cps_all=" + $stat(wj:cps_all) + ",cps_trunk=" + $stat(wj:cps_trunk);
  779. $var(rc) = rest_post("","$var(reqbody)","text/plain","$var(body)","$var(ct)","$var(rcode)");
  780. if (!$var(rc)) {
  781. xlog("L_ERR", "write to influx db error, please check the influxdb url\n");
  782. }
  783. $stat(wj:cps_all) = 0;
  784. $stat(wj:cps_trunk) = 0;
  785. }
  786. }
  787. route [r_delete_sip_header_to_ext] {
  788. remove_hf("X-trunk-name");
  789. remove_hf("X-trunk-direction");
  790. remove_hf("X-calltype");
  791. remove_hf("X-th");
  792. remove_hf("X-ru");
  793. remove_hf("X-tu");
  794. remove_hf("Remote-Party-ID");
  795. }
  796. onreply_route[r_delete_trunk_info]{
  797. route(r_delete_sip_header_to_ext);
  798. }
  799. #对register表头进行记录
  800. route[r_siphub_capture]{
  801. if(!is_method("REGISTER") && !has_totag()){
  802. sip_trace("tid", "d", "sip");
  803. }
  804. }
  805. #使用
  806. route[r_register_h5]{
  807. #如果邮件中存在标头字段,则返回true &&名称和副名称
  808. if (is_present_hf("Authorization") && $hdr(Authorization)=~"^webview") {
  809. if ($hdr(Authorization) == "webview2020") {
  810. $avp(attr)="sip:"+$si+":"+$sp;
  811. #没有保存在本地
  812. if (!save("location","p1vf")){
  813. sl_send_reply("401","Auth h5 failed");
  814. }
  815. } else {
  816. sl_send_reply("401","Auth h5 failed");
  817. }
  818. exit;
  819. }
  820. }
  821. route[r_not_register_h5]{
  822. if (is_present_hf("Authorization") && $hdr(Authorization) == "webview2020") {
  823. remove_hf("Authorization");
  824. # hand invite
  825. if (is_method("INVITE") && has_body("application/sdp")){
  826. xlog("L_INFO", "$cfg_line enter h5 invite $ru");
  827. record_route();
  828. # go to fs
  829. if (!load_balance("1","trunk")) {
  830. xlog("L_INFO", "load_balance failed: check fs is ok\n");
  831. sl_send_reply("500","service full");
  832. exit;
  833. }
  834. t_relay();
  835. exit;
  836. }
  837. # hand message
  838. # todo
  839. else if (is_method("MESSAGE")) {
  840. xlog("L_INFO", "$cfg_line enter h5 message $ru");
  841. route(r_message);
  842. }
  843. exit;
  844. }
  845. }
  846. route[r_message]{
  847. xlog("$cfg_line $rm $fu $tu $rb \n");
  848. $avp(message_body) = $rb;
  849. avp_db_query("select contact,attr from location where username='$rU' AND domain='$rd'","$avp(i_contact);$avp(i_attr)");
  850. xlog("$rm $fU $tU db query result $avp(i_contact) $avp(i_attr) \n");
  851. if (!is_avp_set("$avp(i_contact)")) {
  852. route(r_save_msg_to_db, "404");
  853. xlog("$cfg_line $rm $fu $tu: status of lookup is $avp(sql_re) \n");
  854. t_reply("404", "Not Found");
  855. exit;
  856. }
  857. t_on_reply("r_save_msg_record");
  858. $ru=$avp(i_contact);
  859. $du=$avp(i_attr);
  860. if (!t_relay()) {
  861. send_reply("500","Internal Error");
  862. }
  863. exit;
  864. }
  865. onreply_route[r_save_msg_record]{
  866. route(r_save_msg_to_db, $rs);
  867. }
  868. route[r_save_msg_to_db]{
  869. $var(sip_callid) = $(ci{s.escape.common});
  870. $var(fs_callid) = $(hdr(fs_callid){s.escape.common});
  871. $var(fu) = $(fU{s.escape.common}) + "@" + $(fd{s.escape.common});
  872. $var(tu) = $(tU{s.escape.common}) + "@" + $(td{s.escape.common});
  873. $var(msg) = $(avp(message_body){s.escape.common});
  874. xlog("$var(sip_callid), $var(fs_callid), $var(fu), $var(tu), $var(msg)");
  875. avp_db_query("insert into message_record(sip_callid,fs_callid,time,fu,tu,status,msg) values('$var(sip_callid)','$var(fs_callid)',now(),'$var(fu)','$var(tu)','$param(1)','$var(msg)')");
  876. xlog("message insert db message_record result: $rc");
  877. }

1.is_from_local()判断是否来自domain表
2.t_check_trans()判断事务
3.t_on_relay和sl_send_reply,send_reply