?
概述
freeswitch是一款簡單好用的VOIP開源軟交換平臺。
mod_xml_curl模塊支持從web服務獲取xml配置,本文介紹如何動態獲取acl配置。
環境
centos:CentOS? release 7.0 (Final)或以上版本
freeswitch:v1.6.20
GCC:4.8.5
web服務
mod_xml_curl模塊依賴于web服務,需要自己創建一個web接口并動態的返回xml配置。
下面是python3.10實現的一個簡單的web服務接口函數,從基類“BaseHTTPRequestHandler”繼承并實現簡單的返回邏輯。
??? def fsDialplan(self):
??????? length = int(self.headers['content-length'])?
??????? datas = self.rfile.read(length)
??????? logging.info('/fs/dialplan request, data=%s' % urllib.parse.unquote(datas))
??????? respcode = '''<document type="freeswitch/xml">
<section name="dialplan" description="dialplan-url">
??? <include>
??????? <context name="public">
??????????? <extension name="test-url" continue="false">
??????????????? <condition field="${acl(${network_addr} list_out)}" expression="true"/>
??????????????? <condition field="destination_number" expression="^(\d+)$">
?????????? ?????????<action application="answer"/>
??????????????????? <action application="playback" data="/usr/local/freeswitch/sounds/dialplan-test-url.wav"/>
??????????????? </condition>
??????????? </extension>
??????? </context>
??? </include>
</section>
</document>
'''
??????? self.send_response(200)
??????? self.send_header('Content-Type', 'application;charset=utf-8')
??????? self.end_headers()
??????? self.wfile.write(respcode.encode('utf-8'))
??????? return
???
??? def fsConfigAcl(self):
??????? length = int(self.headers['content-length'])?
??????? datas = self.rfile.read(length)
??????? # print('fsConfigAcl request, data=', datas.decode())
??????? logging.info('/fs/config/acl request, data=%s' % urllib.parse.unquote(datas))
??????? respcode = '''<document type="freeswitch/xml">
<section name="configuration" description="config-acl">
<configuration name="acl.conf" description="Network Lists">
? <network-lists>
??? <list name="list_out" default="deny">
????? <node type="allow" cidr="10.55.55.138/32"/>
??? </list>
? </network-lists>
</configuration>
</section>
</document>
'''
??????? self.send_response(200)
??????? self.send_header('Content-Type', 'application;charset=utf-8')
??????? self.end_headers()
??????? self.wfile.write(respcode.encode('utf-8'))
??????? return
web服務響應消息格式注意事項,必須有“section”段,xml格式不能使用壓縮格式,否則會解析錯誤。
fsDialplan函數的響應中增加了acl的條件判斷。
fsConfigAcl函數響應添加“list_out”的acl規則。
配置
檢查conf/autoload_configs/modules.conf.xml文件,mod_xml_curl模塊要放在配置的頂部。
??? <load module="mod_console"/>
<load module="mod_logfile"/>
<load module="mod_xml_curl"/>
修改conf/autoload_configs/xml_curl.conf.xml文件。
<configuration name="xml_curl.conf" description="cURL XML Gateway">
? <bindings>
??? <binding name="dialplan">
????? <param name="gateway-url" value="http://10.55.55.137:8080/fs/dialplan" bindings="dialplan"/>
</binding>
<binding name="configuration">
<param name="gateway-url" value="http://10.9.0.27:8080/fs/config-acl" bindings="configuration"/>
</binding>
? </bindings>
</configuration>
測試
configuration動態配置需要刷新生效。
freeswitch@localhost.localdomain> reloadacl
+OK acl reloaded
2023-08-04 10:37:59.117939 [NOTICE] switch_utils.c:545 Adding 10.55.55.138/32 (allow) [] to list list_out
使用10011發起呼叫,日志如下。
2023-08-04 10:38:05.277908 [INFO] mod_dialplan_xml.c:637 Processing 10011 <10011>->13712345678 in context public
Dialplan: sofia/external/10011@10.55.55.138 parsing [public->test-url] continue=false
Dialplan: sofia/external/10011@10.55.55.138 Regex (PASS) [test-url] ${acl(${network_addr} list_out)}(true) =~ /true/ break=on-false
Dialplan: sofia/external/10011@10.55.55.138 Regex (PASS) [test-url] destination_number(13712345678) =~ /^(\d+)$/ break=on-false
Dialplan: sofia/external/10011@10.55.55.138 Action answer()
Dialplan: sofia/external/10011@10.55.55.138 Action playback(/usr/local/freeswitch/sounds/dialplan-test-url.wav)
呼叫結果符合預期。
總結
mod_xml_curl模塊動態獲取config數據,方便對批量的fs集中統一管理配置。
未解決問題。
configuration類型的配置數據動態刷新的邊界在哪里,我們可以把哪些配置數據放在web服務統一管理。
如何解決web服務不可用的本地xml配置問題,本地xml配置與web動態配置不一致的問題。
空空如常
求真得真