<p>sungtae kim has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/10617">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip: Patch for res_pjsip_* module load/reload crash<br><br>The session_supplements for the pjsip makes crashes when the module<br>load/unload.<br><br>ASTERISK-28157<br><br>Change-Id: I5b82be3a75d702cf1933d8d1417f44aa10ad1029<br>---<br>M include/asterisk/res_pjsip_session.h<br>M res/res_pjsip/pjsip_session.c<br>M res/res_pjsip_session.c<br>3 files changed, 306 insertions(+), 19 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/17/10617/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h</span><br><span>index ccee8c9..5b948b4 100644</span><br><span>--- a/include/asterisk/res_pjsip_session.h</span><br><span>+++ b/include/asterisk/res_pjsip_session.h</span><br><span>@@ -215,6 +215,9 @@</span><br><span>        enum ast_sip_dtmf_mode dtmf;</span><br><span>         /*! Initial incoming INVITE Request-URI.  NULL otherwise. */</span><br><span>         pjsip_uri *request_uri;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /*! Next item in the list */</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_LIST_ENTRY(ast_sip_session) next;</span><br><span> };</span><br><span> </span><br><span> typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);</span><br><span>@@ -472,6 +475,13 @@</span><br><span>         struct ast_sip_contact *contact, pjsip_inv_session *inv, pjsip_rx_data *rdata);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Unregister a an supplement to SIP session processing from exisiting SIP sessions.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param supplement The supplement to unregister</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sip_remove_registered_supplement(struct ast_sip_session_supplement *supplement);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span>  * \brief Request and wait for the session serializer to be suspended.</span><br><span>  * \since 12.7.0</span><br><span>  *</span><br><span>@@ -573,6 +583,21 @@</span><br><span> void ast_sip_session_unregister_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Insert a session to the list.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param session</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sip_session_insert(struct ast_sip_session *session);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Remove session from the list.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param session</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sip_session_remove(struct ast_sip_session *session);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span>  * \brief Register a supplement to SIP session processing</span><br><span>  *</span><br><span>  * This allows for someone to insert themselves in the processing of SIP</span><br><span>diff --git a/res/res_pjsip/pjsip_session.c b/res/res_pjsip/pjsip_session.c</span><br><span>index f3f3a4d..95c8fb6 100644</span><br><span>--- a/res/res_pjsip/pjsip_session.c</span><br><span>+++ b/res/res_pjsip/pjsip_session.c</span><br><span>@@ -29,9 +29,14 @@</span><br><span> #include "asterisk/lock.h"</span><br><span> #include "asterisk/module.h"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+AST_LIST_HEAD_STATIC(pjsip_sessions, ast_sip_session);</span><br><span> </span><br><span> AST_RWLIST_HEAD_STATIC(session_supplements, ast_sip_session_supplement);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void remove_registered_supplement(struct ast_sip_session *session, struct ast_sip_session_supplement *supplement);</span><br><span style="color: hsl(120, 100%, 40%);">+static int is_same_supplement(const struct ast_sip_session_supplement *supp1, const struct ast_sip_session_supplement *supp2);</span><br><span style="color: hsl(120, 100%, 40%);">+static int is_same_method(const char* m1, const char* m2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement)</span><br><span> {</span><br><span>    struct ast_sip_session_supplement *iter;</span><br><span>@@ -59,7 +64,8 @@</span><br><span> void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)</span><br><span> {</span><br><span>       struct ast_sip_session_supplement *iter;</span><br><span style="color: hsl(0, 100%, 40%);">-        SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_RWLIST_WRLOCK(&session_supplements);</span><br><span> </span><br><span>     AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) {</span><br><span>               if (supplement == iter) {</span><br><span>@@ -68,6 +74,10 @@</span><br><span>               }</span><br><span>    }</span><br><span>    AST_RWLIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_RWLIST_UNLOCK(&session_supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_sip_remove_registered_supplement(supplement);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span> </span><br><span> static struct ast_sip_session_supplement *supplement_dup(const struct ast_sip_session_supplement *src)</span><br><span>@@ -77,6 +87,7 @@</span><br><span>   if (!dst) {</span><br><span>          return NULL;</span><br><span>         }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /* Will need to revisit if shallow copy becomes an issue */</span><br><span>  *dst = *src;</span><br><span> </span><br><span>@@ -94,8 +105,183 @@</span><br><span>              if (!copy) {</span><br><span>                         return -1;</span><br><span>           }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           AST_LIST_LOCK(&session->supplements);</span><br><span>                 AST_LIST_INSERT_TAIL(&session->supplements, copy, next);</span><br><span style="color: hsl(120, 100%, 40%);">+               AST_LIST_UNLOCK(&session->supplements);</span><br><span>       }</span><br><span> </span><br><span>        return 0;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sip_remove_registered_supplement(struct ast_sip_session_supplement *supplement)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_session *iter;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!supplement) {</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_LIST_LOCK(&pjsip_sessions);</span><br><span style="color: hsl(120, 100%, 40%);">+   </span><br><span style="color: hsl(120, 100%, 40%);">+      AST_LIST_TRAVERSE_SAFE_BEGIN(&pjsip_sessions, iter, next) {</span><br><span style="color: hsl(120, 100%, 40%);">+               remove_registered_supplement(iter, supplement);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_UNLOCK(&pjsip_sessions);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns 1 if the given string is the same.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param m1</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param m2</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static int is_same_method(const char* m1, const char* m2)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (m1 == m2) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((!m1) || (!m2)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ret = strcmp(m1, m2);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ret != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param supp1</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param supp2</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return return 1 if supplements are the same. Otherwise 0.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static int is_same_supplement(const struct ast_sip_session_supplement *supp1, const struct ast_sip_session_supplement *supp2)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if ((!supp1) || (!supp2)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* check method */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (is_same_method(supp1->method, supp2->method) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* check request/response handler */</span><br><span style="color: hsl(120, 100%, 40%);">+  if ((supp1->incoming_request != supp2->incoming_request)</span><br><span style="color: hsl(120, 100%, 40%);">+                        || (supp1->incoming_response != supp2->incoming_response)</span><br><span style="color: hsl(120, 100%, 40%);">+                       || (supp1->outgoing_request != supp2->outgoing_request)</span><br><span style="color: hsl(120, 100%, 40%);">+                 || (supp1->outgoing_response != supp2->outgoing_response)</span><br><span style="color: hsl(120, 100%, 40%);">+                       ) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* check session handler */</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((supp1->session_begin != supp2->session_begin)</span><br><span style="color: hsl(120, 100%, 40%);">+                      || (supp1->session_destroy != supp2->session_destroy)</span><br><span style="color: hsl(120, 100%, 40%);">+                   || (supp1->session_end != supp2->session_end)</span><br><span style="color: hsl(120, 100%, 40%);">+                   ) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* check priority */</span><br><span style="color: hsl(120, 100%, 40%);">+  if ((supp1->priority != supp2->priority)</span><br><span style="color: hsl(120, 100%, 40%);">+                        || (supp1->response_priority != supp2->response_priority)</span><br><span style="color: hsl(120, 100%, 40%);">+                       ) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void remove_registered_supplement(struct ast_sip_session *session, struct ast_sip_session_supplement *supplement)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_session_supplement *iter;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!session) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_log(LOG_DEBUG, "Removing registered supplement. method[%s]\n", supplement->method);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_LIST_LOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_LIST_TRAVERSE_SAFE_BEGIN(&session->supplements, iter, next) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (is_same_supplement(iter, supplement)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   ast_log(LOG_DEBUG, "Found same supplement. Remove it.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                  AST_LIST_REMOVE_CURRENT(next);</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_UNLOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sip_session_insert(struct ast_sip_session *session)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_session *iter;</span><br><span style="color: hsl(120, 100%, 40%);">+ int inserted;</span><br><span style="color: hsl(120, 100%, 40%);">+ int count;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!session) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   inserted = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_LIST_LOCK(&pjsip_sessions);</span><br><span style="color: hsl(120, 100%, 40%);">+   </span><br><span style="color: hsl(120, 100%, 40%);">+      AST_LIST_TRAVERSE_SAFE_BEGIN(&pjsip_sessions, iter, next) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (iter == session) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        inserted = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                 break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             count++;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!inserted) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_log(LOG_DEBUG, "Insert session to the list. count[%d]\n", count);</span><br><span style="color: hsl(120, 100%, 40%);">+               AST_LIST_INSERT_TAIL(&pjsip_sessions, session, next);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_LIST_UNLOCK(&pjsip_sessions);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sip_session_remove(struct ast_sip_session *session)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_session *iter;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!session) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_LIST_LOCK(&pjsip_sessions);</span><br><span style="color: hsl(120, 100%, 40%);">+   </span><br><span style="color: hsl(120, 100%, 40%);">+      AST_LIST_TRAVERSE_SAFE_BEGIN(&pjsip_sessions, iter, next) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (iter == session) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        AST_RWLIST_REMOVE_CURRENT(next);</span><br><span style="color: hsl(120, 100%, 40%);">+                      break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_UNLOCK(&pjsip_sessions);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c</span><br><span>index 4ce35c9..133488b 100644</span><br><span>--- a/res/res_pjsip_session.c</span><br><span>+++ b/res/res_pjsip_session.c</span><br><span>@@ -58,6 +58,8 @@</span><br><span> #define DEFAULT_NUM_SESSION_MEDIA 2</span><br><span> </span><br><span> /* Some forward declarations */</span><br><span style="color: hsl(120, 100%, 40%);">+static void handle_session_begin(struct ast_sip_session *session);</span><br><span style="color: hsl(120, 100%, 40%);">+static void handle_session_end(struct ast_sip_session *session);</span><br><span> static void handle_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata);</span><br><span> static void handle_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata,</span><br><span>            enum ast_sip_session_response_priority response_priority);</span><br><span>@@ -2104,19 +2106,22 @@</span><br><span>                 , session->contact ? ast_sorcery_object_get_id(session->contact) : "<none>"</span><br><span>            );</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        AST_LIST_LOCK(&session->supplements);</span><br><span>         while ((supplement = AST_LIST_REMOVE_HEAD(&session->supplements, next))) {</span><br><span>            if (supplement->session_destroy) {</span><br><span>                        supplement->session_destroy(session);</span><br><span>             }</span><br><span>            ast_free(supplement);</span><br><span>        }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_UNLOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      AST_LIST_HEAD_DESTROY(&session->supplements);</span><br><span> </span><br><span>     ast_taskprocessor_unreference(session->serializer);</span><br><span>       ao2_cleanup(session->datastores);</span><br><span>         ast_sip_session_media_state_free(session->active_media_state);</span><br><span>    ast_sip_session_media_state_free(session->pending_media_state);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  AST_LIST_HEAD_DESTROY(&session->supplements);</span><br><span>         while ((delay = AST_LIST_REMOVE_HEAD(&session->delayed_requests, next))) {</span><br><span>            delayed_request_free(delay);</span><br><span>         }</span><br><span>@@ -2132,6 +2137,9 @@</span><br><span>            pjsip_dlg_dec_session(session->inv_session->dlg, &session_module);</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Remove session from the list */</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_sip_session_remove(session);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   ast_test_suite_event_notify("SESSION_DESTROYED", "Endpoint: %s", endpoint_name);</span><br><span> }</span><br><span> </span><br><span>@@ -2211,6 +2219,9 @@</span><br><span> </span><br><span>    session->endpoint = ao2_bump(endpoint);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        /* Insert to list */</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_sip_session_insert(session);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   if (rdata) {</span><br><span>                 /*</span><br><span>            * We must continue using the serializer that the original</span><br><span>@@ -2246,11 +2257,9 @@</span><br><span>          ao2_ref(session, -1);</span><br><span>                return NULL;</span><br><span>         }</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_LIST_TRAVERSE(&session->supplements, iter, next) {</span><br><span style="color: hsl(0, 100%, 40%);">-           if (iter->session_begin) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   iter->session_begin(session);</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(120, 100%, 40%);">+     </span><br><span style="color: hsl(120, 100%, 40%);">+      /* Fire seesion begin handlers */</span><br><span style="color: hsl(120, 100%, 40%);">+     handle_session_begin(session);</span><br><span> </span><br><span>   /* Avoid unnecessary ref manipulation to return a session */</span><br><span>         ret_session = session;</span><br><span>@@ -3135,21 +3144,31 @@</span><br><span>     return pj_stristr(&method, message_method) ? PJ_TRUE : PJ_FALSE;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static pj_bool_t has_supplement(const struct ast_sip_session *session, const pjsip_rx_data *rdata)</span><br><span style="color: hsl(120, 100%, 40%);">+static pj_bool_t has_supplement(struct ast_sip_session *session, const pjsip_rx_data *rdata)</span><br><span> {</span><br><span>   struct ast_sip_session_supplement *supplement;</span><br><span>       struct pjsip_method *method = &rdata->msg_info.msg->line.req.method;</span><br><span style="color: hsl(120, 100%, 40%);">+        int found;</span><br><span> </span><br><span>       if (!session) {</span><br><span>              return PJ_FALSE;</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_LOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+  found = 0;</span><br><span>   AST_LIST_TRAVERSE(&session->supplements, supplement, next) {</span><br><span>          if (does_method_match(&method->name, supplement->method)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   return PJ_TRUE;</span><br><span style="color: hsl(120, 100%, 40%);">+                       found = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                    break;</span><br><span>               }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       return PJ_FALSE;</span><br><span style="color: hsl(120, 100%, 40%);">+      AST_LIST_UNLOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if(!found) {</span><br><span style="color: hsl(120, 100%, 40%);">+          return PJ_FALSE;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return PJ_TRUE;</span><br><span> }</span><br><span> /*!</span><br><span>  * \brief Called when a new SIP request comes into PJSIP</span><br><span>@@ -3306,13 +3325,56 @@</span><br><span>    struct pjsip_request_line req = rdata->msg_info.msg->line.req;</span><br><span> </span><br><span>     ast_debug(3, "Method is %.*s\n", (int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name));</span><br><span style="color: hsl(0, 100%, 40%);">-     AST_LIST_TRAVERSE(&session->supplements, supplement, next) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_LOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_LIST_TRAVERSE_SAFE_BEGIN(&session->supplements, supplement, next) {</span><br><span>               if (supplement->incoming_request && does_method_match(&req.method.name, supplement->method)) {</span><br><span>                     if (supplement->incoming_request(session, rdata)) {</span><br><span>                               break;</span><br><span>                       }</span><br><span>            }</span><br><span>    }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_UNLOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void handle_session_begin(struct ast_sip_session *session)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct ast_sip_session_supplement *iter;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_log(LOG_DEBUG, "Fired handle_session_begin.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      AST_LIST_LOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_LIST_TRAVERSE_SAFE_BEGIN(&session->supplements, iter, next) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (iter->session_begin) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 iter->session_begin(session);</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_UNLOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void handle_session_end(struct ast_sip_session *session)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_sip_session_supplement *iter;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_log(LOG_DEBUG, "Fired handle_session_end.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_LIST_LOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Session is dead.  Notify the supplements. */</span><br><span style="color: hsl(120, 100%, 40%);">+       AST_LIST_TRAVERSE_SAFE_BEGIN(&session->supplements, iter, next) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (iter->session_end) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   iter->session_end(session);</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_UNLOCK(&session->supplements);</span><br><span> }</span><br><span> </span><br><span> static void handle_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata,</span><br><span>@@ -3324,7 +3386,9 @@</span><br><span>       ast_debug(3, "Response is %d %.*s\n", status.code, (int) pj_strlen(&status.reason),</span><br><span>                    pj_strbuf(&status.reason));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     AST_LIST_TRAVERSE(&session->supplements, supplement, next) {</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_LIST_LOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_LIST_TRAVERSE_SAFE_BEGIN(&session->supplements, supplement, next) {</span><br><span>               if (!(supplement->response_priority & response_priority)) {</span><br><span>                   continue;</span><br><span>            }</span><br><span>@@ -3332,6 +3396,9 @@</span><br><span>                    supplement->incoming_response(session, rdata);</span><br><span>            }</span><br><span>    }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_UNLOCK(&session->supplements);</span><br><span> }</span><br><span> </span><br><span> static int handle_incoming(struct ast_sip_session *session, pjsip_rx_data *rdata,</span><br><span>@@ -3358,11 +3425,17 @@</span><br><span> </span><br><span>   ast_sip_message_apply_transport(session->endpoint->transport, tdata);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_TRAVERSE(&session->supplements, supplement, next) {</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_LIST_LOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_LIST_TRAVERSE_SAFE_BEGIN(&session->supplements, supplement, next) {</span><br><span>               if (supplement->outgoing_request && does_method_match(&req.method.name, supplement->method)) {</span><br><span>                     supplement->outgoing_request(session, tdata);</span><br><span>             }</span><br><span>    }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_UNLOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span> </span><br><span> static void handle_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)</span><br><span>@@ -3382,11 +3455,17 @@</span><br><span> </span><br><span>       ast_sip_message_apply_transport(session->endpoint->transport, tdata);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_TRAVERSE(&session->supplements, supplement, next) {</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_LIST_LOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_LIST_TRAVERSE_SAFE_BEGIN(&session->supplements, supplement, next) {</span><br><span>               if (supplement->outgoing_response && does_method_match(&cseq->method.name, supplement->method)) {</span><br><span>                       supplement->outgoing_response(session, tdata);</span><br><span>            }</span><br><span>    }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_LIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_UNLOCK(&session->supplements);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span> </span><br><span> static int session_end(void *vsession)</span><br><span>@@ -3398,11 +3477,8 @@</span><br><span>         sip_session_defer_termination_stop_timer(session);</span><br><span> </span><br><span>       /* Session is dead.  Notify the supplements. */</span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_TRAVERSE(&session->supplements, iter, next) {</span><br><span style="color: hsl(0, 100%, 40%);">-           if (iter->session_end) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     iter->session_end(session);</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(120, 100%, 40%);">+     handle_session_end(session);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       return 0;</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10617">change 10617</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/10617"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I5b82be3a75d702cf1933d8d1417f44aa10ad1029 </div>
<div style="display:none"> Gerrit-Change-Number: 10617 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: sungtae kim <pchero21@gmail.com> </div>