summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2015-11-13 14:32:10 -0600
committerRichard Mudgett <rmudgett@digium.com>2015-11-13 16:34:41 -0500
commit436023a3225e7902178d7e619c20fd7b9f393926 (patch)
treea0f34e6a8acbb8c4610c7688afde76d03eec87fd
parente8881e177046422690d2e87417a93b253469c379 (diff)
res_pjsip_rfc3326.c: Fix crash when channel goes away.
If an authenticated incoming caller does not respond to our 200 OK INVITE response with an ACK then PJSIP will hangup the call. Unfortunately, there is a chance that the session's channel will go away between one use of the channel pointer and another when building the BYE request because the BYE is being built by the monitor thread and not the call's serializer thread. * Added a check to ensure that the thread trying to add the Reason header is the call's serializer thread. This ensures that the channel will not go away on us. Change-Id: I866388d2b97ea2032eaae3f3ab3f1ca6cbd2df89
-rw-r--r--res/res_pjsip_rfc3326.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/res/res_pjsip_rfc3326.c b/res/res_pjsip_rfc3326.c
index 6eb27ffe2..d49a170d3 100644
--- a/res/res_pjsip_rfc3326.c
+++ b/res/res_pjsip_rfc3326.c
@@ -32,6 +32,7 @@
#include "asterisk/res_pjsip_session.h"
#include "asterisk/module.h"
#include "asterisk/causes.h"
+#include "asterisk/threadpool.h"
static void rfc3326_use_reason_header(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
{
@@ -101,9 +102,15 @@ static void rfc3326_add_reason_header(struct ast_sip_session *session, struct pj
static void rfc3326_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
{
- if ((pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_bye_method) &&
- pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_cancel_method)) ||
- !session->channel) {
+ if ((pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_bye_method)
+ && pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_cancel_method))
+ || !session->channel
+ /*
+ * The session->channel has been seen to go away on us between
+ * checks so we must also be running under the call's serializer
+ * thread.
+ */
+ || session->serializer != ast_threadpool_serializer_get_current()) {
return;
}
@@ -114,7 +121,9 @@ static void rfc3326_outgoing_response(struct ast_sip_session *session, struct pj
{
struct pjsip_status_line status = tdata->msg->line.status;
- if ((status.code < 300) || !session->channel) {
+ if (status.code < 300
+ || !session->channel
+ || session->serializer != ast_threadpool_serializer_get_current()) {
return;
}