<p>Joshua Colp has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18112">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">pjproject: Update bundled to 2.12 release.<br><br>ASTERISK-29351<br><br>Change-Id: Id39ece02dedb7b9f739e0e37ea47d76854af7191<br>---<br>M third-party/pjproject/patches/0000-configure-ssl-library-path.patch<br>M third-party/pjproject/patches/0000-remove-third-party.patch<br>D third-party/pjproject/patches/0000-set_apps_initial_log_level.patch<br>D third-party/pjproject/patches/0000-solaris.patch<br>D third-party/pjproject/patches/0011-sip_inv_patch.patch<br>D third-party/pjproject/patches/0020-pjlib_cancel_timer_0.patch<br>D third-party/pjproject/patches/0050-fix-race-parallel-build.patch<br>D third-party/pjproject/patches/0060-clone-sdp-for-sip-timer-refresh-invite.patch<br>D third-party/pjproject/patches/0070-fix-incorrect-copying-when-creating-cancel.patch<br>D third-party/pjproject/patches/0080-fix-sdp-neg-modify-local-offer.patch<br>D third-party/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch<br>D third-party/pjproject/patches/0100-fix-double-stun-free.patch<br>D third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch<br>D third-party/pjproject/patches/0111-ssl-premature-destroy.patch<br>D third-party/pjproject/patches/0120-pjmedia_sdp_attr_get_rtpmap-Strip-param-trailing-whi.patch<br>D third-party/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch<br>D third-party/pjproject/patches/0140-Fix-incorrect-unescaping-of-tokens-during-parsing-29.patch<br>D third-party/pjproject/patches/0150-Create-generic-pjsip_hdr_find-functions.patch<br>D third-party/pjproject/patches/0160-Additional-multipart-improvements.patch<br>D third-party/pjproject/pjproject-2.10.tar.bz2.md5<br>A third-party/pjproject/pjproject-2.12.tar.bz2.md5<br>M third-party/versions.mak<br>22 files changed, 27 insertions(+), 2,708 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/12/18112/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/third-party/pjproject/patches/0000-configure-ssl-library-path.patch b/third-party/pjproject/patches/0000-configure-ssl-library-path.patch</span><br><span>index 3c1f749..c4dbb49 100644</span><br><span>--- a/third-party/pjproject/patches/0000-configure-ssl-library-path.patch</span><br><span>+++ b/third-party/pjproject/patches/0000-configure-ssl-library-path.patch</span><br><span>@@ -1,19 +1,9 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From e8000cc80e5f8ba02cc52852edc02cdb0e949525 Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: Richard Mudgett <rmudgett@digium.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Mon, 6 Aug 2018 11:24:25 -0500</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH 1/5] 0000-configure-ssl-library-path.patch</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- aconfigure    | 6 +++++-</span><br><span style="color: hsl(0, 100%, 40%);">- aconfigure.ac | 6 +++++-</span><br><span style="color: hsl(0, 100%, 40%);">- 2 files changed, 10 insertions(+), 2 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> diff --git a/aconfigure b/aconfigure</span><br><span style="color: hsl(0, 100%, 40%);">-index 1c449b8..c4c6060 100755</span><br><span style="color: hsl(120, 100%, 40%);">+index d6f0e8809..9dcd46398 100755</span><br><span> --- a/aconfigure</span><br><span> +++ b/aconfigure</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -7954,7 +7954,11 @@ else</span><br><span style="color: hsl(0, 100%, 40%);">-                 if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -8986,7 +8986,11 @@ else $as_nop</span><br><span style="color: hsl(120, 100%, 40%);">+             if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then</span><br><span>                      CFLAGS="$CFLAGS -I$with_ssl/include"</span><br><span>                      CPPFLAGS="$CPPFLAGS -I$with_ssl/include"</span><br><span> -                    LDFLAGS="$LDFLAGS -L$with_ssl/lib"</span><br><span>@@ -22,15 +12,15 @@</span><br><span> +                    else</span><br><span> +                        LDFLAGS="$LDFLAGS -L$with_ssl"</span><br><span> +                    fi</span><br><span style="color: hsl(0, 100%, 40%);">-                     { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using SSL prefix... $with_ssl" >&5</span><br><span style="color: hsl(0, 100%, 40%);">- $as_echo "Using SSL prefix... $with_ssl" >&6; }</span><br><span style="color: hsl(120, 100%, 40%);">+                     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using SSL prefix... $with_ssl" >&5</span><br><span style="color: hsl(120, 100%, 40%);">+ printf "%s\n" "Using SSL prefix... $with_ssl" >&6; }</span><br><span>                  fi</span><br><span> diff --git a/aconfigure.ac b/aconfigure.ac</span><br><span style="color: hsl(0, 100%, 40%);">-index 2c272cd..a5d6d97 100644</span><br><span style="color: hsl(120, 100%, 40%);">+index 16b311045..849da81ab 100644</span><br><span> --- a/aconfigure.ac</span><br><span> +++ b/aconfigure.ac</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1580,7 +1580,11 @@ AC_ARG_ENABLE(ssl,</span><br><span style="color: hsl(0, 100%, 40%);">-                 if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -1838,7 +1838,11 @@ AC_ARG_ENABLE(ssl,</span><br><span style="color: hsl(120, 100%, 40%);">+          if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then</span><br><span>                      CFLAGS="$CFLAGS -I$with_ssl/include"</span><br><span>                      CPPFLAGS="$CPPFLAGS -I$with_ssl/include"</span><br><span> -                    LDFLAGS="$LDFLAGS -L$with_ssl/lib"</span><br><span>@@ -42,6 +32,3 @@</span><br><span>                      AC_MSG_RESULT([Using SSL prefix... $with_ssl])</span><br><span>                  fi</span><br><span>  </span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.7.4</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/patches/0000-remove-third-party.patch b/third-party/pjproject/patches/0000-remove-third-party.patch</span><br><span>index f25aeac..1de154d 100644</span><br><span>--- a/third-party/pjproject/patches/0000-remove-third-party.patch</span><br><span>+++ b/third-party/pjproject/patches/0000-remove-third-party.patch</span><br><span>@@ -1,14 +1,5 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From 665a2fbc3a09a71cd77988ae2deb3f5d3e205f63 Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: Richard Mudgett <rmudgett@digium.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Thu, 23 Feb 2017 17:10:07 -0600</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH 2/5] 0000-remove-third-party.patch</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- build.mak.in | 97 ------------------------------------------------------------</span><br><span style="color: hsl(0, 100%, 40%);">- 1 file changed, 97 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> diff --git a/build.mak.in b/build.mak.in</span><br><span style="color: hsl(0, 100%, 40%);">-index 80ccad1..41ec64e 100644</span><br><span style="color: hsl(120, 100%, 40%);">+index 4bc464f8c..80681d961 100644</span><br><span> --- a/build.mak.in</span><br><span> +++ b/build.mak.in</span><br><span> @@ -1,4 +1,3 @@</span><br><span>@@ -16,7 +7,7 @@</span><br><span>  include $(PJDIR)/version.mak</span><br><span>  export PJ_DIR := $(PJDIR)</span><br><span>  </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -37,19 +36,6 @@ export APP_THIRD_PARTY_EXT :=</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -41,19 +40,6 @@ export APP_THIRD_PARTY_EXT :=</span><br><span>  export APP_THIRD_PARTY_LIBS :=</span><br><span>  export APP_THIRD_PARTY_LIB_FILES :=</span><br><span>  </span><br><span>@@ -36,7 +27,7 @@</span><br><span>  ifeq (@ac_pjmedia_resample@,libresample)</span><br><span>  APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample-$(LIB_SUFFIX)</span><br><span>  ifeq ($(PJ_SHARED_LIBRARIES),)</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -66,89 +52,6 @@ APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFI</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -70,102 +56,6 @@ APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFI</span><br><span>  endif</span><br><span>  endif</span><br><span>  </span><br><span>@@ -122,10 +113,20 @@</span><br><span> -endif</span><br><span> -endif</span><br><span> -</span><br><span style="color: hsl(120, 100%, 40%);">+-ifneq (@ac_no_webrtc_aec3@,1)</span><br><span style="color: hsl(120, 100%, 40%);">+-ifeq (@ac_external_webrtc_aec3@,1)</span><br><span style="color: hsl(120, 100%, 40%);">+-APP_THIRD_PARTY_EXT += -lwebrtc-aec3</span><br><span style="color: hsl(120, 100%, 40%);">+-else</span><br><span style="color: hsl(120, 100%, 40%);">+-APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc-aec3-$(LIB_SUFFIX)</span><br><span style="color: hsl(120, 100%, 40%);">+-ifeq ($(PJ_SHARED_LIBRARIES),)</span><br><span style="color: hsl(120, 100%, 40%);">+-APP_THIRD_PARTY_LIBS += -lwebrtc-aec3-$(TARGET_NAME)</span><br><span style="color: hsl(120, 100%, 40%);">+-else</span><br><span style="color: hsl(120, 100%, 40%);">+-APP_THIRD_PARTY_LIBS += -lwebrtc-aec3</span><br><span style="color: hsl(120, 100%, 40%);">+-APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc-aec3.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libwebrtc.$(SHLIB_SUFFIX)</span><br><span style="color: hsl(120, 100%, 40%);">+-endif</span><br><span style="color: hsl(120, 100%, 40%);">+-endif</span><br><span style="color: hsl(120, 100%, 40%);">+-endif</span><br><span> -</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  # Additional flags</span><br><span>  @ac_build_mak_vars@</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.7.4</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/patches/0000-set_apps_initial_log_level.patch b/third-party/pjproject/patches/0000-set_apps_initial_log_level.patch</span><br><span>deleted file mode 100644</span><br><span>index b1fe02c..0000000</span><br><span>--- a/third-party/pjproject/patches/0000-set_apps_initial_log_level.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,53 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From c40ad6ba454fdf6456d8ffa92faa4cd49f2c807d Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: Richard Mudgett <rmudgett@digium.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Thu, 23 Feb 2017 17:11:00 -0600</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH 3/5] 0000-set_apps_initial_log_level.patch</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip-apps/src/pjsua/main.c             | 2 ++</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip-apps/src/pjsystest/main_console.c | 2 ++</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip-apps/src/python/_pjsua.c          | 3 ++-</span><br><span style="color: hsl(0, 100%, 40%);">- 3 files changed, 6 insertions(+), 1 deletion(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip-apps/src/pjsua/main.c b/pjsip-apps/src/pjsua/main.c</span><br><span style="color: hsl(0, 100%, 40%);">-index 2baaf82..11831f2 100644</span><br><span>---- a/pjsip-apps/src/pjsua/main.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip-apps/src/pjsua/main.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -126,5 +126,7 @@ int main_func(int argc, char *argv[])</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- int main(int argc, char *argv[])</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_log_set_level(1);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     return pj_run_app(&main_func, argc, argv, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip-apps/src/pjsystest/main_console.c b/pjsip-apps/src/pjsystest/main_console.c</span><br><span style="color: hsl(0, 100%, 40%);">-index 122cdc7..dc79eab 100644</span><br><span>---- a/pjsip-apps/src/pjsystest/main_console.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip-apps/src/pjsystest/main_console.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -133,6 +133,8 @@ void gui_sleep(unsigned sec)</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- int main()</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_log_set_level(1);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     if (systest_init() != PJ_SUCCESS)</span><br><span style="color: hsl(0, 100%, 40%);">-   return 1;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip-apps/src/python/_pjsua.c b/pjsip-apps/src/python/_pjsua.c</span><br><span style="color: hsl(0, 100%, 40%);">-index 31b835e..3e15030 100644</span><br><span>---- a/pjsip-apps/src/python/_pjsua.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip-apps/src/python/_pjsua.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -4434,7 +4434,8 @@ init_pjsua(void)</span><br><span style="color: hsl(0, 100%, 40%);">-     PyObject* m = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- #define ADD_CONSTANT(mod,name)    PyModule_AddIntConstant(mod,#name,name)</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    </span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_log_set_level(1);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     PyEval_InitThreads();</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     if (PyType_Ready(&PyTyp_pjsua_callback) < 0)</span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.7.4</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/patches/0000-solaris.patch b/third-party/pjproject/patches/0000-solaris.patch</span><br><span>deleted file mode 100644</span><br><span>index 155cdbe..0000000</span><br><span>--- a/third-party/pjproject/patches/0000-solaris.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,135 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From 1ac599a0f29500a15faf0dbbdc2565cc7dce2420 Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: Shaun Ruffell <sruffell@digium.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Fri, 7 Sep 2012 14:31:19 -0500</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH 4/5] pjproject: Fix for Solaris builds. Do not undef s_addr.</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-pjproject, in order to solve build problems on Windows [1], undefines s_addr in</span><br><span style="color: hsl(0, 100%, 40%);">-one of it's headers that is included in res_rtp_asterisk.c. On Solaris s_addr is</span><br><span style="color: hsl(0, 100%, 40%);">-not a structure member, but defined to map to the real strucuture member,</span><br><span style="color: hsl(0, 100%, 40%);">-therefore when building on Solaris it's possible to get build errors like:</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    [CC] res_rtp_asterisk.c -> res_rtp_asterisk.o</span><br><span style="color: hsl(0, 100%, 40%);">-    In file included from /export/home/admin/asterisk-11-svn/include/asterisk/stun.h:29,</span><br><span style="color: hsl(0, 100%, 40%);">-                     from res_rtp_asterisk.c:51:</span><br><span style="color: hsl(0, 100%, 40%);">-    /export/home/admin/asterisk-11-svn/include/asterisk/network.h: In function `inaddrcmp':</span><br><span style="color: hsl(0, 100%, 40%);">-    /export/home/admin/asterisk-11-svn/include/asterisk/network.h:92: error: structure has no member named `s_addr'</span><br><span style="color: hsl(0, 100%, 40%);">-    /export/home/admin/asterisk-11-svn/include/asterisk/network.h:92: error: structure has no member named `s_addr'</span><br><span style="color: hsl(0, 100%, 40%);">-    res_rtp_asterisk.c: In function `ast_rtp_on_ice_tx_pkt':</span><br><span style="color: hsl(0, 100%, 40%);">-    res_rtp_asterisk.c:706: warning: dereferencing type-punned pointer will break strict-aliasing rules</span><br><span style="color: hsl(0, 100%, 40%);">-    res_rtp_asterisk.c:710: warning: dereferencing type-punned pointer will break strict-aliasing rules</span><br><span style="color: hsl(0, 100%, 40%);">-    res_rtp_asterisk.c: In function `rtp_add_candidates_to_ice':</span><br><span style="color: hsl(0, 100%, 40%);">-    res_rtp_asterisk.c:1085: error: structure has no member named `s_addr'</span><br><span style="color: hsl(0, 100%, 40%);">-    make[2]: *** [res_rtp_asterisk.o] Error 1</span><br><span style="color: hsl(0, 100%, 40%);">-    make[1]: *** [res] Error 2</span><br><span style="color: hsl(0, 100%, 40%);">-    make[1]: Leaving directory `/export/home/admin/asterisk-11-svn'</span><br><span style="color: hsl(0, 100%, 40%);">-    gmake: *** [_cleantest_all] Error 2</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-Unfortunately, in order to make this work, I also had to make sure pjproject</span><br><span style="color: hsl(0, 100%, 40%);">-only used the typdef pj_in_addr and not the struct pj_in_addr so that when</span><br><span style="color: hsl(0, 100%, 40%);">-building Asterisk I could "typedef struct in_addr pj_in_addr". It's possible</span><br><span style="color: hsl(0, 100%, 40%);">-then that the library and users of those interfaces in Asterisk have a different</span><br><span style="color: hsl(0, 100%, 40%);">-idea about the type of the argument. While on the surface it looks like they are</span><br><span style="color: hsl(0, 100%, 40%);">-all 32 bit big endian values.</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-[1] http://trac.pjsip.org/repos/changeset/484</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-Reported-by: Ben Klang</span><br><span style="color: hsl(0, 100%, 40%);">-(issues ASTERISK-20366)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-Updated by ASTERISK-27997</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjlib/include/pj/sock.h         | 8 +++++++-</span><br><span style="color: hsl(0, 100%, 40%);">- pjlib/src/pj/sock_bsd.c         | 2 +-</span><br><span style="color: hsl(0, 100%, 40%);">- pjlib/src/pj/sock_symbian.cpp   | 2 +-</span><br><span style="color: hsl(0, 100%, 40%);">- pjlib/src/pj/sock_uwp.cpp       | 2 +-</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/test/transport_test.c | 2 +-</span><br><span style="color: hsl(0, 100%, 40%);">- 5 files changed, 11 insertions(+), 5 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjlib/include/pj/sock.h b/pjlib/include/pj/sock.h</span><br><span style="color: hsl(0, 100%, 40%);">-index 4daf298..c35833c 100644</span><br><span>---- a/pjlib/include/pj/sock.h</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjlib/include/pj/sock.h</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -484,6 +484,7 @@ typedef enum pj_socket_sd_type</span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">- #define PJ_INVALID_SOCKET   (-1)</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+#ifndef _ASTERISK_H</span><br><span style="color: hsl(0, 100%, 40%);">- /* Must undefine s_addr because of pj_in_addr below */</span><br><span style="color: hsl(0, 100%, 40%);">- #undef s_addr</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -495,6 +496,11 @@ typedef struct pj_in_addr</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_uint32_t  s_addr;         /**< The 32bit IP address.       */</span><br><span style="color: hsl(0, 100%, 40%);">- } pj_in_addr;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+#else</span><br><span style="color: hsl(0, 100%, 40%);">-+#include <sys/types.h></span><br><span style="color: hsl(0, 100%, 40%);">-+#include <netinet/in.h></span><br><span style="color: hsl(0, 100%, 40%);">-+typedef struct in_addr pj_in_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-+#endif</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- /**</span><br><span style="color: hsl(0, 100%, 40%);">-  * Maximum length of text representation of an IPv4 address.</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -712,7 +718,7 @@ PJ_DECL(char*) pj_inet_ntoa(pj_in_addr inaddr);</span><br><span style="color: hsl(0, 100%, 40%);">-  *</span><br><span style="color: hsl(0, 100%, 40%);">-  * @return     nonzero if the address is valid, zero if not.</span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">--PJ_DECL(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp);</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- /**</span><br><span style="color: hsl(0, 100%, 40%);">-  * This function converts an address in its standard text presentation form</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjlib/src/pj/sock_bsd.c b/pjlib/src/pj/sock_bsd.c</span><br><span style="color: hsl(0, 100%, 40%);">-index e416991..940fce1 100644</span><br><span>---- a/pjlib/src/pj/sock_bsd.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjlib/src/pj/sock_bsd.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -244,7 +244,7 @@ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)</span><br><span style="color: hsl(0, 100%, 40%);">-  * numbers-and-dots notation into binary data and stores it in the structure</span><br><span style="color: hsl(0, 100%, 40%);">-  * that inp points to. </span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">--PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     char tempaddr[PJ_INET_ADDRSTRLEN];</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjlib/src/pj/sock_symbian.cpp b/pjlib/src/pj/sock_symbian.cpp</span><br><span style="color: hsl(0, 100%, 40%);">-index 09239b0..e72bbda 100644</span><br><span>---- a/pjlib/src/pj/sock_symbian.cpp</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjlib/src/pj/sock_symbian.cpp</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -299,7 +299,7 @@ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)</span><br><span style="color: hsl(0, 100%, 40%);">-  * numbers-and-dots notation into binary data and stores it in the structure</span><br><span style="color: hsl(0, 100%, 40%);">-  * that inp points to. </span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">--PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     enum { MAXIPLEN = PJ_INET_ADDRSTRLEN };</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjlib/src/pj/sock_uwp.cpp b/pjlib/src/pj/sock_uwp.cpp</span><br><span style="color: hsl(0, 100%, 40%);">-index 876c328..40250bf 100644</span><br><span>---- a/pjlib/src/pj/sock_uwp.cpp</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjlib/src/pj/sock_uwp.cpp</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -933,7 +933,7 @@ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)</span><br><span style="color: hsl(0, 100%, 40%);">-  * numbers-and-dots notation into binary data and stores it in the structure</span><br><span style="color: hsl(0, 100%, 40%);">-  * that inp points to. </span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">--PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     char tempaddr[PJ_INET_ADDRSTRLEN];</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/test/transport_test.c b/pjsip/src/test/transport_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-index e5083d1..c429cc7 100644</span><br><span>---- a/pjsip/src/test/transport_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/test/transport_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -35,7 +35,7 @@ int generic_transport_test(pjsip_transport *tp)</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Check that local address name is valid. */</span><br><span style="color: hsl(0, 100%, 40%);">-     {</span><br><span style="color: hsl(0, 100%, 40%);">--      struct pj_in_addr addr;</span><br><span style="color: hsl(0, 100%, 40%);">-+        pj_in_addr addr;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-       if (pj_inet_pton(pj_AF_INET(), &tp->local_name.host,</span><br><span style="color: hsl(0, 100%, 40%);">-                      &addr) == PJ_SUCCESS)</span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.7.4</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/patches/0011-sip_inv_patch.patch b/third-party/pjproject/patches/0011-sip_inv_patch.patch</span><br><span>deleted file mode 100644</span><br><span>index 7f77c74..0000000</span><br><span>--- a/third-party/pjproject/patches/0011-sip_inv_patch.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,39 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-commit c3c1bf45cae2a35003aa16c267d59f97027f9c5e</span><br><span style="color: hsl(0, 100%, 40%);">-Author: Kevin Harwell <kharwell@digium.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date:   Thu Jun 11 11:11:13 2020 -0500</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    sip_inv - fix invite session ref count crash</span><br><span style="color: hsl(0, 100%, 40%);">-    </span><br><span style="color: hsl(0, 100%, 40%);">-    Ensure the session's ref count is only decremented under proper conditons.</span><br><span style="color: hsl(0, 100%, 40%);">-    </span><br><span style="color: hsl(0, 100%, 40%);">-    For more details see the following issue report:</span><br><span style="color: hsl(0, 100%, 40%);">-    https://github.com/pjsip/pjproject/issues/2443</span><br><span style="color: hsl(0, 100%, 40%);">-    </span><br><span style="color: hsl(0, 100%, 40%);">-    Patch supplied by sauwming</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c</span><br><span style="color: hsl(0, 100%, 40%);">-index ca225015b..7c11b1c8e 100644</span><br><span>---- a/pjsip/src/pjsip-ua/sip_inv.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/pjsip-ua/sip_inv.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -323,9 +323,19 @@ static void inv_set_state(pjsip_inv_session *inv, pjsip_inv_state state,</span><br><span style="color: hsl(0, 100%, 40%);">-       (*mod_inv.cb.on_state_changed)(inv, e);</span><br><span style="color: hsl(0, 100%, 40%);">-     pjsip_inv_dec_ref(inv);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    /* Only decrement when previous state is not already DISCONNECTED */</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* The above callback may change the state, so we need to be careful here</span><br><span style="color: hsl(0, 100%, 40%);">-+     * and only decrement inv under the following conditions:</span><br><span style="color: hsl(0, 100%, 40%);">-+     * 1. If the state parameter is DISCONNECTED, and previous state is not</span><br><span style="color: hsl(0, 100%, 40%);">-+     *    already DISCONNECTED.</span><br><span style="color: hsl(0, 100%, 40%);">-+     *    This is to make sure that dec_ref() is not called more than once.</span><br><span style="color: hsl(0, 100%, 40%);">-+     * 2. If current state is PJSIP_INV_STATE_DISCONNECTED.</span><br><span style="color: hsl(0, 100%, 40%);">-+     *    This is to make sure that dec_ref() is not called if user restarts</span><br><span style="color: hsl(0, 100%, 40%);">-+     *    inv within the callback. Note that this check must be last since</span><br><span style="color: hsl(0, 100%, 40%);">-+     *    inv may have already been destroyed.</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (state == PJSIP_INV_STATE_DISCONNECTED &&</span><br><span style="color: hsl(0, 100%, 40%);">--  prev_state != PJSIP_INV_STATE_DISCONNECTED) </span><br><span style="color: hsl(0, 100%, 40%);">-+   prev_state != PJSIP_INV_STATE_DISCONNECTED &&</span><br><span style="color: hsl(0, 100%, 40%);">-+  inv->state == PJSIP_INV_STATE_DISCONNECTED) </span><br><span style="color: hsl(0, 100%, 40%);">-     {</span><br><span style="color: hsl(0, 100%, 40%);">-   pjsip_inv_dec_ref(inv);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span>diff --git a/third-party/pjproject/patches/0020-pjlib_cancel_timer_0.patch b/third-party/pjproject/patches/0020-pjlib_cancel_timer_0.patch</span><br><span>deleted file mode 100644</span><br><span>index 09f72d8..0000000</span><br><span>--- a/third-party/pjproject/patches/0020-pjlib_cancel_timer_0.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,39 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-commit 40dd48d10911f4ff9b8dfbf16428fbc9acc434ba</span><br><span style="color: hsl(0, 100%, 40%);">-Author: Riza Sulistyo <trengginas@users.noreply.github.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date:   Thu Jul 9 17:47:24 2020 +0700</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    Modify timer_id check on cancel() (#2463)</span><br><span style="color: hsl(0, 100%, 40%);">-    </span><br><span style="color: hsl(0, 100%, 40%);">-    * modify timer_id check on cancel().</span><br><span style="color: hsl(0, 100%, 40%);">-    </span><br><span style="color: hsl(0, 100%, 40%);">-    * modification based on comments.</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjlib/include/pj/timer.h b/pjlib/include/pj/timer.h</span><br><span style="color: hsl(0, 100%, 40%);">-index b738a6e76..4b76ab65d 100644</span><br><span>---- a/pjlib/include/pj/timer.h</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjlib/include/pj/timer.h</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -120,7 +120,10 @@ typedef struct pj_timer_entry</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /** </span><br><span style="color: hsl(0, 100%, 40%);">-      * Internal unique timer ID, which is assigned by the timer heap. </span><br><span style="color: hsl(0, 100%, 40%);">--     * Application should not touch this ID.</span><br><span style="color: hsl(0, 100%, 40%);">-+     * Positive values indicate that the timer entry is running, </span><br><span style="color: hsl(0, 100%, 40%);">-+     * while -1 means that it's not. Any other value may indicate that it </span><br><span style="color: hsl(0, 100%, 40%);">-+     * hasn't been properly initialised or is in a bad state.</span><br><span style="color: hsl(0, 100%, 40%);">-+     * Application should not touch this ID. </span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_timer_id_t _timer_id;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjlib/src/pj/timer.c b/pjlib/src/pj/timer.c</span><br><span style="color: hsl(0, 100%, 40%);">-index 66516fce8..34966c481 100644</span><br><span>---- a/pjlib/src/pj/timer.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjlib/src/pj/timer.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -535,7 +535,7 @@ static int cancel( pj_timer_heap_t *ht,</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_CHECK_STACK();</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     // Check to see if the timer_id is out of range</span><br><span style="color: hsl(0, 100%, 40%);">--    if (entry->_timer_id < 0 || (pj_size_t)entry->_timer_id > ht->max_size) {</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (entry->_timer_id < 1 || (pj_size_t)entry->_timer_id >= ht->max_size) {</span><br><span style="color: hsl(0, 100%, 40%);">-        entry->_timer_id = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span>diff --git a/third-party/pjproject/patches/0050-fix-race-parallel-build.patch b/third-party/pjproject/patches/0050-fix-race-parallel-build.patch</span><br><span>deleted file mode 100644</span><br><span>index 674baa2..0000000</span><br><span>--- a/third-party/pjproject/patches/0050-fix-race-parallel-build.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,72 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From 78683646c8bc670ec730a42494e075f671a08e28 Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: Guido Falsi <mad@madpilot.net></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Mon, 11 May 2020 08:50:39 +0200</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH] Fix race condition in parallel builds (#2426)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-* Some targets residing in `OBJDIRS` are missing a dependency on that directory, which results in a race condition, causing build to fail sometimes due to the directory not existing when running parallel builds.</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-* The `PJSUA_LIB` variable is not defined anywhere, resulting in an empty value, and no correct dependency on the pjsua shared library for `pjsua2`. The correct variable seems to be `PJSUA_LIB_LIB`, defined at the start of this same `Makefile`.</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- build/rules.mak      | 12 ++++++------</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/build/Makefile |  2 +-</span><br><span style="color: hsl(0, 100%, 40%);">- 2 files changed, 7 insertions(+), 7 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/build/rules.mak b/build/rules.mak</span><br><span style="color: hsl(0, 100%, 40%);">-index 8fa98655e..912199c41 100644</span><br><span>---- a/build/rules.mak</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/build/rules.mak</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -129,7 +129,7 @@ endif</span><br><span style="color: hsl(0, 100%, 40%);">- $(OBJDIR)/$(app).o: $(OBJDIRS) $(OBJS)</span><br><span style="color: hsl(0, 100%, 40%);">-   $(CROSS_COMPILE)ld -r -o $@ $(OBJS)</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--$(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o</span><br><span style="color: hsl(0, 100%, 40%);">-+$(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o | $(OBJDIRS)</span><br><span style="color: hsl(0, 100%, 40%);">-       @echo Creating kbuild Makefile...</span><br><span style="color: hsl(0, 100%, 40%);">-       @echo "# Our module name:" > $(OBJDIR)/Makefile</span><br><span style="color: hsl(0, 100%, 40%);">-    @echo 'obj-m += $(app).o' >> $(OBJDIR)/Makefile</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -154,27 +154,27 @@ $(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o</span><br><span style="color: hsl(0, 100%, 40%);">- ../lib/$(app).ko: $(LIB) $(OBJDIR)/$(app).ko</span><br><span style="color: hsl(0, 100%, 40%);">-         cp $(OBJDIR)/$(app).ko ../lib</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.m</span><br><span style="color: hsl(0, 100%, 40%);">-+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.m | $(OBJDIRS)</span><br><span style="color: hsl(0, 100%, 40%);">-     $(CC) $($(APP)_CFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">-                $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \</span><br><span style="color: hsl(0, 100%, 40%);">-           $(subst /,$(HOST_PSEP),$<) </span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c</span><br><span style="color: hsl(0, 100%, 40%);">-+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c | $(OBJDIRS)</span><br><span style="color: hsl(0, 100%, 40%);">-    $(CC) $($(APP)_CFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">-                $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \</span><br><span style="color: hsl(0, 100%, 40%);">-           $(subst /,$(HOST_PSEP),$<) </span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.S</span><br><span style="color: hsl(0, 100%, 40%);">-+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.S | $(OBJDIRS)</span><br><span style="color: hsl(0, 100%, 40%);">-    $(CC) $($(APP)_CFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">-                $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \</span><br><span style="color: hsl(0, 100%, 40%);">-           $(subst /,$(HOST_PSEP),$<) </span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp</span><br><span style="color: hsl(0, 100%, 40%);">-+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp | $(OBJDIRS)</span><br><span style="color: hsl(0, 100%, 40%);">-        $(CXX) $($(APP)_CXXFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">-             $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \</span><br><span style="color: hsl(0, 100%, 40%);">-           $(subst /,$(HOST_PSEP),$<)</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc</span><br><span style="color: hsl(0, 100%, 40%);">-+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc | $(OBJDIRS)</span><br><span style="color: hsl(0, 100%, 40%);">-   $(CXX) $($(APP)_CXXFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">-             $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \</span><br><span style="color: hsl(0, 100%, 40%);">-           $(subst /,$(HOST_PSEP),$<)</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/build/Makefile b/pjsip/build/Makefile</span><br><span style="color: hsl(0, 100%, 40%);">-index b85c7817a..20777909f 100644</span><br><span>---- a/pjsip/build/Makefile</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/build/Makefile</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -262,7 +262,7 @@ $(PJSUA_LIB_LIB) $(PJSUA_LIB_SONAME): $(PJSIP_LIB) $(PJSIP_SONAME) $(PJSIP_SIMPL</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- pjsua2-lib: $(PJSUA2_LIB_LIB)</span><br><span style="color: hsl(0, 100%, 40%);">- $(PJSUA2_LIB_SONAME): $(PJSUA2_LIB_LIB)</span><br><span style="color: hsl(0, 100%, 40%);">--$(PJSUA2_LIB_LIB) $(PJSUA2_LIB_SONAME): $(PJSUA_LIB) $(PSJUA_LIB_SONAME) $(PJSIP_LIB) $(PJSIP_SONAME) $(PJSIP_SIMPLE_LIB) $(PJSIP_SIMPLE_SONAME) $(PJSIP_UA_LIB) $(PJSIP_UA_SONAME)</span><br><span style="color: hsl(0, 100%, 40%);">-+$(PJSUA2_LIB_LIB) $(PJSUA2_LIB_SONAME): $(PJSUA_LIB_LIB) $(PJSUA_LIB_SONAME) $(PJSIP_LIB) $(PJSIP_SONAME) $(PJSIP_SIMPLE_LIB) $(PJSIP_SIMPLE_SONAME) $(PJSIP_UA_LIB) $(PJSIP_UA_SONAME)</span><br><span style="color: hsl(0, 100%, 40%);">-   $(MAKE) -f $(RULES_MAK) APP=PJSUA2_LIB app=pjsua2-lib $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- pjsip-test: $(TEST_EXE)</span><br><span>diff --git a/third-party/pjproject/patches/0060-clone-sdp-for-sip-timer-refresh-invite.patch b/third-party/pjproject/patches/0060-clone-sdp-for-sip-timer-refresh-invite.patch</span><br><span>deleted file mode 100644</span><br><span>index f1f180a..0000000</span><br><span>--- a/third-party/pjproject/patches/0060-clone-sdp-for-sip-timer-refresh-invite.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,28 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-diff -ur source.orig/pjmedia/src/pjmedia/sdp_neg.c source/pjmedia/src/pjmedia/sdp_neg.c</span><br><span>---- source.orig/pjmedia/src/pjmedia/sdp_neg.c     2020-07-02 10:35:42.022459904 +0200</span><br><span style="color: hsl(0, 100%, 40%);">-+++ source/pjmedia/src/pjmedia/sdp_neg.c     2020-07-02 10:33:24.996316867 +0200</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -906,7 +906,7 @@</span><br><span style="color: hsl(0, 100%, 40%);">-  * after receiving remote answer.</span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">- static pj_status_t process_answer(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">--                                  pjmedia_sdp_session *offer,</span><br><span style="color: hsl(0, 100%, 40%);">-+                            pjmedia_sdp_session *local_offer,</span><br><span style="color: hsl(0, 100%, 40%);">-                               pjmedia_sdp_session *answer,</span><br><span style="color: hsl(0, 100%, 40%);">-                            pj_bool_t allow_asym,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   pjmedia_sdp_session **p_active)</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -914,10 +914,14 @@</span><br><span style="color: hsl(0, 100%, 40%);">-     unsigned omi = 0; /* Offer media index */</span><br><span style="color: hsl(0, 100%, 40%);">-     unsigned ami = 0; /* Answer media index */</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_bool_t has_active = PJ_FALSE;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjmedia_sdp_session *offer;</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_status_t status;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Check arguments. */</span><br><span style="color: hsl(0, 100%, 40%);">--    PJ_ASSERT_RETURN(pool && offer && answer && p_active, PJ_EINVAL);</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(pool && local_offer && answer && p_active, PJ_EINVAL);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Duplicate local offer SDP. */</span><br><span style="color: hsl(0, 100%, 40%);">-+    offer = pjmedia_sdp_session_clone(pool, local_offer);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Check that media count match between offer and answer */</span><br><span style="color: hsl(0, 100%, 40%);">-     // Ticket #527, different media count is allowed for more interoperability,</span><br><span>diff --git a/third-party/pjproject/patches/0070-fix-incorrect-copying-when-creating-cancel.patch b/third-party/pjproject/patches/0070-fix-incorrect-copying-when-creating-cancel.patch</span><br><span>deleted file mode 100644</span><br><span>index 95725c1..0000000</span><br><span>--- a/third-party/pjproject/patches/0070-fix-incorrect-copying-when-creating-cancel.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,37 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From ce18018cc17bef8f80c08686e3a7b28384ef3ba5 Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: sauwming <ming@teluu.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Mon, 12 Oct 2020 13:31:25 +0800</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH] Fix incorrect copying of destination info when creating</span><br><span style="color: hsl(0, 100%, 40%);">- CANCEL (#2546)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/pjsip/sip_util.c | 10 +++++-----</span><br><span style="color: hsl(0, 100%, 40%);">- 1 file changed, 5 insertions(+), 5 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c</span><br><span style="color: hsl(0, 100%, 40%);">-index d10a6fa30..a1bf878ea 100644</span><br><span>---- a/pjsip/src/pjsip/sip_util.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/pjsip/sip_util.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -779,14 +779,14 @@ PJ_DEF(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,</span><br><span style="color: hsl(0, 100%, 40%);">-            pjsip_hdr_clone(cancel_tdata->pool, req_tdata->saved_strict_route);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    /* Copy the destination host name from the original request */</span><br><span style="color: hsl(0, 100%, 40%);">--    pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,</span><br><span style="color: hsl(0, 100%, 40%);">--           &req_tdata->dest_info.name);</span><br><span style="color: hsl(0, 100%, 40%);">--</span><br><span style="color: hsl(0, 100%, 40%);">--    /* Finally copy the destination info from the original request */</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Copy the destination info from the original request */</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_memcpy(&cancel_tdata->dest_info, &req_tdata->dest_info,</span><br><span style="color: hsl(0, 100%, 40%);">-           sizeof(req_tdata->dest_info));</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Finally, copy the destination host name from the original request */</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,</span><br><span style="color: hsl(0, 100%, 40%);">-+              &req_tdata->dest_info.name);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Done.</span><br><span style="color: hsl(0, 100%, 40%);">-      * Return the transmit buffer containing the CANCEL request.</span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.25.1</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/patches/0080-fix-sdp-neg-modify-local-offer.patch b/third-party/pjproject/patches/0080-fix-sdp-neg-modify-local-offer.patch</span><br><span>deleted file mode 100644</span><br><span>index c27a489..0000000</span><br><span>--- a/third-party/pjproject/patches/0080-fix-sdp-neg-modify-local-offer.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,33 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c</span><br><span style="color: hsl(0, 100%, 40%);">-index 3b85b4273..a14009662 100644</span><br><span>---- a/pjmedia/src/pjmedia/sdp_neg.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjmedia/src/pjmedia/sdp_neg.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -304,7 +304,6 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     pjmedia_sdp_session *new_offer;</span><br><span style="color: hsl(0, 100%, 40%);">-     pjmedia_sdp_session *old_offer;</span><br><span style="color: hsl(0, 100%, 40%);">--    char media_used[PJMEDIA_MAX_SDP_MEDIA];</span><br><span style="color: hsl(0, 100%, 40%);">-     unsigned oi; /* old offer media index */</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_status_t status;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -323,8 +322,19 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Change state to STATE_LOCAL_OFFER */</span><br><span style="color: hsl(0, 100%, 40%);">-     neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+    /* When there is no active local SDP in state PJMEDIA_SDP_NEG_STATE_DONE,</span><br><span style="color: hsl(0, 100%, 40%);">-+     * it means that the previous initial SDP nego must have been failed,</span><br><span style="color: hsl(0, 100%, 40%);">-+     * so we'll just set the local SDP offer here.</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!neg->active_local_sdp) {</span><br><span style="color: hsl(0, 100%, 40%);">-+        neg->initial_sdp_tmp = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+        neg->initial_sdp = pjmedia_sdp_session_clone(pool, local);</span><br><span style="color: hsl(0, 100%, 40%);">-+  neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, local);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+       return PJ_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Init vars */</span><br><span style="color: hsl(0, 100%, 40%);">--    pj_bzero(media_used, sizeof(media_used));</span><br><span style="color: hsl(0, 100%, 40%);">-     old_offer = neg->active_local_sdp;</span><br><span style="color: hsl(0, 100%, 40%);">-     new_offer = pjmedia_sdp_session_clone(pool, local);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span>diff --git a/third-party/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch b/third-party/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch</span><br><span>deleted file mode 100644</span><br><span>index a2db220..0000000</span><br><span>--- a/third-party/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,212 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From bdbeb7c4b2b11efc2e59f5dee7aa4360a2bc9fff Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: sauwming <ming@teluu.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Thu, 22 Apr 2021 14:03:28 +0800</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH 90/90] Skip unsupported digest algorithm (#2408)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-Co-authored-by: Nanang Izzuddin <nanang@teluu.com></span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/pjsip/sip_auth_client.c             | 32 +++++--</span><br><span style="color: hsl(0, 100%, 40%);">- tests/pjsua/scripts-sipp/uas-auth-two-algo.py |  7 ++</span><br><span style="color: hsl(0, 100%, 40%);">- .../pjsua/scripts-sipp/uas-auth-two-algo.xml  | 83 +++++++++++++++++++</span><br><span style="color: hsl(0, 100%, 40%);">- 3 files changed, 117 insertions(+), 5 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">- create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.py</span><br><span style="color: hsl(0, 100%, 40%);">- create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.xml</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/pjsip/sip_auth_client.c b/pjsip/src/pjsip/sip_auth_client.c</span><br><span style="color: hsl(0, 100%, 40%);">-index 828b04db9..7eb2f5cd1 100644</span><br><span>---- a/pjsip/src/pjsip/sip_auth_client.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/pjsip/sip_auth_client.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1042,7 +1042,7 @@ static pj_status_t process_auth( pj_pool_t *req_pool,</span><br><span style="color: hsl(0, 100%, 40%);">-     pjsip_hdr *hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_status_t status;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    /* See if we have sent authorization header for this realm */</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* See if we have sent authorization header for this realm (and scheme) */</span><br><span style="color: hsl(0, 100%, 40%);">-     hdr = tdata->msg->hdr.next;</span><br><span style="color: hsl(0, 100%, 40%);">-     while (hdr != &tdata->msg->hdr) {</span><br><span style="color: hsl(0, 100%, 40%);">-        if ((hchal->type == PJSIP_H_WWW_AUTHENTICATE &&</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1052,7 +1052,8 @@ static pj_status_t process_auth( pj_pool_t *req_pool,</span><br><span style="color: hsl(0, 100%, 40%);">-   {</span><br><span style="color: hsl(0, 100%, 40%);">-           sent_auth = (pjsip_authorization_hdr*) hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-             if (pj_stricmp(&hchal->challenge.common.realm,</span><br><span style="color: hsl(0, 100%, 40%);">--                         &sent_auth->credential.common.realm )==0)</span><br><span style="color: hsl(0, 100%, 40%);">-+                       &sent_auth->credential.common.realm)==0 &&</span><br><span style="color: hsl(0, 100%, 40%);">-+           pj_stricmp(&hchal->scheme, &sent_auth->scheme)==0)</span><br><span style="color: hsl(0, 100%, 40%);">-            {</span><br><span style="color: hsl(0, 100%, 40%);">-           /* If this authorization has empty response, remove it. */</span><br><span style="color: hsl(0, 100%, 40%);">-              if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1062,6 +1063,14 @@ static pj_status_t process_auth( pj_pool_t *req_pool,</span><br><span style="color: hsl(0, 100%, 40%);">-                  hdr = hdr->next;</span><br><span style="color: hsl(0, 100%, 40%);">-                     pj_list_erase(sent_auth);</span><br><span style="color: hsl(0, 100%, 40%);">-               continue;</span><br><span style="color: hsl(0, 100%, 40%);">-+          } else</span><br><span style="color: hsl(0, 100%, 40%);">-+         if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&</span><br><span style="color: hsl(0, 100%, 40%);">-+             pj_stricmp(&sent_auth->credential.digest.algorithm,</span><br><span style="color: hsl(0, 100%, 40%);">-+                        &hchal->challenge.digest.algorithm)!=0)</span><br><span style="color: hsl(0, 100%, 40%);">-+          {</span><br><span style="color: hsl(0, 100%, 40%);">-+                  /* Same 'digest' scheme but different algo */</span><br><span style="color: hsl(0, 100%, 40%);">-+                  hdr = hdr->next;</span><br><span style="color: hsl(0, 100%, 40%);">-+                    continue;</span><br><span style="color: hsl(0, 100%, 40%);">-           } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* Found previous authorization attempt */</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1155,9 +1164,10 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     pjsip_tx_data *tdata;</span><br><span style="color: hsl(0, 100%, 40%);">-     const pjsip_hdr *hdr;</span><br><span style="color: hsl(0, 100%, 40%);">--    unsigned chal_cnt;</span><br><span style="color: hsl(0, 100%, 40%);">-+    unsigned chal_cnt, auth_cnt;</span><br><span style="color: hsl(0, 100%, 40%);">-     pjsip_via_hdr *via;</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_status_t status;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_status_t last_auth_err;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_ASSERT_RETURN(sess && rdata && old_request && new_request,</span><br><span style="color: hsl(0, 100%, 40%);">-                   PJ_EINVAL);</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1178,6 +1188,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req(    pjsip_auth_clt_sess *sess,</span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span style="color: hsl(0, 100%, 40%);">-     hdr = rdata->msg_info.msg->hdr.next;</span><br><span style="color: hsl(0, 100%, 40%);">-     chal_cnt = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-+    auth_cnt = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-+    last_auth_err = PJSIP_EAUTHNOAUTH;</span><br><span style="color: hsl(0, 100%, 40%);">-     while (hdr != &rdata->msg_info.msg->hdr) {</span><br><span style="color: hsl(0, 100%, 40%);">-   pjsip_cached_auth *cached_auth;</span><br><span style="color: hsl(0, 100%, 40%);">-         const pjsip_www_authenticate_hdr *hchal;</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1222,8 +1234,13 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req(   pjsip_auth_clt_sess *sess,</span><br><span style="color: hsl(0, 100%, 40%);">-       */</span><br><span style="color: hsl(0, 100%, 40%);">-     status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri,</span><br><span style="color: hsl(0, 100%, 40%);">-                          tdata, sess, cached_auth, &hauth);</span><br><span style="color: hsl(0, 100%, 40%);">--   if (status != PJ_SUCCESS)</span><br><span style="color: hsl(0, 100%, 40%);">--          return status;</span><br><span style="color: hsl(0, 100%, 40%);">-+     if (status != PJ_SUCCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">-+        last_auth_err = status;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+       /* Process next header. */</span><br><span style="color: hsl(0, 100%, 40%);">-+     hdr = hdr->next;</span><br><span style="color: hsl(0, 100%, 40%);">-+            continue;</span><br><span style="color: hsl(0, 100%, 40%);">-+  }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-      if (pj_pool_get_used_size(cached_auth->pool) ></span><br><span style="color: hsl(0, 100%, 40%);">-        PJSIP_AUTH_CACHED_POOL_MAX_SIZE) </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1236,12 +1253,17 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req(     pjsip_auth_clt_sess *sess,</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Process next header. */</span><br><span style="color: hsl(0, 100%, 40%);">-      hdr = hdr->next;</span><br><span style="color: hsl(0, 100%, 40%);">-+    auth_cnt++;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Check if challenge is present */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (chal_cnt == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-       return PJSIP_EAUTHNOCHAL;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Check if any authorization header has been created */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (auth_cnt == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-+ return last_auth_err;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Remove branch param in Via header. */</span><br><span style="color: hsl(0, 100%, 40%);">-     via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-     via->branch_param.slen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/tests/pjsua/scripts-sipp/uas-auth-two-algo.py b/tests/pjsua/scripts-sipp/uas-auth-two-algo.py</span><br><span style="color: hsl(0, 100%, 40%);">-new file mode 100644</span><br><span style="color: hsl(0, 100%, 40%);">-index 000000000..c79c9f6d3</span><br><span>---- /dev/null</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.py</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -0,0 +1,7 @@</span><br><span style="color: hsl(0, 100%, 40%);">-+# $Id$</span><br><span style="color: hsl(0, 100%, 40%);">-+#</span><br><span style="color: hsl(0, 100%, 40%);">-+import inc_const as const</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+PJSUA = ["--null-audio --max-calls=1 --id=sip:a@localhost --username=a --realm=* --registrar=$SIPP_URI"]</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+PJSUA_EXPECTS = [[0, "registration success", ""]]</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml</span><br><span style="color: hsl(0, 100%, 40%);">-new file mode 100644</span><br><span style="color: hsl(0, 100%, 40%);">-index 000000000..bd4871940</span><br><span>---- /dev/null</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -0,0 +1,83 @@</span><br><span style="color: hsl(0, 100%, 40%);">-+<?xml version="1.0" encoding="ISO-8859-1" ?></span><br><span style="color: hsl(0, 100%, 40%);">-+<!DOCTYPE scenario SYSTEM "sipp.dtd"></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+<scenario name="Basic UAS responder"></span><br><span style="color: hsl(0, 100%, 40%);">-+  <recv request="REGISTER" crlf="true"></span><br><span style="color: hsl(0, 100%, 40%);">-+  </recv></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+  <send></span><br><span style="color: hsl(0, 100%, 40%);">-+    <![CDATA[</span><br><span style="color: hsl(0, 100%, 40%);">-+      SIP/2.0 100 Trying</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_Via:];received=1.1.1.1;rport=1111</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_From:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_To:];tag=[call_number]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_Call-ID:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_CSeq:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      Content-Length: 0</span><br><span style="color: hsl(0, 100%, 40%);">-+    ]]></span><br><span style="color: hsl(0, 100%, 40%);">-+  </send></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+  <send></span><br><span style="color: hsl(0, 100%, 40%);">-+    <![CDATA[</span><br><span style="color: hsl(0, 100%, 40%);">-+      SIP/2.0 401 Unauthorized</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_Via:];received=1.1.1.1;rport=1111</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_From:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_To:];tag=[call_number]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_Call-ID:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_CSeq:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=SHA-256, qop="auth"</span><br><span style="color: hsl(0, 100%, 40%);">-+      WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=MD5, qop="auth"</span><br><span style="color: hsl(0, 100%, 40%);">-+      WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=MD2, qop="auth"</span><br><span style="color: hsl(0, 100%, 40%);">-+      Content-Length: 0</span><br><span style="color: hsl(0, 100%, 40%);">-+    ]]></span><br><span style="color: hsl(0, 100%, 40%);">-+  </send></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+  <recv request="REGISTER" crlf="true"></span><br><span style="color: hsl(0, 100%, 40%);">-+    <action></span><br><span style="color: hsl(0, 100%, 40%);">-+      <ereg regexp=".*"</span><br><span style="color: hsl(0, 100%, 40%);">-+            search_in="hdr"</span><br><span style="color: hsl(0, 100%, 40%);">-+       header="Authorization:"</span><br><span style="color: hsl(0, 100%, 40%);">-+      assign_to="have_auth" /></span><br><span style="color: hsl(0, 100%, 40%);">-+    </action></span><br><span style="color: hsl(0, 100%, 40%);">-+  </recv></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+  <nop next="resp_okay" test="have_auth" /></span><br><span style="color: hsl(0, 100%, 40%);">-+  </span><br><span style="color: hsl(0, 100%, 40%);">-+  <send next="end"></span><br><span style="color: hsl(0, 100%, 40%);">-+    <![CDATA[</span><br><span style="color: hsl(0, 100%, 40%);">-+      SIP/2.0 403 no auth</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_Via:];received=1.1.1.1;rport=1111</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_From:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_To:];tag=[call_number]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_Call-ID:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_CSeq:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_Contact:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      Content-Length: 0</span><br><span style="color: hsl(0, 100%, 40%);">-+    ]]></span><br><span style="color: hsl(0, 100%, 40%);">-+  </send></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+  <label id="resp_okay" /></span><br><span style="color: hsl(0, 100%, 40%);">-+  </span><br><span style="color: hsl(0, 100%, 40%);">-+  <send></span><br><span style="color: hsl(0, 100%, 40%);">-+    <![CDATA[</span><br><span style="color: hsl(0, 100%, 40%);">-+      SIP/2.0 200 OK</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_Via:];received=1.1.1.1;rport=1111</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_From:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_To:];tag=[call_number]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_Call-ID:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_CSeq:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      [last_Contact:]</span><br><span style="color: hsl(0, 100%, 40%);">-+      Content-Length: 0</span><br><span style="color: hsl(0, 100%, 40%);">-+    ]]></span><br><span style="color: hsl(0, 100%, 40%);">-+  </send></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+  <label id="end" /></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+  <!-- definition of the response time repartition table (unit is ms)   --></span><br><span style="color: hsl(0, 100%, 40%);">-+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+  <!-- definition of the call length repartition table (unit is ms)     --></span><br><span style="color: hsl(0, 100%, 40%);">-+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+</scenario></span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.31.1</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/patches/0100-fix-double-stun-free.patch b/third-party/pjproject/patches/0100-fix-double-stun-free.patch</span><br><span>deleted file mode 100644</span><br><span>index b1cfcfd..0000000</span><br><span>--- a/third-party/pjproject/patches/0100-fix-double-stun-free.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,82 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-commit f0ff5817d0647bdecd1ec99488db9378e304cf83</span><br><span style="color: hsl(0, 100%, 40%);">-Author: sauwming <ming@teluu.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date:   Mon May 17 09:56:27 2021 +0800</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    Fix double free of stun session (#2709)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjnath/include/pjnath/stun_session.h b/pjnath/include/pjnath/stun_session.h</span><br><span style="color: hsl(0, 100%, 40%);">-index bee630ab4..afca06911 100644</span><br><span>---- a/pjnath/include/pjnath/stun_session.h</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjnath/include/pjnath/stun_session.h</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -341,6 +341,7 @@ struct pj_stun_tx_data</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_pool_t             *pool;          /**< Pool.                       */</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_stun_session      *sess;          /**< The STUN session.                   */</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_stun_msg          *msg;           /**< The STUN message.                   */</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_bool_t             is_destroying; /**< Is destroying?              */</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     void                *token;         /**< The token.                          */</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjnath/src/pjnath/stun_session.c b/pjnath/src/pjnath/stun_session.c</span><br><span style="color: hsl(0, 100%, 40%);">-index f2b4f7058..d436b94bf 100644</span><br><span>---- a/pjnath/src/pjnath/stun_session.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjnath/src/pjnath/stun_session.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -167,16 +167,27 @@ static void tdata_on_destroy(void *arg)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_stun_tx_data *tdata = (pj_stun_tx_data*)arg;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+    if (tdata->grp_lock) {</span><br><span style="color: hsl(0, 100%, 40%);">-+     pj_grp_lock_dec_ref(tdata->sess->grp_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_pool_safe_release(&tdata->pool);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">--    TRACE_((THIS_FILE, "tdata %p destroy request, force=%d, tsx=%p", tdata,</span><br><span style="color: hsl(0, 100%, 40%);">--      force, tdata->client_tsx));</span><br><span style="color: hsl(0, 100%, 40%);">-+    TRACE_((THIS_FILE,</span><br><span style="color: hsl(0, 100%, 40%);">-+          "tdata %p destroy request, force=%d, tsx=%p, destroying=%d",</span><br><span style="color: hsl(0, 100%, 40%);">-+         tdata, force, tdata->client_tsx, tdata->is_destroying));</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Just return if destroy has been requested before */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (tdata->is_destroying)</span><br><span style="color: hsl(0, 100%, 40%);">-+        return;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* STUN session may have been destroyed, except when tdata is cached. */</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+    tdata->is_destroying = PJ_TRUE;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     if (tdata->res_timer.id != PJ_FALSE) {</span><br><span style="color: hsl(0, 100%, 40%);">-    pj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  &tdata->res_timer, PJ_FALSE);</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -189,7 +200,6 @@ static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)</span><br><span style="color: hsl(0, 100%, 40%);">-           pj_stun_client_tsx_set_data(tdata->client_tsx, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (tdata->grp_lock) {</span><br><span style="color: hsl(0, 100%, 40%);">--          pj_grp_lock_dec_ref(tdata->sess->grp_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-       pj_grp_lock_dec_ref(tdata->grp_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-            tdata_on_destroy(tdata);</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -200,11 +210,11 @@ static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)</span><br><span style="color: hsl(0, 100%, 40%);">-        /* "Probably" this is to absorb retransmission */</span><br><span style="color: hsl(0, 100%, 40%);">-             pj_time_val delay = {0, 300};</span><br><span style="color: hsl(0, 100%, 40%);">-           pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay);</span><br><span style="color: hsl(0, 100%, 40%);">-+         tdata->is_destroying = PJ_FALSE;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-        } else {</span><br><span style="color: hsl(0, 100%, 40%);">-            pj_list_erase(tdata);</span><br><span style="color: hsl(0, 100%, 40%);">-           if (tdata->grp_lock) {</span><br><span style="color: hsl(0, 100%, 40%);">--          pj_grp_lock_dec_ref(tdata->sess->grp_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-               pj_grp_lock_dec_ref(tdata->grp_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-            } else {</span><br><span style="color: hsl(0, 100%, 40%);">-            tdata_on_destroy(tdata);</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -238,7 +248,7 @@ static void on_cache_timeout(pj_timer_heap_t *timer_heap,</span><br><span style="color: hsl(0, 100%, 40%);">-     sess = tdata->sess;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     pj_grp_lock_acquire(sess->grp_lock);</span><br><span style="color: hsl(0, 100%, 40%);">--    if (sess->is_destroying) {</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (sess->is_destroying || tdata->is_destroying) {</span><br><span style="color: hsl(0, 100%, 40%);">-    pj_grp_lock_release(sess->grp_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span>diff --git a/third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch b/third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch</span><br><span>deleted file mode 100644</span><br><span>index 81781f2..0000000</span><br><span>--- a/third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,166 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From bb92c97ea512aa0ef316c9b2335c7d57b84dfc9a Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: Nanang Izzuddin <nanang@teluu.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Wed, 16 Jun 2021 12:12:35 +0700</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH 1/2] - Avoid SSL socket parent/listener getting destroyed</span><br><span style="color: hsl(0, 100%, 40%);">- during handshake by increasing parent's reference count. - Add missing SSL</span><br><span style="color: hsl(0, 100%, 40%);">- socket close when the newly accepted SSL socket is discarded in SIP TLS</span><br><span style="color: hsl(0, 100%, 40%);">- transport.</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjlib/src/pj/ssl_sock_imp_common.c  | 44 +++++++++++++++++++++--------</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/pjsip/sip_transport_tls.c | 23 ++++++++++++++-</span><br><span style="color: hsl(0, 100%, 40%);">- 2 files changed, 55 insertions(+), 12 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c</span><br><span style="color: hsl(0, 100%, 40%);">-index bc468bcb3..abec31805 100644</span><br><span>---- a/pjlib/src/pj/ssl_sock_imp_common.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjlib/src/pj/ssl_sock_imp_common.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -224,6 +224,8 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Accepting */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ssock->is_server) {</span><br><span style="color: hsl(0, 100%, 40%);">-+ pj_bool_t ret = PJ_TRUE;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-       if (status != PJ_SUCCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">-         /* Handshake failed in accepting, destroy our self silently. */</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -241,6 +243,12 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,</span><br><span style="color: hsl(0, 100%, 40%);">-                 status);</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+     /* Decrement ref count of parent */</span><br><span style="color: hsl(0, 100%, 40%);">-+            if (ssock->parent->param.grp_lock) {</span><br><span style="color: hsl(0, 100%, 40%);">-+         pj_grp_lock_dec_ref(ssock->parent->param.grp_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-+              ssock->parent = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+           }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Originally, this is a workaround for ticket #985. However,</span><br><span style="color: hsl(0, 100%, 40%);">-            * a race condition may occur in multiple worker threads</span><br><span style="color: hsl(0, 100%, 40%);">-         * environment when we are destroying SSL objects while other</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -284,23 +292,29 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-        return PJ_FALSE;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Notify application the newly accepted SSL socket */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (ssock->param.cb.on_accept_complete2) {</span><br><span style="color: hsl(0, 100%, 40%);">--      pj_bool_t ret;</span><br><span style="color: hsl(0, 100%, 40%);">-          ret = (*ssock->param.cb.on_accept_complete2) </span><br><span style="color: hsl(0, 100%, 40%);">-                (ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr, </span><br><span style="color: hsl(0, 100%, 40%);">-                     pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr), </span><br><span style="color: hsl(0, 100%, 40%);">-                  status);</span><br><span style="color: hsl(0, 100%, 40%);">--       if (ret == PJ_FALSE)</span><br><span style="color: hsl(0, 100%, 40%);">--               return PJ_FALSE;        </span><br><span style="color: hsl(0, 100%, 40%);">-        } else if (ssock->param.cb.on_accept_complete) {</span><br><span style="color: hsl(0, 100%, 40%);">--        pj_bool_t ret;</span><br><span style="color: hsl(0, 100%, 40%);">-          ret = (*ssock->param.cb.on_accept_complete)</span><br><span style="color: hsl(0, 100%, 40%);">-                    (ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr,</span><br><span style="color: hsl(0, 100%, 40%);">-                       pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr));</span><br><span style="color: hsl(0, 100%, 40%);">--      if (ret == PJ_FALSE)</span><br><span style="color: hsl(0, 100%, 40%);">--               return PJ_FALSE;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+     /* Decrement ref count of parent and reset parent (we don't need it</span><br><span style="color: hsl(0, 100%, 40%);">-+         * anymore, right?).</span><br><span style="color: hsl(0, 100%, 40%);">-+    */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (ssock->parent->param.grp_lock) {</span><br><span style="color: hsl(0, 100%, 40%);">-+         pj_grp_lock_dec_ref(ssock->parent->param.grp_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-+      ssock->parent = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+   }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+     if (ret == PJ_FALSE)</span><br><span style="color: hsl(0, 100%, 40%);">-+       return PJ_FALSE;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Connecting */</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -864,9 +878,13 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,</span><br><span style="color: hsl(0, 100%, 40%);">-     if (status != PJ_SUCCESS)</span><br><span style="color: hsl(0, 100%, 40%);">-   goto on_return;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Set parent and add ref count (avoid parent destroy during handshake) */</span><br><span style="color: hsl(0, 100%, 40%);">-+    ssock->parent = ssock_parent;</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (ssock->parent->param.grp_lock)</span><br><span style="color: hsl(0, 100%, 40%);">-+      pj_grp_lock_add_ref(ssock->parent->param.grp_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Update new SSL socket attributes */</span><br><span style="color: hsl(0, 100%, 40%);">-     ssock->sock = newsock;</span><br><span style="color: hsl(0, 100%, 40%);">--    ssock->parent = ssock_parent;</span><br><span style="color: hsl(0, 100%, 40%);">-     ssock->is_server = PJ_TRUE;</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ssock_parent->cert) {</span><br><span style="color: hsl(0, 100%, 40%);">-    status = pj_ssl_sock_set_certificate(ssock, ssock->pool, </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -913,16 +931,20 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,</span><br><span style="color: hsl(0, 100%, 40%);">-     ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool, </span><br><span style="color: hsl(0, 100%, 40%);">-                                                ssock->param.async_cnt,</span><br><span style="color: hsl(0, 100%, 40%);">-                                              sizeof(void*));</span><br><span style="color: hsl(0, 100%, 40%);">--    if (!ssock->asock_rbuf)</span><br><span style="color: hsl(0, 100%, 40%);">--        return PJ_ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!ssock->asock_rbuf) {</span><br><span style="color: hsl(0, 100%, 40%);">-+               status = PJ_ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">-+            goto on_return;</span><br><span style="color: hsl(0, 100%, 40%);">-+        }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     for (i = 0; i<ssock->param.async_cnt; ++i) {</span><br><span style="color: hsl(0, 100%, 40%);">--      ssock->asock_rbuf[i] = (void*) pj_pool_alloc(</span><br><span style="color: hsl(0, 100%, 40%);">-+               ssock->asock_rbuf[i] = (void*) pj_pool_alloc(</span><br><span style="color: hsl(0, 100%, 40%);">-                                            ssock->pool, </span><br><span style="color: hsl(0, 100%, 40%);">-                                        ssock->param.read_buffer_size + </span><br><span style="color: hsl(0, 100%, 40%);">-                                             sizeof(read_data_t*));</span><br><span style="color: hsl(0, 100%, 40%);">--        if (!ssock->asock_rbuf[i])</span><br><span style="color: hsl(0, 100%, 40%);">--            return PJ_ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">-+         if (!ssock->asock_rbuf[i]) {</span><br><span style="color: hsl(0, 100%, 40%);">-+                        status = PJ_ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">-+                    goto on_return;</span><br><span style="color: hsl(0, 100%, 40%);">-+                }</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Create active socket */</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c</span><br><span style="color: hsl(0, 100%, 40%);">-index 17b7ae3de..ce524d53f 100644</span><br><span>---- a/pjsip/src/pjsip/sip_transport_tls.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/pjsip/sip_transport_tls.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1325,9 +1325,26 @@ static pj_bool_t on_accept_complete2(pj_ssl_sock_t *ssock,</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_UNUSED_ARG(src_addr_len);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     listener = (struct tls_listener*) pj_ssl_sock_get_user_data(ssock);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!listener) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   /* Listener already destroyed, e.g: after TCP accept but before SSL</span><br><span style="color: hsl(0, 100%, 40%);">-+     * handshake is completed.</span><br><span style="color: hsl(0, 100%, 40%);">-+      */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (new_ssock && accept_status == PJ_SUCCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">-+            /* Close the SSL socket if the accept op is successful */</span><br><span style="color: hsl(0, 100%, 40%);">-+      PJ_LOG(4,(THIS_FILE,</span><br><span style="color: hsl(0, 100%, 40%);">-+                     "Incoming TLS connection from %s (sock=%d) is discarded "</span><br><span style="color: hsl(0, 100%, 40%);">-+                    "because listener is already destroyed",</span><br><span style="color: hsl(0, 100%, 40%);">-+                     pj_sockaddr_print(src_addr, addr, sizeof(addr), 3),</span><br><span style="color: hsl(0, 100%, 40%);">-+                    new_ssock));</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+        pj_ssl_sock_close(new_ssock);</span><br><span style="color: hsl(0, 100%, 40%);">-+      }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+     return PJ_FALSE;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     if (accept_status != PJ_SUCCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">-- if (listener && listener->tls_setting.on_accept_fail_cb) {</span><br><span style="color: hsl(0, 100%, 40%);">-+  if (listener->tls_setting.on_accept_fail_cb) {</span><br><span style="color: hsl(0, 100%, 40%);">-           pjsip_tls_on_accept_fail_param param;</span><br><span style="color: hsl(0, 100%, 40%);">-           pj_ssl_sock_info ssi;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1350,6 +1367,8 @@ static pj_bool_t on_accept_complete2(pj_ssl_sock_t *ssock,</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_ASSERT_RETURN(new_ssock, PJ_TRUE);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!listener->is_registered) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   pj_ssl_sock_close(new_ssock);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-  if (listener->tls_setting.on_accept_fail_cb) {</span><br><span style="color: hsl(0, 100%, 40%);">-           pjsip_tls_on_accept_fail_param param;</span><br><span style="color: hsl(0, 100%, 40%);">-           pj_bzero(&param, sizeof(param));</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1401,6 +1420,8 @@ static pj_bool_t on_accept_complete2(pj_ssl_sock_t *ssock,</span><br><span style="color: hsl(0, 100%, 40%);">-                         ssl_info.grp_lock, &tls);</span><br><span style="color: hsl(0, 100%, 40%);">-     </span><br><span style="color: hsl(0, 100%, 40%);">-     if (status != PJ_SUCCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_ssl_sock_close(new_ssock);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-  if (listener->tls_setting.on_accept_fail_cb) {</span><br><span style="color: hsl(0, 100%, 40%);">-           pjsip_tls_on_accept_fail_param param;</span><br><span style="color: hsl(0, 100%, 40%);">-           pj_bzero(&param, sizeof(param));</span><br><span>diff --git a/third-party/pjproject/patches/0111-ssl-premature-destroy.patch b/third-party/pjproject/patches/0111-ssl-premature-destroy.patch</span><br><span>deleted file mode 100644</span><br><span>index 9de2915..0000000</span><br><span>--- a/third-party/pjproject/patches/0111-ssl-premature-destroy.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,136 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From 68c69f516f95df1faa42e5647e9ce7cfdc41ac38 Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: Nanang Izzuddin <nanang@teluu.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Wed, 16 Jun 2021 12:15:29 +0700</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH 2/2] - Fix silly mistake: accepted active socket created</span><br><span style="color: hsl(0, 100%, 40%);">- without group lock in SSL socket. - Replace assertion with normal validation</span><br><span style="color: hsl(0, 100%, 40%);">- check of SSL socket instance in OpenSSL verification callback (verify_cb())</span><br><span style="color: hsl(0, 100%, 40%);">- to avoid crash, e.g: if somehow race condition with SSL socket destroy</span><br><span style="color: hsl(0, 100%, 40%);">- happens or OpenSSL application data index somehow gets corrupted.</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjlib/src/pj/ssl_sock_imp_common.c |  3 +-</span><br><span style="color: hsl(0, 100%, 40%);">- pjlib/src/pj/ssl_sock_ossl.c       | 45 +++++++++++++++++++++++++-----</span><br><span style="color: hsl(0, 100%, 40%);">- 2 files changed, 40 insertions(+), 8 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c</span><br><span style="color: hsl(0, 100%, 40%);">-index bc468bcb3..c2b8a846b 100644</span><br><span>---- a/pjlib/src/pj/ssl_sock_imp_common.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjlib/src/pj/ssl_sock_imp_common.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -927,6 +927,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Create active socket */</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_activesock_cfg_default(&asock_cfg);</span><br><span style="color: hsl(0, 100%, 40%);">-+    asock_cfg.grp_lock = ssock->param.grp_lock;</span><br><span style="color: hsl(0, 100%, 40%);">-     asock_cfg.async_cnt = ssock->param.async_cnt;</span><br><span style="color: hsl(0, 100%, 40%);">-     asock_cfg.concurrency = ssock->param.concurrency;</span><br><span style="color: hsl(0, 100%, 40%);">-     asock_cfg.whole_data = PJ_TRUE;</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -942,7 +943,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,</span><br><span style="color: hsl(0, 100%, 40%);">-       goto on_return;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-    pj_grp_lock_add_ref(glock);</span><br><span style="color: hsl(0, 100%, 40%);">--    asock_cfg.grp_lock = ssock->param.grp_lock = glock;</span><br><span style="color: hsl(0, 100%, 40%);">-+ ssock->param.grp_lock = glock;</span><br><span style="color: hsl(0, 100%, 40%);">-       pj_grp_lock_add_handler(ssock->param.grp_lock, ssock->pool, ssock,</span><br><span style="color: hsl(0, 100%, 40%);">-                                ssl_on_destroy);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c</span><br><span style="color: hsl(0, 100%, 40%);">-index a95b339a5..56841f80a 100644</span><br><span>---- a/pjlib/src/pj/ssl_sock_ossl.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjlib/src/pj/ssl_sock_ossl.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -327,7 +327,8 @@ static pj_status_t STATUS_FROM_SSL_ERR(char *action, pj_ssl_sock_t *ssock,</span><br><span style="color: hsl(0, 100%, 40%);">-   ERROR_LOG("STATUS_FROM_SSL_ERR", err, ssock);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    ssock->last_err = err;</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (ssock)</span><br><span style="color: hsl(0, 100%, 40%);">-+    ssock->last_err = err;</span><br><span style="color: hsl(0, 100%, 40%);">-     return GET_STATUS_FROM_SSL_ERR(err);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -344,7 +345,8 @@ static pj_status_t STATUS_FROM_SSL_ERR2(char *action, pj_ssl_sock_t *ssock,</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Dig for more from OpenSSL error queue */</span><br><span style="color: hsl(0, 100%, 40%);">-     SSLLogErrors(action, ret, err, len, ssock);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    ssock->last_err = ssl_err;</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (ssock)</span><br><span style="color: hsl(0, 100%, 40%);">-+ ssock->last_err = ssl_err;</span><br><span style="color: hsl(0, 100%, 40%);">-     return GET_STATUS_FROM_SSL_ERR(ssl_err);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -587,6 +589,13 @@ static pj_status_t init_openssl(void)</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Create OpenSSL application data index for SSL socket */</span><br><span style="color: hsl(0, 100%, 40%);">-     sslsock_idx = SSL_get_ex_new_index(0, "SSL socket", NULL, NULL, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+   if (sslsock_idx == -1) {</span><br><span style="color: hsl(0, 100%, 40%);">-+               status = STATUS_FROM_SSL_ERR2("Init", NULL, -1, ERR_get_error(), 0);</span><br><span style="color: hsl(0, 100%, 40%);">-+         PJ_LOG(1,(THIS_FILE,</span><br><span style="color: hsl(0, 100%, 40%);">-+                             "Fatal error: failed to get application data index for "</span><br><span style="color: hsl(0, 100%, 40%);">-+                             "SSL socket"));</span><br><span style="color: hsl(0, 100%, 40%);">-+            return status;</span><br><span style="color: hsl(0, 100%, 40%);">-+ }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     return status;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -614,21 +623,36 @@ static int password_cb(char *buf, int num, int rwflag, void *user_data)</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--/* SSL password callback. */</span><br><span style="color: hsl(0, 100%, 40%);">-+/* SSL certificate verification result callback.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Note that this callback seems to be always called from library worker</span><br><span style="color: hsl(0, 100%, 40%);">-+ * thread, e.g: active socket on_read_complete callback, which should have</span><br><span style="color: hsl(0, 100%, 40%);">-+ * already been equipped with race condition avoidance mechanism (should not</span><br><span style="color: hsl(0, 100%, 40%);">-+ * be destroyed while callback is being invoked).</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">- static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">--    pj_ssl_sock_t *ssock;</span><br><span style="color: hsl(0, 100%, 40%);">--    SSL *ossl_ssl;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_ssl_sock_t *ssock = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+    SSL *ossl_ssl = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-     int err;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Get SSL instance */</span><br><span style="color: hsl(0, 100%, 40%);">-     ossl_ssl = X509_STORE_CTX_get_ex_data(x509_ctx, </span><br><span style="color: hsl(0, 100%, 40%);">-                              SSL_get_ex_data_X509_STORE_CTX_idx());</span><br><span style="color: hsl(0, 100%, 40%);">--    pj_assert(ossl_ssl);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!ossl_ssl) {</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_LOG(1,(THIS_FILE,</span><br><span style="color: hsl(0, 100%, 40%);">-+             "SSL verification callback failed to get SSL instance"));</span><br><span style="color: hsl(0, 100%, 40%);">-+  goto on_return;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Get SSL socket instance */</span><br><span style="color: hsl(0, 100%, 40%);">-     ssock = SSL_get_ex_data(ossl_ssl, sslsock_idx);</span><br><span style="color: hsl(0, 100%, 40%);">--    pj_assert(ssock);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!ssock) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   /* SSL socket may have been destroyed */</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_LOG(1,(THIS_FILE,</span><br><span style="color: hsl(0, 100%, 40%);">-+             "SSL verification callback failed to get SSL socket "</span><br><span style="color: hsl(0, 100%, 40%);">-+                "instance (sslsock_idx=%d).", sslsock_idx));</span><br><span style="color: hsl(0, 100%, 40%);">-+       goto on_return;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* Store verification status */</span><br><span style="color: hsl(0, 100%, 40%);">-     err = X509_STORE_CTX_get_error(x509_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -706,6 +730,7 @@ static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)</span><br><span style="color: hsl(0, 100%, 40%);">-     if (PJ_FALSE == ssock->param.verify_peer)</span><br><span style="color: hsl(0, 100%, 40%);">-   preverify_ok = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+on_return:</span><br><span style="color: hsl(0, 100%, 40%);">-     return preverify_ok;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1213,6 +1238,12 @@ static void ssl_destroy(pj_ssl_sock_t *ssock)</span><br><span style="color: hsl(0, 100%, 40%);">- static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     ossl_sock_t *ossock = (ossl_sock_t *)ssock;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Detach from SSL instance */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (ossock->ossl_ssl) {</span><br><span style="color: hsl(0, 100%, 40%);">-+      SSL_set_ex_data(ossock->ossl_ssl, sslsock_idx, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     /**</span><br><span style="color: hsl(0, 100%, 40%);">-      * Avoid calling SSL_shutdown() if handshake wasn't completed.</span><br><span style="color: hsl(0, 100%, 40%);">-      * OpenSSL 1.0.2f complains if SSL_shutdown() is called during an</span><br><span>diff --git a/third-party/pjproject/patches/0120-pjmedia_sdp_attr_get_rtpmap-Strip-param-trailing-whi.patch b/third-party/pjproject/patches/0120-pjmedia_sdp_attr_get_rtpmap-Strip-param-trailing-whi.patch</span><br><span>deleted file mode 100644</span><br><span>index 1b1fcad..0000000</span><br><span>--- a/third-party/pjproject/patches/0120-pjmedia_sdp_attr_get_rtpmap-Strip-param-trailing-whi.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,32 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From 2ae784030b0d9cf217c3d562af20e4967f19a3dc Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: George Joseph <gjoseph@sangoma.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Tue, 14 Sep 2021 10:47:29 -0600</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH] pjmedia_sdp_attr_get_rtpmap: Strip param trailing whitespace</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-Use pj_scan_get() to parse the param part of rtpmap so</span><br><span style="color: hsl(0, 100%, 40%);">-trailing whitespace is automatically stripped.</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-Fixes #2827</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjmedia/src/pjmedia/sdp.c | 4 ++--</span><br><span style="color: hsl(0, 100%, 40%);">- 1 file changed, 2 insertions(+), 2 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjmedia/src/pjmedia/sdp.c b/pjmedia/src/pjmedia/sdp.c</span><br><span style="color: hsl(0, 100%, 40%);">-index 5d05a0d9c..3448749c9 100644</span><br><span>---- a/pjmedia/src/pjmedia/sdp.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjmedia/src/pjmedia/sdp.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -313,9 +313,9 @@ PJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtpmap( const pjmedia_sdp_attr *attr,</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-  /* Expecting either '/' or EOF */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (*scanner.curptr == '/') {</span><br><span style="color: hsl(0, 100%, 40%);">-+      /* Skip the '/' */</span><br><span style="color: hsl(0, 100%, 40%);">-      pj_scan_get_char(&scanner);</span><br><span style="color: hsl(0, 100%, 40%);">--        rtpmap->param.ptr = scanner.curptr;</span><br><span style="color: hsl(0, 100%, 40%);">--         rtpmap->param.slen = scanner.end - scanner.curptr;</span><br><span style="color: hsl(0, 100%, 40%);">-+          pj_scan_get(&scanner, &cs_token, &rtpmap->param);</span><br><span style="color: hsl(0, 100%, 40%);">-    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-            rtpmap->param.slen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.31.1</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch b/third-party/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch</span><br><span>deleted file mode 100644</span><br><span>index 91feefb..0000000</span><br><span>--- a/third-party/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,661 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From 0ed41eb5fd0e4192e1b7dc374f819d17aef3e805 Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: George Joseph <gtjoseph@users.noreply.github.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Tue, 21 Dec 2021 19:32:22 -0700</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH] sip_inv:  Additional multipart support (#2919) (#2920)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/include/pjsip-ua/sip_inv.h       | 108 ++++++++++-</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/pjsip-ua/sip_inv.c           | 240 ++++++++++++++++++++-----</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/test/inv_offer_answer_test.c | 103 ++++++++++-</span><br><span style="color: hsl(0, 100%, 40%);">- 3 files changed, 394 insertions(+), 57 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/include/pjsip-ua/sip_inv.h b/pjsip/include/pjsip-ua/sip_inv.h</span><br><span style="color: hsl(0, 100%, 40%);">-index 14f2d23fa..c33551786 100644</span><br><span>---- a/pjsip/include/pjsip-ua/sip_inv.h</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/include/pjsip-ua/sip_inv.h</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -451,11 +451,11 @@ struct pjsip_inv_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(0, 100%, 40%);">- /**</span><br><span style="color: hsl(0, 100%, 40%);">-- * This structure represents SDP information in a pjsip_rx_data. Application</span><br><span style="color: hsl(0, 100%, 40%);">-- * retrieve this information by calling #pjsip_rdata_get_sdp_info(). This</span><br><span style="color: hsl(0, 100%, 40%);">-+ * This structure represents SDP information in a pjsip_(rx|tx)_data. Application</span><br><span style="color: hsl(0, 100%, 40%);">-+ * retrieve this information by calling #pjsip_get_sdp_info(). This</span><br><span style="color: hsl(0, 100%, 40%);">-  * mechanism supports multipart message body.</span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">--typedef struct pjsip_rdata_sdp_info</span><br><span style="color: hsl(0, 100%, 40%);">-+typedef struct pjsip_sdp_info</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     /**</span><br><span style="color: hsl(0, 100%, 40%);">-      * Pointer and length of the text body in the incoming message. If</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -475,7 +475,15 @@ typedef struct pjsip_rdata_sdp_info</span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span style="color: hsl(0, 100%, 40%);">-     pjmedia_sdp_session *sdp;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--} pjsip_rdata_sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+} pjsip_sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * For backwards compatibility and completeness,</span><br><span style="color: hsl(0, 100%, 40%);">-+ * pjsip_rdata_sdp_info and pjsip_tdata_sdp_info</span><br><span style="color: hsl(0, 100%, 40%);">-+ * are typedef'd to pjsip_sdp_info.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+typedef pjsip_sdp_info pjsip_rdata_sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+typedef pjsip_sdp_info pjsip_tdata_sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- /**</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1045,6 +1053,44 @@ PJ_DECL(pj_status_t) pjsip_create_sdp_body(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-                                            pjmedia_sdp_session *sdp,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       pjsip_msg_body **p_body);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * This is a utility function to create a multipart body with the</span><br><span style="color: hsl(0, 100%, 40%);">-+ * SIP body as the first part.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param pool            Pool to allocate memory.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param sdp          SDP session to be put in the SIP message body.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param p_body Pointer to receive SIP message body containing</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                       the SDP session.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return          PJ_SUCCESS on success.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(pj_status_t) pjsip_create_multipart_sdp_body( pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                           pjmedia_sdp_session *sdp,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                           pjsip_msg_body **p_body);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Retrieve SDP information from a message body. Application should</span><br><span style="color: hsl(0, 100%, 40%);">-+ * prefer to use this function rather than parsing the SDP manually since</span><br><span style="color: hsl(0, 100%, 40%);">-+ * this function supports multipart message body.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * This function will only parse the SDP once, the first time it is called</span><br><span style="color: hsl(0, 100%, 40%);">-+ * on the same message. Subsequent call on the same message will just pick</span><br><span style="color: hsl(0, 100%, 40%);">-+ * up the already parsed SDP from the message.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param pool               Pool to allocate memory.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param body               The message body.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param msg_media_type     From the rdata or tdata Content-Type header, if available.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                           If NULL, the content_type from the body will be used.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param search_media_type  The media type to search for.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                           If NULL, "application/sdp" will be used.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return                   The SDP info.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(pjsip_sdp_info*) pjsip_get_sdp_info(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                     pjsip_msg_body *body,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                          pjsip_media_type *msg_media_type,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                      const pjsip_media_type *search_media_type);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">- /**</span><br><span style="color: hsl(0, 100%, 40%);">-  * Retrieve SDP information from an incoming message. Application should</span><br><span style="color: hsl(0, 100%, 40%);">-  * prefer to use this function rather than parsing the SDP manually since</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1061,6 +1107,60 @@ PJ_DECL(pj_status_t) pjsip_create_sdp_body(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">- PJ_DECL(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Retrieve SDP information from an incoming message. Application should</span><br><span style="color: hsl(0, 100%, 40%);">-+ * prefer to use this function rather than parsing the SDP manually since</span><br><span style="color: hsl(0, 100%, 40%);">-+ * this function supports multipart message body.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * This function will only parse the SDP once, the first time it is called</span><br><span style="color: hsl(0, 100%, 40%);">-+ * on the same message. Subsequent call on the same message will just pick</span><br><span style="color: hsl(0, 100%, 40%);">-+ * up the already parsed SDP from the message.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param rdata               The incoming message.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param search_media_type   The SDP media type to search for.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                            If NULL, "application/sdp" will be used.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return                    The SDP info.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info2(</span><br><span style="color: hsl(0, 100%, 40%);">-+                                            pjsip_rx_data *rdata,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                          const pjsip_media_type *search_media_type);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Retrieve SDP information from an outgoing message. Application should</span><br><span style="color: hsl(0, 100%, 40%);">-+ * prefer to use this function rather than parsing the SDP manually since</span><br><span style="color: hsl(0, 100%, 40%);">-+ * this function supports multipart message body.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * This function will only parse the SDP once, the first time it is called</span><br><span style="color: hsl(0, 100%, 40%);">-+ * on the same message. Subsequent call on the same message will just pick</span><br><span style="color: hsl(0, 100%, 40%);">-+ * up the already parsed SDP from the message.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param tdata    The outgoing message.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return         The SDP info.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info(pjsip_tx_data *tdata);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Retrieve SDP information from an outgoing message. Application should</span><br><span style="color: hsl(0, 100%, 40%);">-+ * prefer to use this function rather than parsing the SDP manually since</span><br><span style="color: hsl(0, 100%, 40%);">-+ * this function supports multipart message body.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * This function will only parse the SDP once, the first time it is called</span><br><span style="color: hsl(0, 100%, 40%);">-+ * on the same message. Subsequent call on the same message will just pick</span><br><span style="color: hsl(0, 100%, 40%);">-+ * up the already parsed SDP from the message.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param tdata               The outgoing message.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param search_media_type   The SDP media type to search for.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                            If NULL, "application/sdp" will be used.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return                    The SDP info.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info2(</span><br><span style="color: hsl(0, 100%, 40%);">-+                                        pjsip_tx_data *tdata,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                          const pjsip_media_type *search_media_type);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">- PJ_END_DECL</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- /**</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c</span><br><span style="color: hsl(0, 100%, 40%);">-index ca225015b..b68ae0f16 100644</span><br><span>---- a/pjsip/src/pjsip-ua/sip_inv.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/pjsip-ua/sip_inv.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -118,6 +118,8 @@ static pj_status_t handle_timer_response(pjsip_inv_session *inv,</span><br><span style="color: hsl(0, 100%, 40%);">- static pj_bool_t inv_check_secure_dlg(pjsip_inv_session *inv,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 pjsip_event *e);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+static int print_sdp(pjsip_msg_body *body, char *buf, pj_size_t len);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">- static void (*inv_state_handler[])( pjsip_inv_session *inv, pjsip_event *e) = </span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     &inv_on_state_null,</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -946,66 +948,170 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uac( pjsip_dialog *dlg,</span><br><span style="color: hsl(0, 100%, 40%);">-     return PJ_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata)</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(pjsip_sdp_info*) pjsip_get_sdp_info(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                           pjsip_msg_body *body,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                           pjsip_media_type *msg_media_type,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                           const pjsip_media_type *search_media_type)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">--    pjsip_rdata_sdp_info *sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">--    pjsip_msg_body *body = rdata->msg_info.msg->body;</span><br><span style="color: hsl(0, 100%, 40%);">--    pjsip_ctype_hdr *ctype_hdr = rdata->msg_info.ctype;</span><br><span style="color: hsl(0, 100%, 40%);">--    pjsip_media_type app_sdp;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_sdp_info *sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type search_type;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type multipart_mixed;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type multipart_alternative;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type *msg_type;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_status_t status;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    sdp_info = (pjsip_rdata_sdp_info*)</span><br><span style="color: hsl(0, 100%, 40%);">--            rdata->endpt_info.mod_data[mod_inv.mod.id];</span><br><span style="color: hsl(0, 100%, 40%);">--    if (sdp_info)</span><br><span style="color: hsl(0, 100%, 40%);">--        return sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+    sdp_info = PJ_POOL_ZALLOC_T(pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                pjsip_sdp_info);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    sdp_info = PJ_POOL_ZALLOC_T(rdata->tp_info.pool,</span><br><span style="color: hsl(0, 100%, 40%);">--                               pjsip_rdata_sdp_info);</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_ASSERT_RETURN(mod_inv.mod.id >= 0, sdp_info);</span><br><span style="color: hsl(0, 100%, 40%);">--    rdata->endpt_info.mod_data[mod_inv.mod.id] = sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    pjsip_media_type_init2(&app_sdp, "application", "sdp");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!body) {</span><br><span style="color: hsl(0, 100%, 40%);">-+        return sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    if (body && ctype_hdr &&</span><br><span style="color: hsl(0, 100%, 40%);">--        pj_stricmp(&ctype_hdr->media.type, &app_sdp.type)==0 &&</span><br><span style="color: hsl(0, 100%, 40%);">--     pj_stricmp(&ctype_hdr->media.subtype, &app_sdp.subtype)==0)</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (msg_media_type) {</span><br><span style="color: hsl(0, 100%, 40%);">-+       msg_type = msg_media_type;</span><br><span style="color: hsl(0, 100%, 40%);">-+    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-+        if (body->content_type.type.slen == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-+        return sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+   }</span><br><span style="color: hsl(0, 100%, 40%);">-+      msg_type = &body->content_type;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!search_media_type) {</span><br><span style="color: hsl(0, 100%, 40%);">-+        pjsip_media_type_init2(&search_type, "application", "sdp");</span><br><span style="color: hsl(0, 100%, 40%);">-+    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-+        pj_memcpy(&search_type, search_media_type, sizeof(search_type));</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type_init2(&multipart_mixed, "multipart", "mixed");</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type_init2(&multipart_alternative, "multipart", "alternative");</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (pjsip_media_type_cmp(msg_type, &search_type, PJ_FALSE) == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-     {</span><br><span style="color: hsl(0, 100%, 40%);">--   sdp_info->body.ptr = (char*)body->data;</span><br><span style="color: hsl(0, 100%, 40%);">--  sdp_info->body.slen = body->len;</span><br><span style="color: hsl(0, 100%, 40%);">--    } else if  (body && ctype_hdr &&</span><br><span style="color: hsl(0, 100%, 40%);">--            pj_stricmp2(&ctype_hdr->media.type, "multipart")==0 &&</span><br><span style="color: hsl(0, 100%, 40%);">--                (pj_stricmp2(&ctype_hdr->media.subtype, "mixed")==0 ||</span><br><span style="color: hsl(0, 100%, 40%);">--                 pj_stricmp2(&ctype_hdr->media.subtype, "alternative")==0))</span><br><span style="color: hsl(0, 100%, 40%);">-+   /*</span><br><span style="color: hsl(0, 100%, 40%);">-+      * If the print_body function is print_sdp, we know that</span><br><span style="color: hsl(0, 100%, 40%);">-+        * body->data is a pjmedia_sdp_session object and came from</span><br><span style="color: hsl(0, 100%, 40%);">-+  * a tx_data.  If not, it's the text representation of the</span><br><span style="color: hsl(0, 100%, 40%);">-+  * sdp from an rx_data.</span><br><span style="color: hsl(0, 100%, 40%);">-+         */</span><br><span style="color: hsl(0, 100%, 40%);">-+        if (body->print_body == print_sdp) {</span><br><span style="color: hsl(0, 100%, 40%);">-+            sdp_info->sdp = body->data;</span><br><span style="color: hsl(0, 100%, 40%);">-+        } else {</span><br><span style="color: hsl(0, 100%, 40%);">-+            sdp_info->body.ptr = (char*)body->data;</span><br><span style="color: hsl(0, 100%, 40%);">-+            sdp_info->body.slen = body->len;</span><br><span style="color: hsl(0, 100%, 40%);">-+        }</span><br><span style="color: hsl(0, 100%, 40%);">-+    } else if (pjsip_media_type_cmp(&multipart_mixed, msg_type, PJ_FALSE) == 0 ||</span><br><span style="color: hsl(0, 100%, 40%);">-+        pjsip_media_type_cmp(&multipart_alternative, msg_type, PJ_FALSE) == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-     {</span><br><span style="color: hsl(0, 100%, 40%);">--       pjsip_multipart_part *part;</span><br><span style="color: hsl(0, 100%, 40%);">-+        pjsip_multipart_part *part;</span><br><span style="color: hsl(0, 100%, 40%);">-+        part = pjsip_multipart_find_part(body, &search_type, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+        if (part) {</span><br><span style="color: hsl(0, 100%, 40%);">-+            if (part->body->print_body == print_sdp) {</span><br><span style="color: hsl(0, 100%, 40%);">-+                sdp_info->sdp = part->body->data;</span><br><span style="color: hsl(0, 100%, 40%);">-+            } else {</span><br><span style="color: hsl(0, 100%, 40%);">-+                sdp_info->body.ptr = (char*)part->body->data;</span><br><span style="color: hsl(0, 100%, 40%);">-+                sdp_info->body.slen = part->body->len;</span><br><span style="color: hsl(0, 100%, 40%);">-+            }</span><br><span style="color: hsl(0, 100%, 40%);">-+        }</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-- part = pjsip_multipart_find_part(body, &app_sdp, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">--    if (part) {</span><br><span style="color: hsl(0, 100%, 40%);">--        sdp_info->body.ptr = (char*)part->body->data;</span><br><span style="color: hsl(0, 100%, 40%);">--         sdp_info->body.slen = part->body->len;</span><br><span style="color: hsl(0, 100%, 40%);">--    }</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-+     * If the body was already a pjmedia_sdp_session, we can just</span><br><span style="color: hsl(0, 100%, 40%);">-+     * return it.  If not and there wasn't a text representation</span><br><span style="color: hsl(0, 100%, 40%);">-+     * of the sdp either, we can also just return.</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (sdp_info->sdp || !sdp_info->body.ptr) {</span><br><span style="color: hsl(0, 100%, 40%);">-+       return sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    if (sdp_info->body.ptr) {</span><br><span style="color: hsl(0, 100%, 40%);">--       pj_status_t status;</span><br><span style="color: hsl(0, 100%, 40%);">--    status = pjmedia_sdp_parse(rdata->tp_info.pool,</span><br><span style="color: hsl(0, 100%, 40%);">--                                sdp_info->body.ptr,</span><br><span style="color: hsl(0, 100%, 40%);">--                                 sdp_info->body.slen,</span><br><span style="color: hsl(0, 100%, 40%);">--                                &sdp_info->sdp);</span><br><span style="color: hsl(0, 100%, 40%);">--     if (status == PJ_SUCCESS)</span><br><span style="color: hsl(0, 100%, 40%);">--          status = pjmedia_sdp_validate2(sdp_info->sdp, PJ_FALSE);</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-+     * If the body was the text representation of teh SDP, we need</span><br><span style="color: hsl(0, 100%, 40%);">-+     * to parse it to create a pjmedia_sdp_session object.</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-+    status = pjmedia_sdp_parse(pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              sdp_info->body.ptr,</span><br><span style="color: hsl(0, 100%, 40%);">-+                         sdp_info->body.slen,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                &sdp_info->sdp);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (status == PJ_SUCCESS)</span><br><span style="color: hsl(0, 100%, 40%);">-+  status = pjmedia_sdp_validate2(sdp_info->sdp, PJ_FALSE);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--   if (status != PJ_SUCCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">--        sdp_info->sdp = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">--       PJ_PERROR(1,(THIS_FILE, status,</span><br><span style="color: hsl(0, 100%, 40%);">--                     "Error parsing/validating SDP body"));</span><br><span style="color: hsl(0, 100%, 40%);">--      }</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (status != PJ_SUCCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">-+      sdp_info->sdp = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_PERROR(1, (THIS_FILE, status,</span><br><span style="color: hsl(0, 100%, 40%);">-+           "Error parsing/validating SDP body"));</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    sdp_info->sdp_err = status;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    return sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--        sdp_info->sdp_err = status;</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info2(</span><br><span style="color: hsl(0, 100%, 40%);">-+                                            pjsip_rx_data *rdata,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                            const pjsip_media_type *search_media_type)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type *msg_media_type = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_rdata_sdp_info *sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rdata->endpt_info.mod_data[mod_inv.mod.id]) {</span><br><span style="color: hsl(0, 100%, 40%);">-+  return (pjsip_rdata_sdp_info *)rdata->endpt_info.mod_data[mod_inv.mod.id];</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-+     * rdata should have a Content-Type header at this point but we'll</span><br><span style="color: hsl(0, 100%, 40%);">-+     * make sure.</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rdata->msg_info.ctype) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   msg_media_type = &rdata->msg_info.ctype->media;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+    sdp_info = pjsip_get_sdp_info(rdata->tp_info.pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                 rdata->msg_info.msg->body,</span><br><span style="color: hsl(0, 100%, 40%);">-+                               msg_media_type,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                search_media_type);</span><br><span style="color: hsl(0, 100%, 40%);">-+    rdata->endpt_info.mod_data[mod_inv.mod.id] = sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    return sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    return pjsip_rdata_get_sdp_info2(rdata, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info2(</span><br><span style="color: hsl(0, 100%, 40%);">-+                                            pjsip_tx_data *tdata,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                            const pjsip_media_type *search_media_type)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_ctype_hdr *ctype_hdr = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type *msg_media_type = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_tdata_sdp_info *sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (tdata->mod_data[mod_inv.mod.id]) {</span><br><span style="color: hsl(0, 100%, 40%);">-+  return (pjsip_tdata_sdp_info *)tdata->mod_data[mod_inv.mod.id];</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-+     * tdata won't usually have a Content-Type header at this point</span><br><span style="color: hsl(0, 100%, 40%);">-+     * but we'll check just the same,</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-+    ctype_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTENT_TYPE, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (ctype_hdr) {</span><br><span style="color: hsl(0, 100%, 40%);">-+  msg_media_type = &ctype_hdr->media;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+    sdp_info = pjsip_get_sdp_info(tdata->pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                               tdata->msg->body,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                msg_media_type,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                search_media_type);</span><br><span style="color: hsl(0, 100%, 40%);">-+    tdata->mod_data[mod_inv.mod.id] = sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     return sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info(pjsip_tx_data *tdata)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    return pjsip_tdata_get_sdp_info2(tdata, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- /*</span><br><span style="color: hsl(0, 100%, 40%);">-  * Verify incoming INVITE request.</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1730,13 +1836,55 @@ PJ_DEF(pj_status_t) pjsip_create_sdp_body( pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-     return PJ_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+static pjsip_multipart_part* create_sdp_part(pj_pool_t *pool, pjmedia_sdp_session *sdp)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_multipart_part *sdp_part;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type media_type;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type_init2(&media_type, "application", "sdp");</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    sdp_part = pjsip_multipart_create_part(pool);</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(sdp_part != NULL, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    sdp_part->body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(sdp_part->body != NULL, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type_cp(pool, &sdp_part->body->content_type, &media_type);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    sdp_part->body->data = sdp;</span><br><span style="color: hsl(0, 100%, 40%);">-+    sdp_part->body->clone_data = clone_sdp;</span><br><span style="color: hsl(0, 100%, 40%);">-+    sdp_part->body->print_body = print_sdp;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    return sdp_part;</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(pj_status_t) pjsip_create_multipart_sdp_body(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                               pjmedia_sdp_session *sdp,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                              pjsip_msg_body **p_body)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type media_type;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_msg_body *multipart;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_multipart_part *sdp_part;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type_init2(&media_type, "multipart", "mixed");</span><br><span style="color: hsl(0, 100%, 40%);">-+    multipart = pjsip_multipart_create(pool, &media_type, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(multipart != NULL, PJ_ENOMEM);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    sdp_part = create_sdp_part(pool, sdp);</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(sdp_part != NULL, PJ_ENOMEM);</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_multipart_add_part(pool, multipart, sdp_part);</span><br><span style="color: hsl(0, 100%, 40%);">-+    *p_body = multipart;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    return PJ_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">- static pjsip_msg_body *create_sdp_body(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       const pjmedia_sdp_session *c_sdp)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     pjsip_msg_body *body;</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_status_t status;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--    status = pjsip_create_sdp_body(pool, </span><br><span style="color: hsl(0, 100%, 40%);">-+    status = pjsip_create_sdp_body(pool,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   pjmedia_sdp_session_clone(pool, c_sdp),</span><br><span style="color: hsl(0, 100%, 40%);">-                                 &body);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -2059,6 +2207,7 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,</span><br><span style="color: hsl(0, 100%, 40%);">-         )</span><br><span style="color: hsl(0, 100%, 40%);">-           )</span><br><span style="color: hsl(0, 100%, 40%);">-    {</span><br><span style="color: hsl(0, 100%, 40%);">-+          pjsip_sdp_info *tdata_sdp_info;</span><br><span style="color: hsl(0, 100%, 40%);">-         const pjmedia_sdp_session *reoffer_sdp = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-         PJ_LOG(4,(inv->obj_name, "Received %s response "</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -2067,14 +2216,15 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,</span><br><span style="color: hsl(0, 100%, 40%);">-                    (st_code/10==18? "early" : "final" )));</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-          /* Retrieve original SDP offer from INVITE request */</span><br><span style="color: hsl(0, 100%, 40%);">--          reoffer_sdp = (const pjmedia_sdp_session*) </span><br><span style="color: hsl(0, 100%, 40%);">--                          tsx->last_tx->msg->body->data;</span><br><span style="color: hsl(0, 100%, 40%);">-+       tdata_sdp_info = pjsip_tdata_get_sdp_info(tsx->last_tx);</span><br><span style="color: hsl(0, 100%, 40%);">-+            reoffer_sdp = tdata_sdp_info->sdp;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-          /* Feed the original offer to negotiator */</span><br><span style="color: hsl(0, 100%, 40%);">-             status = pjmedia_sdp_neg_modify_local_offer2(inv->pool_prov, </span><br><span style="color: hsl(0, 100%, 40%);">-                                                     inv->neg,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                          inv->sdp_neg_flags,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                    reoffer_sdp);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-             if (status != PJ_SUCCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 PJ_LOG(1,(inv->obj_name, "Error updating local offer for "</span><br><span style="color: hsl(0, 100%, 40%);">-                           "forked 2xx/18x response (err=%d)", status));</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/test/inv_offer_answer_test.c b/pjsip/src/test/inv_offer_answer_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-index ad5fcd409..9cdd2654b 100644</span><br><span>---- a/pjsip/src/test/inv_offer_answer_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/test/inv_offer_answer_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -137,6 +137,7 @@ typedef struct inv_test_param_t</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_bool_t     need_established;</span><br><span style="color: hsl(0, 100%, 40%);">-     unsigned  count;</span><br><span style="color: hsl(0, 100%, 40%);">-     oa_t oa[4];</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_bool_t    multipart_body;</span><br><span style="color: hsl(0, 100%, 40%);">- } inv_test_param_t;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- typedef struct inv_test_t</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -257,6 +258,17 @@ static void on_media_update(pjsip_inv_session *inv_ses,</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+     /* Special handling for standard offer/answer */</span><br><span style="color: hsl(0, 100%, 40%);">-+       if (inv_test.param.count == 1 &&</span><br><span style="color: hsl(0, 100%, 40%);">-+           inv_test.param.oa[0] == OFFERER_UAC &&</span><br><span style="color: hsl(0, 100%, 40%);">-+         inv_test.param.need_established)</span><br><span style="color: hsl(0, 100%, 40%);">-+   {</span><br><span style="color: hsl(0, 100%, 40%);">-+          jobs[job_cnt].type = ESTABLISH_CALL;</span><br><span style="color: hsl(0, 100%, 40%);">-+           jobs[job_cnt].who = PJSIP_ROLE_UAS;</span><br><span style="color: hsl(0, 100%, 40%);">-+            job_cnt++;</span><br><span style="color: hsl(0, 100%, 40%);">-+     TRACE_((THIS_FILE, "      C+++"));</span><br><span style="color: hsl(0, 100%, 40%);">-+       }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-      pj_assert(job_cnt <= PJ_ARRAY_SIZE(jobs));</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -333,6 +345,15 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata)</span><br><span style="color: hsl(0, 100%, 40%);">-                                    NULL, &tdata);</span><br><span style="color: hsl(0, 100%, 40%);">-    pj_assert(status == PJ_SUCCESS);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+      /* Use multipart body, if configured */</span><br><span style="color: hsl(0, 100%, 40%);">-+        if (sdp && inv_test.param.multipart_body) {</span><br><span style="color: hsl(0, 100%, 40%);">-+         status = pjsip_create_multipart_sdp_body(</span><br><span style="color: hsl(0, 100%, 40%);">-+                         tdata->pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                pjmedia_sdp_session_clone(tdata->pool, sdp),</span><br><span style="color: hsl(0, 100%, 40%);">-+                                &tdata->msg->body);</span><br><span style="color: hsl(0, 100%, 40%);">-+  }</span><br><span style="color: hsl(0, 100%, 40%);">-+      pj_assert(status == PJ_SUCCESS);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-       status = pjsip_inv_send_msg(inv_test.uas, tdata);</span><br><span style="color: hsl(0, 100%, 40%);">-       pj_assert(status == PJ_SUCCESS);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -426,6 +447,7 @@ static int perform_test(inv_test_param_t *param)</span><br><span style="color: hsl(0, 100%, 40%);">-   sdp = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     status = pjsip_inv_create_uac(dlg, sdp, inv_test.param.inv_option, &inv_test.uac);</span><br><span style="color: hsl(0, 100%, 40%);">-+    //inv_test.uac->create_multipart = param->multipart_body;</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_ASSERT_RETURN(status==PJ_SUCCESS, -20);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     TRACE_((THIS_FILE, "    Sending INVITE %s offer", (sdp ? "with" : "without")));</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -436,8 +458,17 @@ static int perform_test(inv_test_param_t *param)</span><br><span style="color: hsl(0, 100%, 40%);">-     status = pjsip_inv_invite(inv_test.uac, &tdata);</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Use multipart body, if configured */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (sdp && param->multipart_body) {</span><br><span style="color: hsl(0, 100%, 40%);">-+      status = pjsip_create_multipart_sdp_body(</span><br><span style="color: hsl(0, 100%, 40%);">-+                         tdata->pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                        pjmedia_sdp_session_clone(tdata->pool, sdp),</span><br><span style="color: hsl(0, 100%, 40%);">-+                        &tdata->msg->body);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -40);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     status = pjsip_inv_send_msg(inv_test.uac, tdata);</span><br><span style="color: hsl(0, 100%, 40%);">--    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30);</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -50);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /*</span><br><span style="color: hsl(0, 100%, 40%);">-      * Wait until test completes</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -525,13 +556,14 @@ static inv_test_param_t test_params[] =</span><br><span style="color: hsl(0, 100%, 40%);">-     200/INVITE (answer)       <--</span><br><span style="color: hsl(0, 100%, 40%);">-     ACK                  --></span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">--#if 0</span><br><span style="color: hsl(0, 100%, 40%);">-+#if 1</span><br><span style="color: hsl(0, 100%, 40%);">-     {</span><br><span style="color: hsl(0, 100%, 40%);">-    "Standard INVITE with offer",</span><br><span style="color: hsl(0, 100%, 40%);">-         0,</span><br><span style="color: hsl(0, 100%, 40%);">-      PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-        1,</span><br><span style="color: hsl(0, 100%, 40%);">--     { OFFERER_UAC }</span><br><span style="color: hsl(0, 100%, 40%);">-+        { OFFERER_UAC },</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_FALSE</span><br><span style="color: hsl(0, 100%, 40%);">-     },</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     {</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -539,7 +571,25 @@ static inv_test_param_t test_params[] =</span><br><span style="color: hsl(0, 100%, 40%);">-      PJSIP_INV_REQUIRE_100REL,</span><br><span style="color: hsl(0, 100%, 40%);">-       PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-        1,</span><br><span style="color: hsl(0, 100%, 40%);">--     { OFFERER_UAC }</span><br><span style="color: hsl(0, 100%, 40%);">-+        { OFFERER_UAC },</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_FALSE</span><br><span style="color: hsl(0, 100%, 40%);">-+    },</span><br><span style="color: hsl(0, 100%, 40%);">-+    {</span><br><span style="color: hsl(0, 100%, 40%);">-+  "Standard INVITE with offer, with Multipart",</span><br><span style="color: hsl(0, 100%, 40%);">-+        0,</span><br><span style="color: hsl(0, 100%, 40%);">-+     PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-+       1,</span><br><span style="color: hsl(0, 100%, 40%);">-+     { OFFERER_UAC },</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_TRUE</span><br><span style="color: hsl(0, 100%, 40%);">-+    },</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    {</span><br><span style="color: hsl(0, 100%, 40%);">-+  "Standard INVITE with offer, with 100rel, with Multipart",</span><br><span style="color: hsl(0, 100%, 40%);">-+   PJSIP_INV_REQUIRE_100REL,</span><br><span style="color: hsl(0, 100%, 40%);">-+      PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-+       1,</span><br><span style="color: hsl(0, 100%, 40%);">-+     { OFFERER_UAC },</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_TRUE</span><br><span style="color: hsl(0, 100%, 40%);">-     },</span><br><span style="color: hsl(0, 100%, 40%);">- #endif</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -555,7 +605,8 @@ static inv_test_param_t test_params[] =</span><br><span style="color: hsl(0, 100%, 40%);">-       0,</span><br><span style="color: hsl(0, 100%, 40%);">-      PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-        1,</span><br><span style="color: hsl(0, 100%, 40%);">--     { OFFERER_UAS }</span><br><span style="color: hsl(0, 100%, 40%);">-+        { OFFERER_UAS },</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_FALSE</span><br><span style="color: hsl(0, 100%, 40%);">-     },</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     {</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -563,7 +614,25 @@ static inv_test_param_t test_params[] =</span><br><span style="color: hsl(0, 100%, 40%);">-      PJSIP_INV_REQUIRE_100REL,</span><br><span style="color: hsl(0, 100%, 40%);">-       PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-        1,</span><br><span style="color: hsl(0, 100%, 40%);">--     { OFFERER_UAS }</span><br><span style="color: hsl(0, 100%, 40%);">-+        { OFFERER_UAS },</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_FALSE</span><br><span style="color: hsl(0, 100%, 40%);">-+    },</span><br><span style="color: hsl(0, 100%, 40%);">-+    {</span><br><span style="color: hsl(0, 100%, 40%);">-+  "INVITE with no offer, with Multipart",</span><br><span style="color: hsl(0, 100%, 40%);">-+      0,</span><br><span style="color: hsl(0, 100%, 40%);">-+     PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-+       1,</span><br><span style="color: hsl(0, 100%, 40%);">-+     { OFFERER_UAS },</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_TRUE</span><br><span style="color: hsl(0, 100%, 40%);">-+    },</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    {</span><br><span style="color: hsl(0, 100%, 40%);">-+  "INVITE with no offer, with 100rel, with Multipart",</span><br><span style="color: hsl(0, 100%, 40%);">-+ PJSIP_INV_REQUIRE_100REL,</span><br><span style="color: hsl(0, 100%, 40%);">-+      PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-+       1,</span><br><span style="color: hsl(0, 100%, 40%);">-+     { OFFERER_UAS },</span><br><span style="color: hsl(0, 100%, 40%);">-+       PJ_TRUE</span><br><span style="color: hsl(0, 100%, 40%);">-     },</span><br><span style="color: hsl(0, 100%, 40%);">- #endif</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -584,14 +653,24 @@ static inv_test_param_t test_params[] =</span><br><span style="color: hsl(0, 100%, 40%);">-     0,</span><br><span style="color: hsl(0, 100%, 40%);">-      PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-        2,</span><br><span style="color: hsl(0, 100%, 40%);">--     { OFFERER_UAC, OFFERER_UAC }</span><br><span style="color: hsl(0, 100%, 40%);">-+   { OFFERER_UAC, OFFERER_UAC },</span><br><span style="color: hsl(0, 100%, 40%);">-+  PJ_FALSE</span><br><span style="color: hsl(0, 100%, 40%);">-+    },</span><br><span style="color: hsl(0, 100%, 40%);">-+    {</span><br><span style="color: hsl(0, 100%, 40%);">-+  "INVITE and UPDATE by UAC, with Multipart",</span><br><span style="color: hsl(0, 100%, 40%);">-+  0,</span><br><span style="color: hsl(0, 100%, 40%);">-+     PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-+       2,</span><br><span style="color: hsl(0, 100%, 40%);">-+     { OFFERER_UAC, OFFERER_UAC },</span><br><span style="color: hsl(0, 100%, 40%);">-+  PJ_TRUE</span><br><span style="color: hsl(0, 100%, 40%);">-     },</span><br><span style="color: hsl(0, 100%, 40%);">-     {</span><br><span style="color: hsl(0, 100%, 40%);">-    "INVITE and UPDATE by UAC, with 100rel",</span><br><span style="color: hsl(0, 100%, 40%);">-      PJSIP_INV_REQUIRE_100REL,</span><br><span style="color: hsl(0, 100%, 40%);">-       PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-        2,</span><br><span style="color: hsl(0, 100%, 40%);">--     { OFFERER_UAC, OFFERER_UAC }</span><br><span style="color: hsl(0, 100%, 40%);">-+   { OFFERER_UAC, OFFERER_UAC },</span><br><span style="color: hsl(0, 100%, 40%);">-+  PJ_FALSE</span><br><span style="color: hsl(0, 100%, 40%);">-     },</span><br><span style="color: hsl(0, 100%, 40%);">- #endif</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -617,6 +696,14 @@ static inv_test_param_t test_params[] =</span><br><span style="color: hsl(0, 100%, 40%);">-     4,</span><br><span style="color: hsl(0, 100%, 40%);">-      { OFFERER_UAC, OFFERER_UAS, OFFERER_UAC, OFFERER_UAS }</span><br><span style="color: hsl(0, 100%, 40%);">-     },</span><br><span style="color: hsl(0, 100%, 40%);">-+    {</span><br><span style="color: hsl(0, 100%, 40%);">-+    "INVITE and many UPDATE by UAC and UAS, with Multipart",</span><br><span style="color: hsl(0, 100%, 40%);">-+     0,</span><br><span style="color: hsl(0, 100%, 40%);">-+     PJ_TRUE,</span><br><span style="color: hsl(0, 100%, 40%);">-+       4,</span><br><span style="color: hsl(0, 100%, 40%);">-+     { OFFERER_UAC, OFFERER_UAS, OFFERER_UAC, OFFERER_UAS },</span><br><span style="color: hsl(0, 100%, 40%);">-+        PJ_TRUE</span><br><span style="color: hsl(0, 100%, 40%);">-+    },</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- };</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.33.1</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/patches/0140-Fix-incorrect-unescaping-of-tokens-during-parsing-29.patch b/third-party/pjproject/patches/0140-Fix-incorrect-unescaping-of-tokens-during-parsing-29.patch</span><br><span>deleted file mode 100644</span><br><span>index 22df638..0000000</span><br><span>--- a/third-party/pjproject/patches/0140-Fix-incorrect-unescaping-of-tokens-during-parsing-29.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,123 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From 3faf1d2b4da553bbaee04f9a13a5d084b381e5fb Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: sauwming <ming@teluu.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Tue, 4 Jan 2022 15:28:49 +0800</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH] Fix incorrect unescaping of tokens during parsing (#2933)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/pjsip/sip_parser.c | 29 +++++++++++++++++++++++++----</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/test/msg_test.c    |  6 +++---</span><br><span style="color: hsl(0, 100%, 40%);">- 2 files changed, 28 insertions(+), 7 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c</span><br><span style="color: hsl(0, 100%, 40%);">-index c2add3299..b9a7c6a5c 100644</span><br><span>---- a/pjsip/src/pjsip/sip_parser.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/pjsip/sip_parser.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -378,17 +378,23 @@ static pj_status_t init_parser()</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_cis_add_str( &pconst.pjsip_TOKEN_SPEC, TOKEN);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Token is allowed to have '%' so we do not need this. */</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-     status = pj_cis_dup(&pconst.pjsip_TOKEN_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC);</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_cis_del_str(&pconst.pjsip_TOKEN_SPEC_ESC, "%");</span><br><span style="color: hsl(0, 100%, 40%);">-+    */</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC, &pconst.pjsip_TOKEN_SPEC);</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, "[:]");</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Token is allowed to have '%' */</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-     status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC_ESC);</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);</span><br><span style="color: hsl(0, 100%, 40%);">-     pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC_ESC, "[:]");</span><br><span style="color: hsl(0, 100%, 40%);">-+    */</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     status = pj_cis_dup(&pconst.pjsip_HOST_SPEC, &pconst.pjsip_ALNUM_SPEC);</span><br><span style="color: hsl(0, 100%, 40%);">-     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1210,7 +1216,11 @@ static void parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-                             unsigned option)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     /* pname */</span><br><span style="color: hsl(0, 100%, 40%);">--    parser_get_and_unescape(scanner, pool, spec, esc_spec, pname);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!esc_spec) {</span><br><span style="color: hsl(0, 100%, 40%);">-+        pj_scan_get(scanner, spec, pname);</span><br><span style="color: hsl(0, 100%, 40%);">-+    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-+        parser_get_and_unescape(scanner, pool, spec, esc_spec, pname);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     /* init pvalue */</span><br><span style="color: hsl(0, 100%, 40%);">-     pvalue->ptr = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1240,7 +1250,12 @@ static void parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-                 // pj_scan_get_until_ch(scanner, ']', pvalue);</span><br><span style="color: hsl(0, 100%, 40%);">-          // pj_scan_get_char(scanner);</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if(pj_cis_match(spec, *scanner->curptr)) {</span><br><span style="color: hsl(0, 100%, 40%);">--               parser_get_and_unescape(scanner, pool, spec, esc_spec, pvalue);</span><br><span style="color: hsl(0, 100%, 40%);">-+                if (!esc_spec) {</span><br><span style="color: hsl(0, 100%, 40%);">-+                   pj_scan_get(scanner, spec, pvalue);</span><br><span style="color: hsl(0, 100%, 40%);">-+                } else {</span><br><span style="color: hsl(0, 100%, 40%);">-+                   parser_get_and_unescape(scanner, pool, spec, esc_spec,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                         pvalue);</span><br><span style="color: hsl(0, 100%, 40%);">-+           }</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1252,7 +1267,10 @@ PJ_DEF(void) pjsip_parse_param_imp(pj_scanner *scanner, pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-                             unsigned option)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-     parse_param_imp(scanner, pool, pname, pvalue, &pconst.pjsip_TOKEN_SPEC,</span><br><span style="color: hsl(0, 100%, 40%);">--              &pconst.pjsip_TOKEN_SPEC_ESC, option);</span><br><span style="color: hsl(0, 100%, 40%);">-+             // Token does not need to be unescaped.</span><br><span style="color: hsl(0, 100%, 40%);">-+                // Refer to PR #2933.</span><br><span style="color: hsl(0, 100%, 40%);">-+                  // &pconst.pjsip_TOKEN_SPEC_ESC,</span><br><span style="color: hsl(0, 100%, 40%);">-+                   NULL, option);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-@@ -2168,7 +2186,10 @@ static void int_parse_via_param( pjsip_via_hdr *hdr, pj_scanner *scanner,</span><br><span style="color: hsl(0, 100%, 40%);">-  pj_scan_get_char(scanner);</span><br><span style="color: hsl(0, 100%, 40%);">-      parse_param_imp(scanner, pool, &pname, &pvalue,</span><br><span style="color: hsl(0, 100%, 40%);">-                         &pconst.pjsip_VIA_PARAM_SPEC,</span><br><span style="color: hsl(0, 100%, 40%);">--                      &pconst.pjsip_VIA_PARAM_SPEC_ESC,</span><br><span style="color: hsl(0, 100%, 40%);">-+                  // Token does not need to be unescaped.</span><br><span style="color: hsl(0, 100%, 40%);">-+                        // Refer to PR #2933.</span><br><span style="color: hsl(0, 100%, 40%);">-+                  // &pconst.pjsip_VIA_PARAM_SPEC_ESC,</span><br><span style="color: hsl(0, 100%, 40%);">-+                       NULL,</span><br><span style="color: hsl(0, 100%, 40%);">-                   0);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-    if (!parser_stricmp(pname, pconst.pjsip_BRANCH_STR) && pvalue.slen) {</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/test/msg_test.c b/pjsip/src/test/msg_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-index c511e1cf6..24e3d405d 100644</span><br><span>---- a/pjsip/src/test/msg_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/test/msg_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -953,7 +953,7 @@ static int hdr_test_subject_utf(pjsip_hdr *h);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- #define GENERIC_PARAM         "p0=a;p1=\"ab:;cd\";p2=ab%3acd;p3"</span><br><span style="color: hsl(0, 100%, 40%);">--#define GENERIC_PARAM_PARSED "p0=a;p1=\"ab:;cd\";p2=ab:cd;p3"</span><br><span style="color: hsl(0, 100%, 40%);">-+#define GENERIC_PARAM_PARSED "p0=a;p1=\"ab:;cd\";p2=ab%3acd;p3"</span><br><span style="color: hsl(0, 100%, 40%);">- #define PARAM_CHAR         "][/:&+$"</span><br><span style="color: hsl(0, 100%, 40%);">- #define SIMPLE_ADDR_SPEC     "sip:host"</span><br><span style="color: hsl(0, 100%, 40%);">- #define ADDR_SPEC             SIMPLE_ADDR_SPEC ";"PARAM_CHAR"="PARAM_CHAR ";p1=\";\""</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1401,7 +1401,7 @@ static int generic_param_test(pjsip_param *param_head)</span><br><span style="color: hsl(0, 100%, 40%);">-     param = param->next;</span><br><span style="color: hsl(0, 100%, 40%);">-     if (pj_strcmp2(&param->name, "p2"))</span><br><span style="color: hsl(0, 100%, 40%);">-   return -956;</span><br><span style="color: hsl(0, 100%, 40%);">--    if (pj_strcmp2(&param->value, "ab:cd"))</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (pj_strcmp2(&param->value, "ab%3acd"))</span><br><span style="color: hsl(0, 100%, 40%);">-        return -957;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     param = param->next;</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -1621,7 +1621,7 @@ static int hdr_test_content_type(pjsip_hdr *h)</span><br><span style="color: hsl(0, 100%, 40%);">-     prm = prm->next;</span><br><span style="color: hsl(0, 100%, 40%);">-     if (prm == &hdr->media.param) return -1960;</span><br><span style="color: hsl(0, 100%, 40%);">-     if (pj_strcmp2(&prm->name, "p2")) return -1961;</span><br><span style="color: hsl(0, 100%, 40%);">--    if (pj_strcmp2(&prm->value, "ab:cd")) return -1962;</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (pj_strcmp2(&prm->value, "ab%3acd")) return -1962;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     prm = prm->next;</span><br><span style="color: hsl(0, 100%, 40%);">-     if (prm == &hdr->media.param) return -1970;</span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.32.0</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/patches/0150-Create-generic-pjsip_hdr_find-functions.patch b/third-party/pjproject/patches/0150-Create-generic-pjsip_hdr_find-functions.patch</span><br><span>deleted file mode 100644</span><br><span>index 6ddb346..0000000</span><br><span>--- a/third-party/pjproject/patches/0150-Create-generic-pjsip_hdr_find-functions.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,176 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From 7e3dfd8a15fd0f98dbf0e04d2d7a5bded90ee401 Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: George Joseph <gjoseph@sangoma.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Tue, 11 Jan 2022 09:27:23 -0700</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH] Create generic pjsip_hdr_find functions</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-pjsip_msg_find_hdr(), pjsip_msg_find_hdr_by_name(), and</span><br><span style="color: hsl(0, 100%, 40%);">-pjsip_msg_find_hdr_by_names() require a pjsip_msg to be passed in</span><br><span style="color: hsl(0, 100%, 40%);">-so if you need to search a header list that's not in a pjsip_msg,</span><br><span style="color: hsl(0, 100%, 40%);">-you have to do it yourself.  This commit adds generic versions of</span><br><span style="color: hsl(0, 100%, 40%);">-those 3 functions that take in the actual header list head instead</span><br><span style="color: hsl(0, 100%, 40%);">-of a pjsip_msg so if you need to search a list of headers in</span><br><span style="color: hsl(0, 100%, 40%);">-something like a pjsip_multipart_part, you can do so easily.</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/include/pjsip/sip_msg.h | 53 +++++++++++++++++++++++++++++++++++</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/pjsip/sip_msg.c     | 51 +++++++++++++++++++++++----------</span><br><span style="color: hsl(0, 100%, 40%);">- 2 files changed, 89 insertions(+), 15 deletions(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/include/pjsip/sip_msg.h b/pjsip/include/pjsip/sip_msg.h</span><br><span style="color: hsl(0, 100%, 40%);">-index 4c9100d39..e3502e94e 100644</span><br><span>---- a/pjsip/include/pjsip/sip_msg.h</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/include/pjsip/sip_msg.h</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -362,6 +362,59 @@ PJ_DECL(void*) pjsip_hdr_shallow_clone( pj_pool_t *pool, const void *hdr );</span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">- PJ_DECL(int) pjsip_hdr_print_on( void *hdr, char *buf, pj_size_t len);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Find a header in a header list by the header type.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param hdr_list  The "head" of the header list.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param type      The header type to find.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param start     The first header field where the search should begin.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  If NULL is specified, then the search will begin from the</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  first header, otherwise the search will begin at the</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  specified header.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return          The header field, or NULL if no header with the specified</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  type is found.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(void*)  pjsip_hdr_find( const void *hdr_list,</span><br><span style="color: hsl(0, 100%, 40%);">-+                            pjsip_hdr_e type,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              const void *start);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Find a header in a header list by its name.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param hdr_list  The "head" of the header list.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param name      The header name to find.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param start     The first header field where the search should begin.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  If NULL is specified, then the search will begin from the</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  first header, otherwise the search will begin at the</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  specified header.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return          The header field, or NULL if no header with the specified</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  type is found.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(void*)  pjsip_hdr_find_by_name( const void *hdr_list,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                      const pj_str_t *name,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                  const void *start);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Find a header in a header list by its name and short name version.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param hdr_list  The "head" of the header list.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param name      The header name to find.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param sname     The short name version of the header name.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param start     The first header field where the search should begin.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  If NULL is specified, then the search will begin from the</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  first header, otherwise the search will begin at the</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                  specified header.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return     The header field, or NULL if no header with the specified</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                    type is found.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(void*)  pjsip_hdr_find_by_names( const void *hdr_list,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                   const pj_str_t *name,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                  const pj_str_t *sname,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                         const void *start);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">- /**</span><br><span style="color: hsl(0, 100%, 40%);">-  * @}</span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/pjsip/sip_msg.c b/pjsip/src/pjsip/sip_msg.c</span><br><span style="color: hsl(0, 100%, 40%);">-index 6ba3054da..2a6a96af0 100644</span><br><span>---- a/pjsip/src/pjsip/sip_msg.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/pjsip/sip_msg.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -356,13 +356,13 @@ PJ_DEF(pjsip_msg*) pjsip_msg_clone( pj_pool_t *pool, const pjsip_msg *src)</span><br><span style="color: hsl(0, 100%, 40%);">-     return dst;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--PJ_DEF(void*)  pjsip_msg_find_hdr( const pjsip_msg *msg, </span><br><span style="color: hsl(0, 100%, 40%);">--                             pjsip_hdr_e hdr_type, const void *start)</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(void*)  pjsip_hdr_find( const void *hdr_list,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              pjsip_hdr_e hdr_type, const void *start)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">--    const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=&msg->hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-+    const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=hdr_list;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     if (hdr == NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">--  hdr = msg->hdr.next;</span><br><span style="color: hsl(0, 100%, 40%);">-+        hdr = end->next;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-     for (; hdr!=end; hdr = hdr->next) {</span><br><span style="color: hsl(0, 100%, 40%);">-    if (hdr->type == hdr_type)</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -371,14 +371,14 @@ PJ_DEF(void*)  pjsip_msg_find_hdr( const pjsip_msg *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-     return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--PJ_DEF(void*)  pjsip_msg_find_hdr_by_name( const pjsip_msg *msg, </span><br><span style="color: hsl(0, 100%, 40%);">--                                         const pj_str_t *name, </span><br><span style="color: hsl(0, 100%, 40%);">--                                         const void *start)</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(void*)  pjsip_hdr_find_by_name( const void *hdr_list,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                    const pj_str_t *name,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                  const void *start)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">--    const pjsip_hdr *hdr=(const pjsip_hdr*)start, *end=&msg->hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-+    const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=hdr_list;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     if (hdr == NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">-- hdr = msg->hdr.next;</span><br><span style="color: hsl(0, 100%, 40%);">-+        hdr = end->next;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-     for (; hdr!=end; hdr = hdr->next) {</span><br><span style="color: hsl(0, 100%, 40%);">-    if (pj_stricmp(&hdr->name, name) == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -387,15 +387,15 @@ PJ_DEF(void*)  pjsip_msg_find_hdr_by_name( const pjsip_msg *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-     return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">--PJ_DEF(void*)  pjsip_msg_find_hdr_by_names( const pjsip_msg *msg, </span><br><span style="color: hsl(0, 100%, 40%);">--                                         const pj_str_t *name, </span><br><span style="color: hsl(0, 100%, 40%);">--                                         const pj_str_t *sname,</span><br><span style="color: hsl(0, 100%, 40%);">--                                         const void *start)</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(void*)  pjsip_hdr_find_by_names( const void *hdr_list,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                   const pj_str_t *name,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                  const pj_str_t *sname,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                 const void *start)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">--    const pjsip_hdr *hdr=(const pjsip_hdr*)start, *end=&msg->hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-+    const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=hdr_list;</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     if (hdr == NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">--        hdr = msg->hdr.next;</span><br><span style="color: hsl(0, 100%, 40%);">-+        hdr = end->next;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-     for (; hdr!=end; hdr = hdr->next) {</span><br><span style="color: hsl(0, 100%, 40%);">-    if (pj_stricmp(&hdr->name, name) == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -406,6 +406,27 @@ PJ_DEF(void*)  pjsip_msg_find_hdr_by_names( const pjsip_msg *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-     return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(void*)  pjsip_msg_find_hdr( const pjsip_msg *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                  pjsip_hdr_e hdr_type, const void *start)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    return pjsip_hdr_find(&msg->hdr, hdr_type, start);</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(void*)  pjsip_msg_find_hdr_by_name( const pjsip_msg *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                           const pj_str_t *name,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                          const void *start)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    return pjsip_hdr_find_by_name(&msg->hdr, name, start);</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(void*)  pjsip_msg_find_hdr_by_names( const pjsip_msg *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                     const pj_str_t *name,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                          const pj_str_t *sname,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                         const void *start)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    return pjsip_hdr_find_by_names(&msg->hdr, name, sname, start);</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">- PJ_DEF(void*) pjsip_msg_find_remove_hdr( pjsip_msg *msg, </span><br><span style="color: hsl(0, 100%, 40%);">-                                          pjsip_hdr_e hdr_type, void *start)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.34.1</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/patches/0160-Additional-multipart-improvements.patch b/third-party/pjproject/patches/0160-Additional-multipart-improvements.patch</span><br><span>deleted file mode 100644</span><br><span>index 373f9b8..0000000</span><br><span>--- a/third-party/pjproject/patches/0160-Additional-multipart-improvements.patch</span><br><span>+++ /dev/null</span><br><span>@@ -1,644 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-From b7ecff22e77887626fd8e8608c4dd73bc7b7366f Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(0, 100%, 40%);">-From: George Joseph <gjoseph@sangoma.com></span><br><span style="color: hsl(0, 100%, 40%);">-Date: Tue, 18 Jan 2022 06:14:31 -0700</span><br><span style="color: hsl(0, 100%, 40%);">-Subject: [PATCH] Additional multipart improvements</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-Added the following APIs:</span><br><span style="color: hsl(0, 100%, 40%);">-pjsip_multipart_find_part_by_header()</span><br><span style="color: hsl(0, 100%, 40%);">-pjsip_multipart_find_part_by_header_str()</span><br><span style="color: hsl(0, 100%, 40%);">-pjsip_multipart_find_part_by_cid_str()</span><br><span style="color: hsl(0, 100%, 40%);">-pjsip_multipart_find_part_by_cid_uri()</span><br><span>----</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/include/pjsip/sip_multipart.h |  83 ++++++++++</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/pjsip/sip_multipart.c     | 223 +++++++++++++++++++++++++++</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip/src/test/multipart_test.c     | 225 +++++++++++++++++++++++++++-</span><br><span style="color: hsl(0, 100%, 40%);">- 3 files changed, 530 insertions(+), 1 deletion(-)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/include/pjsip/sip_multipart.h b/pjsip/include/pjsip/sip_multipart.h</span><br><span style="color: hsl(0, 100%, 40%);">-index 1c05767c5..c6b82b0b4 100644</span><br><span>---- a/pjsip/include/pjsip/sip_multipart.h</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/include/pjsip/sip_multipart.h</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -153,6 +153,89 @@ pjsip_multipart_find_part( const pjsip_msg_body *mp,</span><br><span style="color: hsl(0, 100%, 40%);">-                       const pjsip_media_type *content_type,</span><br><span style="color: hsl(0, 100%, 40%);">-                           const pjsip_multipart_part *start);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Find a body inside multipart bodies which has a header matching the</span><br><span style="color: hsl(0, 100%, 40%);">-+ * supplied one. Most useful for finding a part with a specific Content-ID.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param pool                Memory pool to use for temp space.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param mp         The multipart body.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param search_hdr        Header to search for.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param start           If specified, the search will begin at</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                       start->next part. Otherwise it will begin at</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                      the first part in the multipart bodies.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return           The first part which has a header matching the</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                       specified one, or NULL if not found.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(pjsip_multipart_part*)</span><br><span style="color: hsl(0, 100%, 40%);">-+pjsip_multipart_find_part_by_header(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                               const pjsip_msg_body *mp,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              void *search_hdr,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              const pjsip_multipart_part *start);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Find a body inside multipart bodies which has a header matching the</span><br><span style="color: hsl(0, 100%, 40%);">-+ * supplied name and value. Most useful for finding a part with a specific</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Content-ID.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param pool         Memory pool to use for temp space.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param mp         The multipart body.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param hdr_name  Header name to search for.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param hdr_value  Header value search for.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param start                If specified, the search will begin at</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                       start->next part. Otherwise it will begin at</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                      the first part in the multipart bodies.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return           The first part which has a header matching the</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                       specified one, or NULL if not found.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(pjsip_multipart_part*)</span><br><span style="color: hsl(0, 100%, 40%);">-+pjsip_multipart_find_part_by_header_str(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                   const pjsip_msg_body *mp,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              const pj_str_t *hdr_name,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              const pj_str_t *hdr_value,</span><br><span style="color: hsl(0, 100%, 40%);">-+                             const pjsip_multipart_part *start);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Find a body inside multipart bodies which has a Content-ID value matching the</span><br><span style="color: hsl(0, 100%, 40%);">-+ * supplied "cid" URI in pj_str form.  The "cid:" scheme will be assumed if the</span><br><span style="color: hsl(0, 100%, 40%);">-+ * URL doesn't start with it.  Enclosing angle brackets will also be handled</span><br><span style="color: hsl(0, 100%, 40%);">-+ * correctly if they exist.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @see RFC2392 Content-ID and Message-ID Uniform Resource Locators</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param pool       Memory pool to use for temp space.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param mp The multipart body.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param cid       The "cid" URI to search for in pj_str form.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return             The first part which has a Content-ID header matching the</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                    specified "cid" URI. or NULL if not found.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(pjsip_multipart_part*)</span><br><span style="color: hsl(0, 100%, 40%);">-+pjsip_multipart_find_part_by_cid_str(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                           const pjsip_msg_body *mp,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              pj_str_t *cid);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+/**</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Find a body inside multipart bodies which has a Content-ID value matching the</span><br><span style="color: hsl(0, 100%, 40%);">-+ * supplied "cid" URI.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @see RFC2392 Content-ID and Message-ID Uniform Resource Locators</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param pool        Memory pool to use for temp space.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param mp The multipart body.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @param cid       The "cid" URI to search for.</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * @return            The first part which had a Content-ID header matching the</span><br><span style="color: hsl(0, 100%, 40%);">-+ *                    specified "cid" URI. or NULL if not found.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DECL(pjsip_multipart_part*)</span><br><span style="color: hsl(0, 100%, 40%);">-+pjsip_multipart_find_part_by_cid_uri(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                           const pjsip_msg_body *mp,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              pjsip_other_uri *cid_uri);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">- /**</span><br><span style="color: hsl(0, 100%, 40%);">-  * Parse multipart message.</span><br><span style="color: hsl(0, 100%, 40%);">-  *</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/pjsip/sip_multipart.c b/pjsip/src/pjsip/sip_multipart.c</span><br><span style="color: hsl(0, 100%, 40%);">-index e7d722d2e..9d8be55b0 100644</span><br><span>---- a/pjsip/src/pjsip/sip_multipart.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/pjsip/sip_multipart.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -19,6 +19,7 @@</span><br><span style="color: hsl(0, 100%, 40%);">- #include <pjsip/sip_multipart.h></span><br><span style="color: hsl(0, 100%, 40%);">- #include <pjsip/sip_parser.h></span><br><span style="color: hsl(0, 100%, 40%);">- #include <pjlib-util/scanner.h></span><br><span style="color: hsl(0, 100%, 40%);">-+#include <pjlib-util/string.h></span><br><span style="color: hsl(0, 100%, 40%);">- #include <pj/assert.h></span><br><span style="color: hsl(0, 100%, 40%);">- #include <pj/ctype.h></span><br><span style="color: hsl(0, 100%, 40%);">- #include <pj/errno.h></span><br><span style="color: hsl(0, 100%, 40%);">-@@ -416,6 +417,220 @@ pjsip_multipart_find_part( const pjsip_msg_body *mp,</span><br><span style="color: hsl(0, 100%, 40%);">-     return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+/*</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Find a body inside multipart bodies which has the header and value.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(pjsip_multipart_part*)</span><br><span style="color: hsl(0, 100%, 40%);">-+pjsip_multipart_find_part_by_header_str(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                const pjsip_msg_body *mp,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              const pj_str_t *hdr_name,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              const pj_str_t *hdr_value,</span><br><span style="color: hsl(0, 100%, 40%);">-+                             const pjsip_multipart_part *start)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    struct multipart_data *m_data;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_multipart_part *part;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_hdr *found_hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t found_hdr_str;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t found_hdr_value;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_size_t expected_hdr_slen;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_size_t buf_size;</span><br><span style="color: hsl(0, 100%, 40%);">-+    int hdr_name_len;</span><br><span style="color: hsl(0, 100%, 40%);">-+#define REASONABLE_PADDING 32</span><br><span style="color: hsl(0, 100%, 40%);">-+#define SEPARATOR_LEN 2</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Must specify mandatory params */</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(mp && hdr_name && hdr_value, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* mp must really point to an actual multipart msg body */</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-+     * We'll need to "print" each header we find to test it but</span><br><span style="color: hsl(0, 100%, 40%);">-+     * allocating a buffer of PJSIP_MAX_URL_SIZE is overkill.</span><br><span style="color: hsl(0, 100%, 40%);">-+     * Instead, we'll allocate one large enough to hold the search</span><br><span style="color: hsl(0, 100%, 40%);">-+     * header name, the ": " separator, the search hdr value, and</span><br><span style="color: hsl(0, 100%, 40%);">-+     * the NULL terminator.  If we can't print the found header</span><br><span style="color: hsl(0, 100%, 40%);">-+     * into that buffer then it can't be a match.</span><br><span style="color: hsl(0, 100%, 40%);">-+     *</span><br><span style="color: hsl(0, 100%, 40%);">-+     * Some header print functions such as generic_int require enough</span><br><span style="color: hsl(0, 100%, 40%);">-+     * space to print the maximum possible header length so we'll</span><br><span style="color: hsl(0, 100%, 40%);">-+     * add a reasonable amount to the print buffer size.</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-+    expected_hdr_slen = hdr_name->slen + SEPARATOR_LEN + hdr_value->slen;</span><br><span style="color: hsl(0, 100%, 40%);">-+    buf_size = expected_hdr_slen + REASONABLE_PADDING;</span><br><span style="color: hsl(0, 100%, 40%);">-+    found_hdr_str.ptr = pj_pool_alloc(pool, buf_size);</span><br><span style="color: hsl(0, 100%, 40%);">-+    found_hdr_str.slen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-+    hdr_name_len = hdr_name->slen + SEPARATOR_LEN;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    m_data = (struct multipart_data*)mp->data;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (start)</span><br><span style="color: hsl(0, 100%, 40%);">-+        part = start->next;</span><br><span style="color: hsl(0, 100%, 40%);">-+    else</span><br><span style="color: hsl(0, 100%, 40%);">-+        part = m_data->part_head.next;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    while (part != &m_data->part_head) {</span><br><span style="color: hsl(0, 100%, 40%);">-+     found_hdr = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+      while ((found_hdr = pjsip_hdr_find_by_name(&part->hdr, hdr_name,</span><br><span style="color: hsl(0, 100%, 40%);">-+            (found_hdr ? found_hdr->next : NULL))) != NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+          found_hdr_str.slen = pjsip_hdr_print_on((void*) found_hdr, found_hdr_str.ptr, buf_size);</span><br><span style="color: hsl(0, 100%, 40%);">-+       /*</span><br><span style="color: hsl(0, 100%, 40%);">-+      * If the buffer was too small (slen = -1) or the result wasn't</span><br><span style="color: hsl(0, 100%, 40%);">-+             * the same length as the search header, it can't be a match.</span><br><span style="color: hsl(0, 100%, 40%);">-+       */</span><br><span style="color: hsl(0, 100%, 40%);">-+            if (found_hdr_str.slen != expected_hdr_slen) {</span><br><span style="color: hsl(0, 100%, 40%);">-+             continue;</span><br><span style="color: hsl(0, 100%, 40%);">-+          }</span><br><span style="color: hsl(0, 100%, 40%);">-+      /*</span><br><span style="color: hsl(0, 100%, 40%);">-+      * Set the value overlay to start at the found header value...</span><br><span style="color: hsl(0, 100%, 40%);">-+          */</span><br><span style="color: hsl(0, 100%, 40%);">-+            found_hdr_value.ptr = found_hdr_str.ptr + hdr_name_len;</span><br><span style="color: hsl(0, 100%, 40%);">-+        found_hdr_value.slen = found_hdr_str.slen - hdr_name_len;</span><br><span style="color: hsl(0, 100%, 40%);">-+      /* ...and compare it to the supplied header value. */</span><br><span style="color: hsl(0, 100%, 40%);">-+          if (pj_strcmp(hdr_value, &found_hdr_value) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-+             return part;</span><br><span style="color: hsl(0, 100%, 40%);">-+       }</span><br><span style="color: hsl(0, 100%, 40%);">-+  }</span><br><span style="color: hsl(0, 100%, 40%);">-+      part = part->next;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+    return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+#undef SEPARATOR_LEN</span><br><span style="color: hsl(0, 100%, 40%);">-+#undef REASONABLE_PADDING</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(pjsip_multipart_part*)</span><br><span style="color: hsl(0, 100%, 40%);">-+pjsip_multipart_find_part_by_header(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                                  const pjsip_msg_body *mp,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              void *search_for,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              const pjsip_multipart_part *start)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    struct multipart_data *m_data;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_hdr *search_hdr = search_for;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t search_buf;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Must specify mandatory params */</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(mp && search_hdr, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* mp must really point to an actual multipart msg body */</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-+     * Unfortunately, there isn't enough information to determine</span><br><span style="color: hsl(0, 100%, 40%);">-+     * the maximum printed size of search_hdr at this point so we</span><br><span style="color: hsl(0, 100%, 40%);">-+     * have to allocate a reasonable max.</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-+    search_buf.ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);</span><br><span style="color: hsl(0, 100%, 40%);">-+    search_buf.slen = pjsip_hdr_print_on(search_hdr, search_buf.ptr, PJSIP_MAX_URL_SIZE - 1);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (search_buf.slen <= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-+ return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-+     * Set the header value to start after the header name plus the ":", then</span><br><span style="color: hsl(0, 100%, 40%);">-+     * strip leading and trailing whitespace.</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-+    search_buf.ptr += (search_hdr->name.slen + 1);</span><br><span style="color: hsl(0, 100%, 40%);">-+    search_buf.slen -= (search_hdr->name.slen + 1);</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_strtrim(&search_buf);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    return pjsip_multipart_find_part_by_header_str(pool, mp, &search_hdr->name, &search_buf, start);</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+/*</span><br><span style="color: hsl(0, 100%, 40%);">-+ * Convert a Content-ID URI to it's corresponding header value.</span><br><span style="color: hsl(0, 100%, 40%);">-+ * RFC2392 says...</span><br><span style="color: hsl(0, 100%, 40%);">-+ * A "cid" URL is converted to the corresponding Content-ID message</span><br><span style="color: hsl(0, 100%, 40%);">-+ * header by removing the "cid:" prefix, converting the % encoded</span><br><span style="color: hsl(0, 100%, 40%);">-+ * character(s) to their equivalent US-ASCII characters, and enclosing</span><br><span style="color: hsl(0, 100%, 40%);">-+ * the remaining parts with an angle bracket pair, "<" and ">".</span><br><span style="color: hsl(0, 100%, 40%);">-+ *</span><br><span style="color: hsl(0, 100%, 40%);">-+ * This implementation will accept URIs with or without the "cid:"</span><br><span style="color: hsl(0, 100%, 40%);">-+ * scheme and optional angle brackets.</span><br><span style="color: hsl(0, 100%, 40%);">-+ */</span><br><span style="color: hsl(0, 100%, 40%);">-+static pj_str_t cid_uri_to_hdr_value(pj_pool_t *pool, pj_str_t *cid_uri)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_size_t cid_len = pj_strlen(cid_uri);</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_size_t alloc_len = cid_len + 2 /* for the leading and trailing angle brackets */;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t uri_overlay;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t cid_hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t hdr_overlay;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_strassign(&uri_overlay, cid_uri);</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* If the URI is already enclosed in angle brackets, remove them. */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (uri_overlay.ptr[0] == '<') {</span><br><span style="color: hsl(0, 100%, 40%);">-+     uri_overlay.ptr++;</span><br><span style="color: hsl(0, 100%, 40%);">-+     uri_overlay.slen -= 2;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* If the URI starts with the "cid:" scheme, skip over it. */</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (pj_strncmp2(&uri_overlay, "cid:", 4) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-+    uri_overlay.ptr += 4;</span><br><span style="color: hsl(0, 100%, 40%);">-+  uri_overlay.slen -= 4;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* Start building */</span><br><span style="color: hsl(0, 100%, 40%);">-+    cid_hdr.ptr = pj_pool_alloc(pool, alloc_len);</span><br><span style="color: hsl(0, 100%, 40%);">-+    cid_hdr.ptr[0] = '<';</span><br><span style="color: hsl(0, 100%, 40%);">-+    cid_hdr.slen = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-+    hdr_overlay.ptr = cid_hdr.ptr + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-+    hdr_overlay.slen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_strcpy_unescape(&hdr_overlay, &uri_overlay);</span><br><span style="color: hsl(0, 100%, 40%);">-+    cid_hdr.slen += hdr_overlay.slen;</span><br><span style="color: hsl(0, 100%, 40%);">-+    cid_hdr.ptr[cid_hdr.slen] = '>';</span><br><span style="color: hsl(0, 100%, 40%);">-+    cid_hdr.slen++;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    return cid_hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(pjsip_multipart_part*)</span><br><span style="color: hsl(0, 100%, 40%);">-+pjsip_multipart_find_part_by_cid_str(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                           const pjsip_msg_body *mp,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              pj_str_t *cid)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    struct multipart_data *m_data;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_multipart_part *part;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_generic_string_hdr *found_hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t found_hdr_value;</span><br><span style="color: hsl(0, 100%, 40%);">-+    static pj_str_t hdr_name = { "Content-ID", 10};</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t hdr_value;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(pool && mp && cid && (pj_strlen(cid) > 0), NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    hdr_value = cid_uri_to_hdr_value(pool, cid);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (pj_strlen(&hdr_value) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-+       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    m_data = (struct multipart_data*)mp->data;</span><br><span style="color: hsl(0, 100%, 40%);">-+    part = m_data->part_head.next;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    while (part != &m_data->part_head) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   found_hdr = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+      while ((found_hdr = pjsip_hdr_find_by_name(&part->hdr, &hdr_name,</span><br><span style="color: hsl(0, 100%, 40%);">-+       (found_hdr ? found_hdr->next : NULL))) != NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">-+           if (pj_strcmp(&hdr_value, &found_hdr->hvalue) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-+           return part;</span><br><span style="color: hsl(0, 100%, 40%);">-+       }</span><br><span style="color: hsl(0, 100%, 40%);">-+  }</span><br><span style="color: hsl(0, 100%, 40%);">-+      part = part->next;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+    return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+PJ_DEF(pjsip_multipart_part*)</span><br><span style="color: hsl(0, 100%, 40%);">-+pjsip_multipart_find_part_by_cid_uri(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-+                             const pjsip_msg_body *mp,</span><br><span style="color: hsl(0, 100%, 40%);">-+                              pjsip_other_uri *cid_uri)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    PJ_ASSERT_RETURN(pool && mp && cid_uri, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (pj_strcmp2(&cid_uri->scheme, "cid") != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-+  return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-+     * We only need to pass the URI content so we</span><br><span style="color: hsl(0, 100%, 40%);">-+     * can do that directly.</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-+    return pjsip_multipart_find_part_by_cid_str(pool, mp, &cid_uri->content);</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">- /* Parse a multipart part. "pct" is parent content-type  */</span><br><span style="color: hsl(0, 100%, 40%);">- static pjsip_multipart_part *parse_multipart_part(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                 char *start,</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -584,6 +799,7 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-                (int)boundary.slen, boundary.ptr));</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Build the delimiter:</span><br><span style="color: hsl(0, 100%, 40%);">-      *   delimiter = "--" boundary</span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -630,6 +846,8 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-  if (*curptr=='\r') ++curptr;</span><br><span style="color: hsl(0, 100%, 40%);">-    if (*curptr!='\n') {</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Expecting a newline here */</span><br><span style="color: hsl(0, 100%, 40%);">-+         PJ_LOG(2, (THIS_FILE, "Failed to find newline"));</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-            return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-       ++curptr;</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -645,6 +863,7 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-         curptr = pj_strstr(&subbody, &delim);</span><br><span style="color: hsl(0, 100%, 40%);">-           if (!curptr) {</span><br><span style="color: hsl(0, 100%, 40%);">-              /* We're really expecting end delimiter to be found. */</span><br><span style="color: hsl(0, 100%, 40%);">-+            PJ_LOG(2, (THIS_FILE, "Failed to find end-delimiter"));</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -670,9 +889,13 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,</span><br><span style="color: hsl(0, 100%, 40%);">-    part = parse_multipart_part(pool, start_body, end_body - start_body,</span><br><span style="color: hsl(0, 100%, 40%);">-                                ctype);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (part) {</span><br><span style="color: hsl(0, 100%, 40%);">-+        TRACE_((THIS_FILE, "Adding part"));</span><br><span style="color: hsl(0, 100%, 40%);">-           pjsip_multipart_add_part(pool, body, part);</span><br><span style="color: hsl(0, 100%, 40%);">-+        } else {</span><br><span style="color: hsl(0, 100%, 40%);">-+           PJ_LOG(2, (THIS_FILE, "Failed to add part"));</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-+    TRACE_((THIS_FILE, "pjsip_multipart_parse finished: %p", body));</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-     return body;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-diff --git a/pjsip/src/test/multipart_test.c b/pjsip/src/test/multipart_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-index 4f16e68bf..97267a290 100644</span><br><span>---- a/pjsip/src/test/multipart_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-+++ b/pjsip/src/test/multipart_test.c</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -28,6 +28,7 @@</span><br><span style="color: hsl(0, 100%, 40%);">- typedef pj_status_t (*verify_ptr)(pj_pool_t*,pjsip_msg_body*);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- static pj_status_t verify1(pj_pool_t *pool, pjsip_msg_body *body);</span><br><span style="color: hsl(0, 100%, 40%);">-+static pj_status_t verify2(pj_pool_t *pool, pjsip_msg_body *body);</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- static struct test_t</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -68,7 +69,41 @@ static struct test_t</span><br><span style="color: hsl(0, 100%, 40%);">-           "This is epilogue, which should be ignored too",</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-             &verify1</span><br><span style="color: hsl(0, 100%, 40%);">-+   },</span><br><span style="color: hsl(0, 100%, 40%);">-+     {</span><br><span style="color: hsl(0, 100%, 40%);">-+              /* Content-type */</span><br><span style="color: hsl(0, 100%, 40%);">-+             "multipart", "mixed", "12345",</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+          /* Body: */</span><br><span style="color: hsl(0, 100%, 40%);">-+            "This is the prolog, which should be ignored.\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+           "--12345\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+                "Content-Type: text/plain\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+               "Content-ID: <header1@example.org>\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+                "Content-ID: <\"header1\"@example.org>\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+          "Content-Length: 13\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+             "\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+               "has header1\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+            "--12345 \t\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+             "Content-Type: application/pidf+xml\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+             "Content-ID: <my header2@example.org>\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+             "Content-ID: <my\xffheader2@example.org>\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+          "Content-Length: 13\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+             "\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+               "has header2\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+            "--12345\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+                "Content-Type: text/plain\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+               "Content-ID: <my header3@example.org>\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+             "Content-ID: <header1@example.org>\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+                "Content-ID: <my header4@example.org>\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+             "Content-Length: 13\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+             "\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+               "has header4\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+            "--12345--\r\n"</span><br><span style="color: hsl(0, 100%, 40%);">-+              "This is epilogue, which should be ignored too",</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+            &verify2</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">- };</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">- static void init_media_type(pjsip_media_type *mt,</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -87,6 +122,192 @@ static void init_media_type(pjsip_media_type *mt,</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-+static int verify_hdr(pj_pool_t *pool, pjsip_msg_body *multipart_body,</span><br><span style="color: hsl(0, 100%, 40%);">-+    void *hdr, char *part_body)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type mt;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_multipart_part *part;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t the_body;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    part = pjsip_multipart_find_part_by_header(pool, multipart_body, hdr, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!part) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    the_body.ptr = (char*)part->body->data;</span><br><span style="color: hsl(0, 100%, 40%);">-+    the_body.slen = part->body->len;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (pj_strcmp2(&the_body, part_body) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   return -2;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+static int verify_cid_str(pj_pool_t *pool, pjsip_msg_body *multipart_body,</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t cid_url, char *part_body)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type mt;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_multipart_part *part;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t the_body;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    part = pjsip_multipart_find_part_by_cid_str(pool, multipart_body, &cid_url);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!part) {</span><br><span style="color: hsl(0, 100%, 40%);">-+  return -3;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    the_body.ptr = (char*)part->body->data;</span><br><span style="color: hsl(0, 100%, 40%);">-+    the_body.slen = part->body->len;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (pj_strcmp2(&the_body, part_body) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   return -4;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+static int verify_cid_uri(pj_pool_t *pool, pjsip_msg_body *multipart_body,</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_other_uri *cid_uri, char *part_body)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_media_type mt;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_multipart_part *part;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pj_str_t the_body;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    part = pjsip_multipart_find_part_by_cid_uri(pool, multipart_body, cid_uri);</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!part) {</span><br><span style="color: hsl(0, 100%, 40%);">-+       return -5;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    the_body.ptr = (char*)part->body->data;</span><br><span style="color: hsl(0, 100%, 40%);">-+    the_body.slen = part->body->len;</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (pj_strcmp2(&the_body, part_body) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   return -6;</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+static pj_status_t verify2(pj_pool_t *pool, pjsip_msg_body *body)</span><br><span style="color: hsl(0, 100%, 40%);">-+{</span><br><span style="color: hsl(0, 100%, 40%);">-+    int rc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-+    int rcbase = 300;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_other_uri *cid_uri;</span><br><span style="color: hsl(0, 100%, 40%);">-+    pjsip_ctype_hdr *ctype_hdr = pjsip_ctype_hdr_create(pool);</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    ctype_hdr->media.type = pj_str("application");</span><br><span style="color: hsl(0, 100%, 40%);">-+    ctype_hdr->media.subtype = pj_str("pidf+xml");</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_hdr(pool, body, ctype_hdr, "has header2");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+ return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("cid:header1@example.org"), "has header1");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+        return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("%22header1%22@example.org"), "has header1");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+      return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "<cid:%22header1%22@example.org>",</span><br><span style="color: hsl(0, 100%, 40%);">-+  strlen("<cid:%22header1%22@example.org>"), 0));</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_uri(pool, body, cid_uri, "has header1");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+ return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("<cid:my%20header2@example.org>"), "has header2");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("cid:my%ffheader2@example.org"), "has header2");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "<cid:my%ffheader2@example.org>",</span><br><span style="color: hsl(0, 100%, 40%);">-+   strlen("<cid:my%ffheader2@example.org>"), 0));</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_uri(pool, body, cid_uri, "has header2");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+  return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("cid:my%20header3@example.org"), "has header4");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("<cid:my%20header4@example.org>"), "has header4");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "<cid:my%20header4@example.org>",</span><br><span style="color: hsl(0, 100%, 40%);">-+   strlen("<cid:my%20header4@example.org>"), 0));</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_uri(pool, body, cid_uri, "has header4");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+  return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("<my%20header3@example.org>"), "has header4");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+       return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /* These should all fail for malformed or missing URI */</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("cid:"), "has header4");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+     return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str(""), "has header4");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+      return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("<>"), "has header4");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+      return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("<cid>"), "has header4");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (!rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+   return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    /*</span><br><span style="color: hsl(0, 100%, 40%);">-+     * This is going to pass but the ' ' in the uri is un-encoded which is invalid</span><br><span style="color: hsl(0, 100%, 40%);">-+     * so we should never see it.</span><br><span style="color: hsl(0, 100%, 40%);">-+     */</span><br><span style="color: hsl(0, 100%, 40%);">-+    rcbase += 10;</span><br><span style="color: hsl(0, 100%, 40%);">-+    rc = verify_cid_str(pool, body, pj_str("cid:my header3@example.org"), "has header4");</span><br><span style="color: hsl(0, 100%, 40%);">-+    if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-+ return (rc - rcbase);</span><br><span style="color: hsl(0, 100%, 40%);">-+    }</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">-+    return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-+}</span><br><span style="color: hsl(0, 100%, 40%);">-+</span><br><span style="color: hsl(0, 100%, 40%);">- static int verify_part(pjsip_multipart_part *part,</span><br><span style="color: hsl(0, 100%, 40%);">-                       char *h_content_type,</span><br><span style="color: hsl(0, 100%, 40%);">-                   char *h_content_subtype,</span><br><span style="color: hsl(0, 100%, 40%);">-@@ -236,8 +457,10 @@ static int parse_test(void)</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-        pj_strdup2_with_null(pool, &str, p_tests[i].msg);</span><br><span style="color: hsl(0, 100%, 40%);">-   body = pjsip_multipart_parse(pool, str.ptr, str.slen, &ctype, 0);</span><br><span style="color: hsl(0, 100%, 40%);">--  if (!body)</span><br><span style="color: hsl(0, 100%, 40%);">-+     if (!body) {</span><br><span style="color: hsl(0, 100%, 40%);">-+       pj_pool_release(pool);</span><br><span style="color: hsl(0, 100%, 40%);">-          return -100;</span><br><span style="color: hsl(0, 100%, 40%);">-+       }</span><br><span style="color: hsl(0, 100%, 40%);">- </span><br><span style="color: hsl(0, 100%, 40%);">-      if (p_tests[i].verify) {</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = p_tests[i].verify(pool, body);</span><br><span>--- </span><br><span style="color: hsl(0, 100%, 40%);">-2.34.1</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/third-party/pjproject/pjproject-2.10.tar.bz2.md5 b/third-party/pjproject/pjproject-2.10.tar.bz2.md5</span><br><span>deleted file mode 100644</span><br><span>index 57261b4..0000000</span><br><span>--- a/third-party/pjproject/pjproject-2.10.tar.bz2.md5</span><br><span>+++ /dev/null</span><br><span>@@ -1,2 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-5d0202f79a7aeb14873c45b0e4c14a70 *pjproject-2.10.zip</span><br><span style="color: hsl(0, 100%, 40%);">-4fffc49b461133f0a4143b05a22fb30e  pjproject-2.10.tar.bz2</span><br><span>diff --git a/third-party/pjproject/pjproject-2.12.tar.bz2.md5 b/third-party/pjproject/pjproject-2.12.tar.bz2.md5</span><br><span>new file mode 100644</span><br><span>index 0000000..ab9b9d4</span><br><span>--- /dev/null</span><br><span>+++ b/third-party/pjproject/pjproject-2.12.tar.bz2.md5</span><br><span>@@ -0,0 +1 @@</span><br><span style="color: hsl(120, 100%, 40%);">+ad796d38f5f0357cb5b2fe1b4460b581  pjproject-2.12.tar.bz2</span><br><span>diff --git a/third-party/versions.mak b/third-party/versions.mak</span><br><span>index 2a59cf4..b95d687 100644</span><br><span>--- a/third-party/versions.mak</span><br><span>+++ b/third-party/versions.mak</span><br><span>@@ -1,2 +1,2 @@</span><br><span> JANSSON_VERSION = 2.14</span><br><span style="color: hsl(0, 100%, 40%);">-PJPROJECT_VERSION = 2.10</span><br><span style="color: hsl(120, 100%, 40%);">+PJPROJECT_VERSION = 2.12</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18112">change 18112</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/c/asterisk/+/18112"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 18 </div>
<div style="display:none"> Gerrit-Change-Id: Id39ece02dedb7b9f739e0e37ea47d76854af7191 </div>
<div style="display:none"> Gerrit-Change-Number: 18112 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>