Search the Asterisk Blog

The Case Of The Misunderstood PJSIP Callback

By Joshua Colp

When the PJSIP work for Asterisk began one of the primary concerns kept in mind was that it be extensible. One of the APIs derived from this concern was session supplements. Session supplements are a way for modules to add themselves in to the handling of SIP messages for sessions (or calls as you may know them). They are invoked on incoming and outgoing messages and allow modules to do anything to the session or channel involved. In the case of outgoing messages they can also modify the message.

A prime example of this is PJSIP caller ID support. The caller ID module (res_pjsip_caller_id) uses a session supplement to handle both incoming and outgoing messages. For incoming messages it examines the SIP message and extracts the caller ID information from it. For outgoing messages it modifies the message to contain the caller ID information. No changes to res_pjsip or res_pjsip_session were required to support this.

You can see what the interface for session supplements looks like by examining the implementation for caller ID.

For this blog post we will focus on the callback for outgoing_request. This callback is invoked when a SIP request is sent as a result of the ast_sip_session_send_request function being called and, until recently, as a result of a callback from PJSIP informing us there is an outgoing message. This PJSIP callback no longer invokes outgoing_request as the original meaning of the PJSIP callback was misunderstood.

Let’s take a gander at some of our original PJSIP callback implementation.

This function is called by PJSIP when a state change occurs and it provides information about why the state changed in the event. The event type that used to invoke outgoing_request is PJSIP_EVENT_TX_MSG. On an initial read you might think that this is called when an outgoing message is about to be sent. You would be incorrect. As found when doing testing of Asterisk internally depending on timing this could be called when an outgoing message is about to be sent, in the process of being sent or has been sent.

Why is this bad?

The outgoing_request callback is supposed to provide a contract that the message is safe to modify before it is sent. Invocation as a result of PJSIP_EVENT_TX_MSG could not provide this guarantee. What is even worse is that the PJSIP process of sending modifies the message. If this occurred while a session supplement was doing the same they would both clash. This is not safe and could cause memory corruption resulting in a crash as seen during our testing.

This problem has been resolved by simply removing the code that invokes the outgoing_request on session supplements as a result of PJSIP_EVENT_TX_MSG. Since we already do it before passing the message to PJSIP we guarantee that it is safe to do so and that no clash will occur between PJSIP and the session supplement.

No Comments Yet

Get the conversation started!

Add to the Discussion

Your email address will not be published. Required fields are marked *

About the Author

Joshua Colp

Joshua Colp is a Senior Software Developer at Digium and a long time Asterisk developer. He originally started in the community submitting simple patches and grew into improving and creating new core components of Asterisk itself. He is a self-taught programmer who believes in finding the balance between doing things the way they should be done and doing what is right for the people using the software. In his spare time he enjoys smashing fax machines.

See All of Joshua's Articles

More From
The Digium Blog

  • No items