Fix a small race condition in sip_tcp_locate().
authorRussell Bryant <russell@russellbryant.com>
Fri, 12 Dec 2008 18:33:27 +0000 (18:33 +0000)
committerRussell Bryant <russell@russellbryant.com>
Fri, 12 Dec 2008 18:33:27 +0000 (18:33 +0000)
We must increase the reference count on the tcptls_session _before_ unlocking
the thread list.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@163667 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c

index 83f5d49..f81c292 100644 (file)
@@ -20326,22 +20326,28 @@ static int sip_standard_port(enum sip_transport type, int port)
                return port == STANDARD_SIP_PORT;
 }
 
-/*! \todo Find thread for TCP/TLS session (based on IP/Port */
+/*! 
+ * \brief Find thread for TCP/TLS session (based on IP/Port 
+ *
+ * \note This function returns an astobj2 reference
+ */
 static struct ast_tcptls_session_instance *sip_tcp_locate(struct sockaddr_in *s)
 {
        struct sip_threadinfo *th;
+       struct ast_tcptls_session_instance *tcptls_instance = NULL;
 
        AST_LIST_LOCK(&threadl);
        AST_LIST_TRAVERSE(&threadl, th, list) {
                if ((s->sin_family == th->ser->remote_address.sin_family) &&
                        (s->sin_addr.s_addr == th->ser->remote_address.sin_addr.s_addr) &&
                        (s->sin_port == th->ser->remote_address.sin_port))  {
-                               AST_LIST_UNLOCK(&threadl);
-                               return th->ser;
+                               tcptls_instance = (ao2_ref(th->ser, +1), th->ser);
+                               break;
                        }
        }
        AST_LIST_UNLOCK(&threadl);
-       return NULL;
+
+       return tcptls_instance;
 }
 
 /*! \todo Get socket for dialog, prepare if needed, and return file handle  */
@@ -20378,7 +20384,6 @@ static int sip_prepare_socket(struct sip_pvt *p)
                        ao2_ref(s->ser, -1);
                        s->ser = NULL;
                }
-               ao2_ref(ser, +1);
                s->ser = ser;
                return s->fd;
        }