惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
V
Vulnerabilities – Threatpost
GbyAI
GbyAI
P
Proofpoint News Feed
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
A
About on SuperTechFans
T
Tenable Blog
M
MIT News - Artificial intelligence
IT之家
IT之家
I
Intezer
D
DataBreaches.Net
爱范儿
爱范儿
T
Threatpost
C
CERT Recently Published Vulnerability Notes
云风的 BLOG
云风的 BLOG
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
K
Kaspersky official blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
Y
Y Combinator Blog
Cyberwarzone
Cyberwarzone
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
Spread Privacy
Spread Privacy
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
AWS News Blog
AWS News Blog
博客园 - 聂微东
C
Check Point Blog
S
Securelist
有赞技术团队
有赞技术团队
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
Last Week in AI
Last Week in AI
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
D
Docker
G
GRAHAM CLULEY
T
The Exploit Database - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tailwind CSS Blog
L
Lohrmann on Cybersecurity
G
Google Developers Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LangChain Blog

博客园 - uu.Net

修改originate使chan_ss7信令传递原被叫 chan_ss7中原被叫号码的传递 oracle循环插入数据用于测试 ORA-12154: TNS: 无法解析指定的连接标识符 使用windows route命令来控制双网卡,双网络访问 JVM优化引起的逻辑错误 box & unbox scribefIre试用手记 mysql长连接和短连接的问题 tomcat入门 Tomcat5部署 logrotate---日志轮转 关于gcc的include问题 Centos 时间同步 How to create a gun c/c++ project modules的管理 - uu.Net asterisk上加载G729 codec - uu.Net MySQL C API的一次调用体验 - uu.Net FTP的主动和被动模式 - uu.Net
chan_ss7源码分析
uu.Net · 2012-12-27 · via 博客园 - uu.Net

最近在项目中使用了chan_ss7进行中国7号信令的接入,由于在接入过程中,遇到一些问题,需要对源代码进行分析,以解决遇到的问题。下面先对chan_ss7进行逻辑分析。
与OSI7层模型类似,在SS7中,也是按照层次来进行组织的,从底到上依次是MTP1,MTP2,MTP3,ISUP/TUP/SCCP。MTP层主要保证用户层数据(TUP/ISUP)的可靠端到端传输。在chan_ss7中对ISUP进行了较好的支持,对于TUP目前还没有支持,国内的开源通信(openvox)对这部分进行了扩展,增加了支持。这里是以ISUP为例来说明。
chan_ss7编译后,是以一个channel模块加载到asterisk中的。在chan_ss7中采用了asterisk较为常见的do_monitor线程对收到的消息进行处理。另外,还有一个MTP线程来负责接收MTP消息。为了避免死锁问题,这两个线程之间使用了一个receivedbuf进行中转。
MTP线程接收到来自MTP层的数据后,将消息封装成evet,然后通过mtp_put函数,将event送入到receivedbuf中,然后再通过alert pipe方式通知do_monitor线程有新消息到来需要处理。
在do_monitor线程中,从receivedbuf中逐个取出消息,然后按照消息的类型不同,分别进行处理。
消息的处理过程,以ISUP消息为例,
对于ISUP消息,首先会通过chan_ss7.c中的process_event函数,根据消息类型,转到l4isup_event中。在l4isup_event中,首先对event进行解码,解析出isup消息,然后根据isup消息中的cic查找到对应的pvt结构,然后到process_isup_message根据消息的类型的不同,调用对应的handler进行处理。
在process_isup_message中,根据msg的typ取值不同,向process_circuit_message传入不同的函数指针,以完成handler的抽象,进行调用。
在process_circuit_message中,调用具体的handler之前,要完成几个锁的访问问题,一个是global锁,一个是pvt的锁,一个是channel的锁。这三个锁的访问顺序,是需要仔细注意的,加锁的顺序必须是global->channel->pvt。加锁完成后,是对应的handler的调用。处理结束后,释放锁,处理结束。
我的问题:在处理高并发、长呼叫的时候,有些呼入的长呼叫没有正常挂机。如果被叫不主动挂机,主叫会一直在。并且,此时,所有的呼入/呼出信令全部被阻塞,整个ISUP层不会再接续处理。
分析:通过上面的执行过程分析来看,消息的处理过程是在do_monitor线程中进行的。如果在处理某个消息的时候,出现死锁问题,该线程将不会返回,直到死锁条件解除。特别是在process_circuit_message函数中,需要对三个锁进行分别处理,极容易引入锁死。
跟踪:在实际测试中,对process_circuit_message进行了跟踪,发现死锁问题是在ast_channel_lock的时候引起的,此时,通过CHECK_BLOCKING这个宏判断看,原来是在ast_write。通道线程在往线程中写数据的时候。
进一步分析:作为asterisk中较为核心的channel.c,我坚信不会存在死锁的问题。既然问题是在ast_write函数中,那么产生的根源应该是在ss7_write函数中。在这个函数中,直接调用了write函数,对话路那个通道直接写入语音数据。经过做log测试,看出,发生死锁的时候,是从write函数中没有返回。此处的write函数是同步的写,必须等待写结束后,才进行返回。问题的根源应该是在这里。
解决方法:既然问题已经找到了,那么该如何解决?
1.为了避免整个ISUP层被堵塞,应该避免死锁的发生。起初的判断是将处理过程process_circuit_message放到一个独立的线程中去执行。由于这里有个global锁,多线程实际上被串行执行了,没有多少意义。在process_circuit_message进行channel锁的时候,使用trylock,多检测几次,如果仍然没有锁住channel,则对本次消息,不予处理。等待下次重传的消息。
2.即便是处理重传,但是在实际中会一直出现锁在ast_write中。除非被叫端挂机,否则该通道一直会被占用。为了避免这种情况的发生,在1基础之上,对于拆线等事件,如果发现trylock失败,转而让bridged通道去挂机。对于这种方案,目前还没有进行测试。