Chan_ss7 source code analysis

Source: Internet
Author: User

Recently, chan_ss7 was used in the project to access China's no. 7 signaling. Due to some problems encountered during the access process, the source code needs to be analyzed to solve the problems encountered. The following describes the logic analysis of chan_ss7.
Similar to the osi7 layer model, SS7 is organized by layer. The bottom-to-top models are mtp1, mtp2, mtp3, ISUP, Tup, and SCCP. The MTP layer ensures reliable end-to-end transmission of user-layer data (Tup/ISUP. ISUP is well supported in chan_ss7, and Tup is not yet supported. openvox in China has extended this part and added support. ISUP is used as an example.
After chan_ss7 is compiled, it is loaded into Asterisk as a channel module. In chan_ss7, the common do_monitor thread of Asterisk is used to process received messages. In addition, there is an MTP thread to receive MTP messages. To avoid the deadlock problem, a receivedbuf is used between the two threads.
After receiving data from the MTP layer, the MTP thread encapsulates the message into evet, and then sends the event to the receivedbuf through the mtp_put function, then, use the alert pipe method to notify the do_monitor thread that a new message needs to be processed.
In the do_monitor thread, messages are retrieved one by one from the receivedbuf, and processed separately according to different message types.
The process of message processing. Take the ISUP message as an example,
For an ISUP message, it is first transferred to l4isup_event Based on the Message Type through the process_event function in chan_ss7.c. In l4isup_event, first decode the event, parse the ISUP message, find the corresponding PVT structure based on the CIC in the ISUP message, and then go to process_isup_message Based on the message type, call the corresponding handler for processing.
In process_isup_message, different function pointers are passed to process_circuit_message Based on the typ value of MSG to complete handler abstraction and call.
In process_circuit_message, before calling a specific handler, you need to complete several lock access problems. One is the global lock, the other is the PVT lock, and the other is the channel lock. The access sequence of these three locks requires careful attention. The locking sequence must be global-> channel-> PVT. After the lock is completed, it is called by the corresponding handler. After the processing is complete, release the lock and the processing is complete.
My problem: when handling highly concurrent and long calls, some incoming long calls are not properly mounted. If the caller is not active, the caller will remain. In addition, all incoming/outgoing call signals are blocked, and the entire ISUP layer will not be processed.
Analysis: according to the above execution process analysis, the message processing process is performed in the do_monitor thread. If a deadlock occurs when processing a message, the thread will not return until the deadlock condition is lifted. Especially in the process_circuit_message function, three locks need to be processed separately, which is easy to introduce locking.
Tracking: in the actual test, process_circuit_message was tracked and the deadlock problem was found to be caused by ast_channel_lock. At this time, the macro check_blocking was used to judge that it was originally in ast_write. When the channel thread writes data to the thread.
Further analysis: as the core channel. c In asterisk, I firmly believe that there will be no deadlock issues. Since the problem is in the ast_write function, the root cause should be in the ss7_write function. In this function, the write function is called directly, and the channel of the conversation Path Directly writes speech data. After the log test, we can see that when a deadlock occurs, it is not returned from the write function. The Write function is a synchronous write function. It must be returned after the write is completed. The root cause of the problem should be here.
Solution: since the problem has been found, how can this problem be solved?
1. To prevent the entire ISUP layer from being congested, the deadlock should be avoided. The initial judgment is to put process_circuit_message in an independent thread for execution. Since there is a global lock, multithreading is actually executed in a serial mode, which makes little sense. When process_circuit_message is used for Channel lock, trylock is used for multiple times. If the channel is still not locked, this message will not be processed. The message waiting for the next retransmission.
2. Even if retransmission is processed, the lock will always appear in ast_write. Unless the called end is suspended, the channel will be occupied all the time. In order to avoid this situation, on the basis of 1, for events such as Wire Breaking, if trylock fails, the bridged channel will be suspended. This solution has not been tested yet.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.