pjsip_distributor.c: Fix deadlock with TCP type transports.
authorRichard Mudgett <rmudgett@digium.com>
Thu, 29 Jun 2017 23:27:20 +0000 (18:27 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 30 Jun 2017 18:04:37 +0000 (13:04 -0500)
commitb485f6c59c5ffcbb2d7f1fe501c9db44add68bab
tree454cf727f2f4c87f6f0cd6944c6911d8aafb490f
parente1c0e14fac7cdca276a0fd61fa891ea54f4ab5d8
pjsip_distributor.c: Fix deadlock with TCP type transports.

When a SIP message comes in on a transport, pjproject obtains the lock on
the transport and pulls the data out of the socket.  Unlike UDP, the TCP
transport does not allow concurrent access.  Without concurrency the
transport lock is not released when the transport's message complete
callback is called.  The processing continues and eventually Asterisk
starts processing the SIP message.  The first thing Asterisk tries to do
is determine the associated dialog of the message to determine the
associated serializer.  To get the associated serializer safely requires
us to get the dialog lock.

To send a request or response message for a dialog, pjproject obtains the
dialog lock and then obtains the transport lock.  Deadlock can result
because of the opposite order the locks are obtained.

* Fix the deadlock by obtaining the serializer associated with the dialog
another way that doesn't involve obtaining the dialog lock.  In this case,
we use an ao2 container to hold the associated endpoint and serializer.
The new locks are held a brief time and won't overlap other existing lock
times.

ASTERISK-27090 #close

Change-Id: I9ed63f4da9649e9db6ed4be29c360968917a89bd
res/res_pjsip/pjsip_distributor.c