Review Board 1.7.16


fix Deadlock with attended transfers of SIP calls

Review Request #1126 - Created Feb. 23, 2011 and submitted

Alec Davis
trunk
18468, 18491, 18734, 18837
Reviewers
asterisk-dev
Asterisk
in 1.8.2.3 and prior to trunk r306216, when the REFER transfer is complete then a deadlock occurs.

Reason being sip_set_rtp_peer locks pvt, then pbx_builtin_getvar_helper tries to lock chan
Violating locking order.
 
=== Thread ID: -1292625008 (do_monitor started at [24470] chan_sip.c restart_monitor())
=== ---> Lock #0 (chan_sip.c): MUTEX 23964 handle_request_do &netlock 0xb6796e80 (1)
=== ---> Lock #1 (channel.c): MUTEX 6211 ast_do_masquerade channels 0x8d4e0c8 (1)
=== ---> Lock #2 (channel.c): MUTEX 6214 ast_do_masquerade original 0xbd98f48 (1)
=== ---> Lock #3 (channel.c): MUTEX 6234 ast_do_masquerade clonechan 0xb24bf7d0 (1)
=== ---> Waiting for Lock #4 (chan_sip.c): MUTEX 6164 sip_fixup p 0xb24bab10 (1)
=== --- ---> Locked Here: chan_sip.c line 27632 (sip_set_rtp_peer)

=== -------------------------------------------------------------------
===
=== Thread ID: -1315861616 (pbx_thread started at [ 5035] pbx.c ast_pbx_start())
=== ---> Lock #0 (chan_sip.c): MUTEX 27632 sip_set_rtp_peer p 0xb24bab10 (1)
=== ---> Waiting for Lock #1 (pbx.c): MUTEX 9467 pbx_builtin_getvar_helper chan 0xb24bf7d0 (1)
=== --- ---> Locked Here: channel.c line 6234 (ast_do_masquerade)

multiple other bug reports reveal the sip_set_rtp_peer pvt locking issue.

Solution:
  inc pvt refcount to prevent the possibility of it disappearing while unlocked.
  unlock the pvt
    call transmit_reinvite_with_sdp (which finishes up invoking pbx_builtin_getvar_helper)
  lock the pvt
  dec pvt refcount

Applies to 1.8.2.3 and trunk. Both verified deadlocks.
Presumably 1.8 branch

r306216 tries to solve it, but causes more channel locking issues 
see https://issues.asterisk.org/view.php?id=18837#132337
Testing: trunk

3 SIP phones.

A calls B, and B answers on line 1.
B puts A on hold by selecting line2.
B calls C, and C answers.
B initiates transfer of line1 to line2, phone uses REFER.

Changes between revision 2 and 3

1 2 3
1 2 3

  1. trunk/channels/chan_sip.c: Loading...
trunk/channels/chan_sip.c
Diff Revision 2 Diff Revision 3
[20] 27995 lines
[+20] [+] static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl)
27996
			ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
27996
			ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
27997
		}
27997
		}
27998
	}
27998
	}
27999
	/* Reset lastrtprx timer */
27999
	/* Reset lastrtprx timer */
28000
	p->lastrtprx = p->lastrtptx = time(NULL);
28000
	p->lastrtprx = p->lastrtptx = time(NULL);
28001
	ast_channel_trylock(p->owner);
28001
	ast_channel_unlock(p->owner);
28002
	sip_pvt_unlock(p);
28002
	sip_pvt_unlock(p);
28003
	return 0;
28003
	return 0;
28004
}
28004
}
28005

    
   
28005

   
28006
static enum ast_rtp_glue_result sip_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
28006
static enum ast_rtp_glue_result sip_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
[+20] [20] 1475 lines
  1. trunk/channels/chan_sip.c: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.