广告 《大道至简,给所有人看的编程课》 🔥

《FreeSWITCH参考手册》

1.3 mod_blacklist

前几天有网友问黑名单怎么做,我说自己写个Lua脚本查数据库吧。后来又查了一下,FreeSWITCH竟然有一个mod_blacklist,这不就是黑名单嘛。

说实话我以前从来没注意过这个模块。遇到一个新模块怎么办呢?当然是查FreeSWITCH的Wiki。那如果Wiki上也没有呢?Wiki上一般都会有,如果没有的话,也不怕,下面,我就带大家在不看Wiki的情况下如何了解一个模块。

当然,这个模块比较简单。首先,这个模块默认是不编译的,要手动编译

$ cd src/mod/applications/mod_blacklist
$ make install

然后,就可以在FreeSWITCH里加载模块了:

freeswitch> load mod_blacklist

显示日志如下:

2016-04-28 09:12:29.508192 [CONSOLE] switch_loadable_module.c:1538 Successfully Loaded mod_blacklist]
2016-04-28 09:12:29.508192 [NOTICE] switch_loadable_module.c:338 Adding API Function 'blacklist'

从日志中可以看出,该模块好像仅实现了一个API: blacklist

直接输入这个命令试下

freeswitch@seven.local> blacklist
2016-04-28 16:53:23.913138 [ERR] mod_blacklist.c:182 Invalid usage

出错啦,继续试:

freeswitch@seven.local> blacklist test

-ERR: No such command: test (see 'blacklist help')

有门,继续:

freeswitch@seven.local> blacklist help

blacklist check <listname> <item>
blacklist add <listname> <item>
blacklist del <listname> <item>
blacklist save <listname>
blacklist reload
blacklist help
+OK

从命令行中看,它好像支持多个列表(listname),每个列表中都有相关的条目(item)。看配置文件,blacklist.conf.xml里有这么一行:

<list name="example" filename="$${conf_dir}/blacklists/example.list"/>

创建 /usr/local/freeswitch/conf/blacklists/example.list

里面的内容怎么写呢?不知道,蒙一把,输入

1000
1001

就是把电话号码每个一行。至于蒙的对不对,实际上可以看源代码的。在源代码中,有一个load_list()函数,看样子是用于加载这个列表的,主要内容如下:

while (fgets(buf, 1024, f)) {
    trim(buf);
    switch_core_hash_insert(bl->list, buf, (void *)SWITCH_TRUE);
}

很明显,它加从文件中依次读取每一行,然后插入一个内容哈希表中。看样子我们蒙的还比较靠谱。

重新加载一下模块:

freeswitch@seven.local> reload mod_blacklist

2016-04-28 15:09:18.868148 [INFO] mod_blacklist.c:104 Loaded list [example]
2016-04-28 15:09:18.868148 [CONSOLE] switch_loadable_module.c:1538 Successfully Loaded mod_blacklist]

哈哈,Loaded list [example] 显示名为 example 的列表已经加载了。试试检查(check)命令

freeswitch@seven.local> blacklist check example 1000

true
freeswitch@seven.local> blacklist check example 1001

true
freeswitch@seven.local> blacklist check example 1002

false

由于1002不在列表中,返回了false

看看能不能手工加

freeswitch@seven.local> blacklist add example 1002

+OK

2016-04-28 16:54:02.593169 [INFO] mod_blacklist.c:228 Added [1002] to list [example]
freeswitch@seven.local> blacklist check example 1002

true

这次是true了。试试save命令:

freeswitch@seven.local> blacklist save example
2016-04-28 16:54:17.973176 [INFO] mod_blacklist.c:280 Saving example to /usr/local/freeswitch/conf/blacklists/example.list

+OK

$ cat /usr/local/freeswitch/conf/blacklists/example.list

1000
1002
1001

可以看到1002已经加到列表里了。但由于内部实现是哈希表,没有排序,因次并没有特定的次序。

好了,但在实际打电话时怎么用呢?

创建如下Dialplan,这个例子来自FreeSWITCH的Wiki

<extension name="blacklist_check">
    <condition field="${blacklist(check example ${destination_number})}" expression="^true$">
        <action application="bridge" data="sofia/external/sip:lenny@sip.itslenny.com:5060"/>
    </condition>
</extension>

上面的意思是说,测试条件是一个动态条件,该动态条件是由blacklist check listname item完成的。上面的例子测试了被叫号码(destination_number)是否在黑名单,若否则继续呼。

我们再来个稍复杂点的例子:

<extension name="echo">
    <condition field="destination_number" expression="^9196$">
    <condition field="${blacklist(check example ${caller_id_number})}" expression=“^true$">
<action application="answer"/>
    <action application="echo"/>
    </condition>
    </condition>
</extension>

其实很简单,我们只不过是在默认的9196基础上增加了一层blacklist的判断。如果主叫号码是一个不在名单中的号码,则匹配失败,呼叫失败,打印日志如下:

    Dialplan: sofia/internal/1004@192.168.7.6 Regex (PASS) [echo] destination_number(9196) =~ /^9196$/ break=on-false
    |--- Dialplan: Processing recursive conditions level:1 [echo_recur_1] require-nested=TRUE
    |--- Dialplan: sofia/internal/1004@192.168.7.6 Regex (FAIL) [echo_recur_1] ${blacklist(check example ${caller_id_number})}(false) =~ /^true$/ break=on-false

如果是在名单中的号码,则呼叫成功,日志显示如下:

    Dialplan: sofia/internal/1000@192.168.7.6 Regex (PASS) [echo] destination_number(9196) =~ /^9196$/ break=on-false
    |--- Dialplan: Processing recursive conditions level:1 [echo_recur_1] require-nested=TRUE
    |--- Dialplan: sofia/internal/1000@192.168.7.6 Regex (PASS) [echo_recur_1] ${blacklist(check example ${caller_id_number})}(true) =~ /^true$/ break=on-false
    |--- Dialplan: sofia/internal/1000@192.168.7.6 Action answer()
    |--- Dialplan: sofia/internal/1000@192.168.7.6 Action echo()

读到这里,细心的读者可能会问:你上面说错了吧?明明上面的逻辑是白名单……,呵呵,是的,天使跟恶魔只是一念之差,你也可以用黑名单来做白名单 ;)。当然,如果你确实需要黑名单,试试把上面的true改成false就行了,这个,留给读者自己练习吧?



本书版权所有 © 杜金房及各位贡献者 2016-2023,仅供在线阅读,谢绝一切形式转载。 本书还在写作中,持续更新。 如果你也想写上几句,欢迎加入我们。 | 返回首页 |