[Asterisk-code-review] pjproject: Update bundled to 2.12 release. (asterisk[18])
Joshua Colp
asteriskteam at digium.com
Mon Feb 28 08:39:16 CST 2022
Joshua Colp has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/18112 )
Change subject: pjproject: Update bundled to 2.12 release.
......................................................................
pjproject: Update bundled to 2.12 release.
ASTERISK-29351
Change-Id: Id39ece02dedb7b9f739e0e37ea47d76854af7191
---
M third-party/pjproject/patches/0000-configure-ssl-library-path.patch
M third-party/pjproject/patches/0000-remove-third-party.patch
D third-party/pjproject/patches/0000-set_apps_initial_log_level.patch
D third-party/pjproject/patches/0000-solaris.patch
D third-party/pjproject/patches/0011-sip_inv_patch.patch
D third-party/pjproject/patches/0020-pjlib_cancel_timer_0.patch
D third-party/pjproject/patches/0050-fix-race-parallel-build.patch
D third-party/pjproject/patches/0060-clone-sdp-for-sip-timer-refresh-invite.patch
D third-party/pjproject/patches/0070-fix-incorrect-copying-when-creating-cancel.patch
D third-party/pjproject/patches/0080-fix-sdp-neg-modify-local-offer.patch
D third-party/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch
D third-party/pjproject/patches/0100-fix-double-stun-free.patch
D third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch
D third-party/pjproject/patches/0111-ssl-premature-destroy.patch
D third-party/pjproject/patches/0120-pjmedia_sdp_attr_get_rtpmap-Strip-param-trailing-whi.patch
D third-party/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch
D third-party/pjproject/patches/0140-Fix-incorrect-unescaping-of-tokens-during-parsing-29.patch
D third-party/pjproject/patches/0150-Create-generic-pjsip_hdr_find-functions.patch
D third-party/pjproject/patches/0160-Additional-multipart-improvements.patch
D third-party/pjproject/pjproject-2.10.tar.bz2.md5
A third-party/pjproject/pjproject-2.12.tar.bz2.md5
M third-party/versions.mak
22 files changed, 27 insertions(+), 2,708 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/12/18112/1
diff --git a/third-party/pjproject/patches/0000-configure-ssl-library-path.patch b/third-party/pjproject/patches/0000-configure-ssl-library-path.patch
index 3c1f749..c4dbb49 100644
--- a/third-party/pjproject/patches/0000-configure-ssl-library-path.patch
+++ b/third-party/pjproject/patches/0000-configure-ssl-library-path.patch
@@ -1,19 +1,9 @@
-From e8000cc80e5f8ba02cc52852edc02cdb0e949525 Mon Sep 17 00:00:00 2001
-From: Richard Mudgett <rmudgett at digium.com>
-Date: Mon, 6 Aug 2018 11:24:25 -0500
-Subject: [PATCH 1/5] 0000-configure-ssl-library-path.patch
-
----
- aconfigure | 6 +++++-
- aconfigure.ac | 6 +++++-
- 2 files changed, 10 insertions(+), 2 deletions(-)
-
diff --git a/aconfigure b/aconfigure
-index 1c449b8..c4c6060 100755
+index d6f0e8809..9dcd46398 100755
--- a/aconfigure
+++ b/aconfigure
-@@ -7954,7 +7954,11 @@ else
- if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then
+@@ -8986,7 +8986,11 @@ else $as_nop
+ if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then
CFLAGS="$CFLAGS -I$with_ssl/include"
CPPFLAGS="$CPPFLAGS -I$with_ssl/include"
- LDFLAGS="$LDFLAGS -L$with_ssl/lib"
@@ -22,15 +12,15 @@
+ else
+ LDFLAGS="$LDFLAGS -L$with_ssl"
+ fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using SSL prefix... $with_ssl" >&5
- $as_echo "Using SSL prefix... $with_ssl" >&6; }
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using SSL prefix... $with_ssl" >&5
+ printf "%s\n" "Using SSL prefix... $with_ssl" >&6; }
fi
diff --git a/aconfigure.ac b/aconfigure.ac
-index 2c272cd..a5d6d97 100644
+index 16b311045..849da81ab 100644
--- a/aconfigure.ac
+++ b/aconfigure.ac
-@@ -1580,7 +1580,11 @@ AC_ARG_ENABLE(ssl,
- if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then
+@@ -1838,7 +1838,11 @@ AC_ARG_ENABLE(ssl,
+ if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then
CFLAGS="$CFLAGS -I$with_ssl/include"
CPPFLAGS="$CPPFLAGS -I$with_ssl/include"
- LDFLAGS="$LDFLAGS -L$with_ssl/lib"
@@ -42,6 +32,3 @@
AC_MSG_RESULT([Using SSL prefix... $with_ssl])
fi
---
-2.7.4
-
diff --git a/third-party/pjproject/patches/0000-remove-third-party.patch b/third-party/pjproject/patches/0000-remove-third-party.patch
index f25aeac..1de154d 100644
--- a/third-party/pjproject/patches/0000-remove-third-party.patch
+++ b/third-party/pjproject/patches/0000-remove-third-party.patch
@@ -1,14 +1,5 @@
-From 665a2fbc3a09a71cd77988ae2deb3f5d3e205f63 Mon Sep 17 00:00:00 2001
-From: Richard Mudgett <rmudgett at digium.com>
-Date: Thu, 23 Feb 2017 17:10:07 -0600
-Subject: [PATCH 2/5] 0000-remove-third-party.patch
-
----
- build.mak.in | 97 ------------------------------------------------------------
- 1 file changed, 97 deletions(-)
-
diff --git a/build.mak.in b/build.mak.in
-index 80ccad1..41ec64e 100644
+index 4bc464f8c..80681d961 100644
--- a/build.mak.in
+++ b/build.mak.in
@@ -1,4 +1,3 @@
@@ -16,7 +7,7 @@
include $(PJDIR)/version.mak
export PJ_DIR := $(PJDIR)
-@@ -37,19 +36,6 @@ export APP_THIRD_PARTY_EXT :=
+@@ -41,19 +40,6 @@ export APP_THIRD_PARTY_EXT :=
export APP_THIRD_PARTY_LIBS :=
export APP_THIRD_PARTY_LIB_FILES :=
@@ -36,7 +27,7 @@
ifeq (@ac_pjmedia_resample@,libresample)
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
-@@ -66,89 +52,6 @@ APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFI
+@@ -70,102 +56,6 @@ APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFI
endif
endif
@@ -122,10 +113,20 @@
-endif
-endif
-
+-ifneq (@ac_no_webrtc_aec3@,1)
+-ifeq (@ac_external_webrtc_aec3@,1)
+-APP_THIRD_PARTY_EXT += -lwebrtc-aec3
+-else
+-APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc-aec3-$(LIB_SUFFIX)
+-ifeq ($(PJ_SHARED_LIBRARIES),)
+-APP_THIRD_PARTY_LIBS += -lwebrtc-aec3-$(TARGET_NAME)
+-else
+-APP_THIRD_PARTY_LIBS += -lwebrtc-aec3
+-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)
+-endif
+-endif
+-endif
-
+
# Additional flags
@ac_build_mak_vars@
-
---
-2.7.4
-
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
deleted file mode 100644
index b1fe02c..0000000
--- a/third-party/pjproject/patches/0000-set_apps_initial_log_level.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From c40ad6ba454fdf6456d8ffa92faa4cd49f2c807d Mon Sep 17 00:00:00 2001
-From: Richard Mudgett <rmudgett at digium.com>
-Date: Thu, 23 Feb 2017 17:11:00 -0600
-Subject: [PATCH 3/5] 0000-set_apps_initial_log_level.patch
-
----
- pjsip-apps/src/pjsua/main.c | 2 ++
- pjsip-apps/src/pjsystest/main_console.c | 2 ++
- pjsip-apps/src/python/_pjsua.c | 3 ++-
- 3 files changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/pjsip-apps/src/pjsua/main.c b/pjsip-apps/src/pjsua/main.c
-index 2baaf82..11831f2 100644
---- a/pjsip-apps/src/pjsua/main.c
-+++ b/pjsip-apps/src/pjsua/main.c
-@@ -126,5 +126,7 @@ int main_func(int argc, char *argv[])
-
- int main(int argc, char *argv[])
- {
-+ pj_log_set_level(1);
-+
- return pj_run_app(&main_func, argc, argv, 0);
- }
-diff --git a/pjsip-apps/src/pjsystest/main_console.c b/pjsip-apps/src/pjsystest/main_console.c
-index 122cdc7..dc79eab 100644
---- a/pjsip-apps/src/pjsystest/main_console.c
-+++ b/pjsip-apps/src/pjsystest/main_console.c
-@@ -133,6 +133,8 @@ void gui_sleep(unsigned sec)
-
- int main()
- {
-+ pj_log_set_level(1);
-+
- if (systest_init() != PJ_SUCCESS)
- return 1;
-
-diff --git a/pjsip-apps/src/python/_pjsua.c b/pjsip-apps/src/python/_pjsua.c
-index 31b835e..3e15030 100644
---- a/pjsip-apps/src/python/_pjsua.c
-+++ b/pjsip-apps/src/python/_pjsua.c
-@@ -4434,7 +4434,8 @@ init_pjsua(void)
- PyObject* m = NULL;
- #define ADD_CONSTANT(mod,name) PyModule_AddIntConstant(mod,#name,name)
-
--
-+ pj_log_set_level(1);
-+
- PyEval_InitThreads();
-
- if (PyType_Ready(&PyTyp_pjsua_callback) < 0)
---
-2.7.4
-
diff --git a/third-party/pjproject/patches/0000-solaris.patch b/third-party/pjproject/patches/0000-solaris.patch
deleted file mode 100644
index 155cdbe..0000000
--- a/third-party/pjproject/patches/0000-solaris.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From 1ac599a0f29500a15faf0dbbdc2565cc7dce2420 Mon Sep 17 00:00:00 2001
-From: Shaun Ruffell <sruffell at digium.com>
-Date: Fri, 7 Sep 2012 14:31:19 -0500
-Subject: [PATCH 4/5] pjproject: Fix for Solaris builds. Do not undef s_addr.
-
-pjproject, in order to solve build problems on Windows [1], undefines s_addr in
-one of it's headers that is included in res_rtp_asterisk.c. On Solaris s_addr is
-not a structure member, but defined to map to the real strucuture member,
-therefore when building on Solaris it's possible to get build errors like:
-
- [CC] res_rtp_asterisk.c -> res_rtp_asterisk.o
- In file included from /export/home/admin/asterisk-11-svn/include/asterisk/stun.h:29,
- from res_rtp_asterisk.c:51:
- /export/home/admin/asterisk-11-svn/include/asterisk/network.h: In function `inaddrcmp':
- /export/home/admin/asterisk-11-svn/include/asterisk/network.h:92: error: structure has no member named `s_addr'
- /export/home/admin/asterisk-11-svn/include/asterisk/network.h:92: error: structure has no member named `s_addr'
- res_rtp_asterisk.c: In function `ast_rtp_on_ice_tx_pkt':
- res_rtp_asterisk.c:706: warning: dereferencing type-punned pointer will break strict-aliasing rules
- res_rtp_asterisk.c:710: warning: dereferencing type-punned pointer will break strict-aliasing rules
- res_rtp_asterisk.c: In function `rtp_add_candidates_to_ice':
- res_rtp_asterisk.c:1085: error: structure has no member named `s_addr'
- make[2]: *** [res_rtp_asterisk.o] Error 1
- make[1]: *** [res] Error 2
- make[1]: Leaving directory `/export/home/admin/asterisk-11-svn'
- gmake: *** [_cleantest_all] Error 2
-
-Unfortunately, in order to make this work, I also had to make sure pjproject
-only used the typdef pj_in_addr and not the struct pj_in_addr so that when
-building Asterisk I could "typedef struct in_addr pj_in_addr". It's possible
-then that the library and users of those interfaces in Asterisk have a different
-idea about the type of the argument. While on the surface it looks like they are
-all 32 bit big endian values.
-
-[1] http://trac.pjsip.org/repos/changeset/484
-
-Reported-by: Ben Klang
-(issues ASTERISK-20366)
-
-Updated by ASTERISK-27997
----
- pjlib/include/pj/sock.h | 8 +++++++-
- pjlib/src/pj/sock_bsd.c | 2 +-
- pjlib/src/pj/sock_symbian.cpp | 2 +-
- pjlib/src/pj/sock_uwp.cpp | 2 +-
- pjsip/src/test/transport_test.c | 2 +-
- 5 files changed, 11 insertions(+), 5 deletions(-)
-
-diff --git a/pjlib/include/pj/sock.h b/pjlib/include/pj/sock.h
-index 4daf298..c35833c 100644
---- a/pjlib/include/pj/sock.h
-+++ b/pjlib/include/pj/sock.h
-@@ -484,6 +484,7 @@ typedef enum pj_socket_sd_type
- */
- #define PJ_INVALID_SOCKET (-1)
-
-+#ifndef _ASTERISK_H
- /* Must undefine s_addr because of pj_in_addr below */
- #undef s_addr
-
-@@ -495,6 +496,11 @@ typedef struct pj_in_addr
- pj_uint32_t s_addr; /**< The 32bit IP address. */
- } pj_in_addr;
-
-+#else
-+#include <sys/types.h>
-+#include <netinet/in.h>
-+typedef struct in_addr pj_in_addr;
-+#endif
-
- /**
- * Maximum length of text representation of an IPv4 address.
-@@ -712,7 +718,7 @@ PJ_DECL(char*) pj_inet_ntoa(pj_in_addr inaddr);
- *
- * @return nonzero if the address is valid, zero if not.
- */
--PJ_DECL(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp);
-+PJ_DECL(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp);
-
- /**
- * This function converts an address in its standard text presentation form
-diff --git a/pjlib/src/pj/sock_bsd.c b/pjlib/src/pj/sock_bsd.c
-index e416991..940fce1 100644
---- a/pjlib/src/pj/sock_bsd.c
-+++ b/pjlib/src/pj/sock_bsd.c
-@@ -244,7 +244,7 @@ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)
- * numbers-and-dots notation into binary data and stores it in the structure
- * that inp points to.
- */
--PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)
-+PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp)
- {
- char tempaddr[PJ_INET_ADDRSTRLEN];
-
-diff --git a/pjlib/src/pj/sock_symbian.cpp b/pjlib/src/pj/sock_symbian.cpp
-index 09239b0..e72bbda 100644
---- a/pjlib/src/pj/sock_symbian.cpp
-+++ b/pjlib/src/pj/sock_symbian.cpp
-@@ -299,7 +299,7 @@ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)
- * numbers-and-dots notation into binary data and stores it in the structure
- * that inp points to.
- */
--PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)
-+PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp)
- {
- enum { MAXIPLEN = PJ_INET_ADDRSTRLEN };
-
-diff --git a/pjlib/src/pj/sock_uwp.cpp b/pjlib/src/pj/sock_uwp.cpp
-index 876c328..40250bf 100644
---- a/pjlib/src/pj/sock_uwp.cpp
-+++ b/pjlib/src/pj/sock_uwp.cpp
-@@ -933,7 +933,7 @@ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)
- * numbers-and-dots notation into binary data and stores it in the structure
- * that inp points to.
- */
--PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)
-+PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp)
- {
- char tempaddr[PJ_INET_ADDRSTRLEN];
-
-diff --git a/pjsip/src/test/transport_test.c b/pjsip/src/test/transport_test.c
-index e5083d1..c429cc7 100644
---- a/pjsip/src/test/transport_test.c
-+++ b/pjsip/src/test/transport_test.c
-@@ -35,7 +35,7 @@ int generic_transport_test(pjsip_transport *tp)
-
- /* Check that local address name is valid. */
- {
-- struct pj_in_addr addr;
-+ pj_in_addr addr;
-
- if (pj_inet_pton(pj_AF_INET(), &tp->local_name.host,
- &addr) == PJ_SUCCESS)
---
-2.7.4
-
diff --git a/third-party/pjproject/patches/0011-sip_inv_patch.patch b/third-party/pjproject/patches/0011-sip_inv_patch.patch
deleted file mode 100644
index 7f77c74..0000000
--- a/third-party/pjproject/patches/0011-sip_inv_patch.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-commit c3c1bf45cae2a35003aa16c267d59f97027f9c5e
-Author: Kevin Harwell <kharwell at digium.com>
-Date: Thu Jun 11 11:11:13 2020 -0500
-
- sip_inv - fix invite session ref count crash
-
- Ensure the session's ref count is only decremented under proper conditons.
-
- For more details see the following issue report:
- https://github.com/pjsip/pjproject/issues/2443
-
- Patch supplied by sauwming
-
-diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
-index ca225015b..7c11b1c8e 100644
---- a/pjsip/src/pjsip-ua/sip_inv.c
-+++ b/pjsip/src/pjsip-ua/sip_inv.c
-@@ -323,9 +323,19 @@ static void inv_set_state(pjsip_inv_session *inv, pjsip_inv_state state,
- (*mod_inv.cb.on_state_changed)(inv, e);
- pjsip_inv_dec_ref(inv);
-
-- /* Only decrement when previous state is not already DISCONNECTED */
-+ /* The above callback may change the state, so we need to be careful here
-+ * and only decrement inv under the following conditions:
-+ * 1. If the state parameter is DISCONNECTED, and previous state is not
-+ * already DISCONNECTED.
-+ * This is to make sure that dec_ref() is not called more than once.
-+ * 2. If current state is PJSIP_INV_STATE_DISCONNECTED.
-+ * This is to make sure that dec_ref() is not called if user restarts
-+ * inv within the callback. Note that this check must be last since
-+ * inv may have already been destroyed.
-+ */
- if (state == PJSIP_INV_STATE_DISCONNECTED &&
-- prev_state != PJSIP_INV_STATE_DISCONNECTED)
-+ prev_state != PJSIP_INV_STATE_DISCONNECTED &&
-+ inv->state == PJSIP_INV_STATE_DISCONNECTED)
- {
- pjsip_inv_dec_ref(inv);
- }
diff --git a/third-party/pjproject/patches/0020-pjlib_cancel_timer_0.patch b/third-party/pjproject/patches/0020-pjlib_cancel_timer_0.patch
deleted file mode 100644
index 09f72d8..0000000
--- a/third-party/pjproject/patches/0020-pjlib_cancel_timer_0.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-commit 40dd48d10911f4ff9b8dfbf16428fbc9acc434ba
-Author: Riza Sulistyo <trengginas at users.noreply.github.com>
-Date: Thu Jul 9 17:47:24 2020 +0700
-
- Modify timer_id check on cancel() (#2463)
-
- * modify timer_id check on cancel().
-
- * modification based on comments.
-
-diff --git a/pjlib/include/pj/timer.h b/pjlib/include/pj/timer.h
-index b738a6e76..4b76ab65d 100644
---- a/pjlib/include/pj/timer.h
-+++ b/pjlib/include/pj/timer.h
-@@ -120,7 +120,10 @@ typedef struct pj_timer_entry
-
- /**
- * Internal unique timer ID, which is assigned by the timer heap.
-- * Application should not touch this ID.
-+ * Positive values indicate that the timer entry is running,
-+ * while -1 means that it's not. Any other value may indicate that it
-+ * hasn't been properly initialised or is in a bad state.
-+ * Application should not touch this ID.
- */
- pj_timer_id_t _timer_id;
-
-diff --git a/pjlib/src/pj/timer.c b/pjlib/src/pj/timer.c
-index 66516fce8..34966c481 100644
---- a/pjlib/src/pj/timer.c
-+++ b/pjlib/src/pj/timer.c
-@@ -535,7 +535,7 @@ static int cancel( pj_timer_heap_t *ht,
- PJ_CHECK_STACK();
-
- // Check to see if the timer_id is out of range
-- if (entry->_timer_id < 0 || (pj_size_t)entry->_timer_id > ht->max_size) {
-+ if (entry->_timer_id < 1 || (pj_size_t)entry->_timer_id >= ht->max_size) {
- entry->_timer_id = -1;
- return 0;
- }
diff --git a/third-party/pjproject/patches/0050-fix-race-parallel-build.patch b/third-party/pjproject/patches/0050-fix-race-parallel-build.patch
deleted file mode 100644
index 674baa2..0000000
--- a/third-party/pjproject/patches/0050-fix-race-parallel-build.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 78683646c8bc670ec730a42494e075f671a08e28 Mon Sep 17 00:00:00 2001
-From: Guido Falsi <mad at madpilot.net>
-Date: Mon, 11 May 2020 08:50:39 +0200
-Subject: [PATCH] Fix race condition in parallel builds (#2426)
-
-* 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.
-
-* 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`.
----
- build/rules.mak | 12 ++++++------
- pjsip/build/Makefile | 2 +-
- 2 files changed, 7 insertions(+), 7 deletions(-)
-
-diff --git a/build/rules.mak b/build/rules.mak
-index 8fa98655e..912199c41 100644
---- a/build/rules.mak
-+++ b/build/rules.mak
-@@ -129,7 +129,7 @@ endif
- $(OBJDIR)/$(app).o: $(OBJDIRS) $(OBJS)
- $(CROSS_COMPILE)ld -r -o $@ $(OBJS)
-
--$(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o
-+$(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o | $(OBJDIRS)
- @echo Creating kbuild Makefile...
- @echo "# Our module name:" > $(OBJDIR)/Makefile
- @echo 'obj-m += $(app).o' >> $(OBJDIR)/Makefile
-@@ -154,27 +154,27 @@ $(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o
- ../lib/$(app).ko: $(LIB) $(OBJDIR)/$(app).ko
- cp $(OBJDIR)/$(app).ko ../lib
-
--$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.m
-+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.m | $(OBJDIRS)
- $(CC) $($(APP)_CFLAGS) \
- $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
- $(subst /,$(HOST_PSEP),$<)
-
--$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c
-+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c | $(OBJDIRS)
- $(CC) $($(APP)_CFLAGS) \
- $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
- $(subst /,$(HOST_PSEP),$<)
-
--$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.S
-+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.S | $(OBJDIRS)
- $(CC) $($(APP)_CFLAGS) \
- $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
- $(subst /,$(HOST_PSEP),$<)
-
--$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp
-+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp | $(OBJDIRS)
- $(CXX) $($(APP)_CXXFLAGS) \
- $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
- $(subst /,$(HOST_PSEP),$<)
-
--$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc
-+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc | $(OBJDIRS)
- $(CXX) $($(APP)_CXXFLAGS) \
- $(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
- $(subst /,$(HOST_PSEP),$<)
-diff --git a/pjsip/build/Makefile b/pjsip/build/Makefile
-index b85c7817a..20777909f 100644
---- a/pjsip/build/Makefile
-+++ b/pjsip/build/Makefile
-@@ -262,7 +262,7 @@ $(PJSUA_LIB_LIB) $(PJSUA_LIB_SONAME): $(PJSIP_LIB) $(PJSIP_SONAME) $(PJSIP_SIMPL
-
- pjsua2-lib: $(PJSUA2_LIB_LIB)
- $(PJSUA2_LIB_SONAME): $(PJSUA2_LIB_LIB)
--$(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)
-+$(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)
- $(MAKE) -f $(RULES_MAK) APP=PJSUA2_LIB app=pjsua2-lib $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)
-
- pjsip-test: $(TEST_EXE)
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
deleted file mode 100644
index f1f180a..0000000
--- a/third-party/pjproject/patches/0060-clone-sdp-for-sip-timer-refresh-invite.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff -ur source.orig/pjmedia/src/pjmedia/sdp_neg.c source/pjmedia/src/pjmedia/sdp_neg.c
---- source.orig/pjmedia/src/pjmedia/sdp_neg.c 2020-07-02 10:35:42.022459904 +0200
-+++ source/pjmedia/src/pjmedia/sdp_neg.c 2020-07-02 10:33:24.996316867 +0200
-@@ -906,7 +906,7 @@
- * after receiving remote answer.
- */
- static pj_status_t process_answer(pj_pool_t *pool,
-- pjmedia_sdp_session *offer,
-+ pjmedia_sdp_session *local_offer,
- pjmedia_sdp_session *answer,
- pj_bool_t allow_asym,
- pjmedia_sdp_session **p_active)
-@@ -914,10 +914,14 @@
- unsigned omi = 0; /* Offer media index */
- unsigned ami = 0; /* Answer media index */
- pj_bool_t has_active = PJ_FALSE;
-+ pjmedia_sdp_session *offer;
- pj_status_t status;
-
- /* Check arguments. */
-- PJ_ASSERT_RETURN(pool && offer && answer && p_active, PJ_EINVAL);
-+ PJ_ASSERT_RETURN(pool && local_offer && answer && p_active, PJ_EINVAL);
-+
-+ /* Duplicate local offer SDP. */
-+ offer = pjmedia_sdp_session_clone(pool, local_offer);
-
- /* Check that media count match between offer and answer */
- // Ticket #527, different media count is allowed for more interoperability,
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
deleted file mode 100644
index 95725c1..0000000
--- a/third-party/pjproject/patches/0070-fix-incorrect-copying-when-creating-cancel.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From ce18018cc17bef8f80c08686e3a7b28384ef3ba5 Mon Sep 17 00:00:00 2001
-From: sauwming <ming at teluu.com>
-Date: Mon, 12 Oct 2020 13:31:25 +0800
-Subject: [PATCH] Fix incorrect copying of destination info when creating
- CANCEL (#2546)
-
----
- pjsip/src/pjsip/sip_util.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c
-index d10a6fa30..a1bf878ea 100644
---- a/pjsip/src/pjsip/sip_util.c
-+++ b/pjsip/src/pjsip/sip_util.c
-@@ -779,14 +779,14 @@ PJ_DEF(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,
- pjsip_hdr_clone(cancel_tdata->pool, req_tdata->saved_strict_route);
- }
-
-- /* Copy the destination host name from the original request */
-- pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,
-- &req_tdata->dest_info.name);
--
-- /* Finally copy the destination info from the original request */
-+ /* Copy the destination info from the original request */
- pj_memcpy(&cancel_tdata->dest_info, &req_tdata->dest_info,
- sizeof(req_tdata->dest_info));
-
-+ /* Finally, copy the destination host name from the original request */
-+ pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,
-+ &req_tdata->dest_info.name);
-+
- /* Done.
- * Return the transmit buffer containing the CANCEL request.
- */
---
-2.25.1
-
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
deleted file mode 100644
index c27a489..0000000
--- a/third-party/pjproject/patches/0080-fix-sdp-neg-modify-local-offer.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c
-index 3b85b4273..a14009662 100644
---- a/pjmedia/src/pjmedia/sdp_neg.c
-+++ b/pjmedia/src/pjmedia/sdp_neg.c
-@@ -304,7 +304,6 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(
- {
- pjmedia_sdp_session *new_offer;
- pjmedia_sdp_session *old_offer;
-- char media_used[PJMEDIA_MAX_SDP_MEDIA];
- unsigned oi; /* old offer media index */
- pj_status_t status;
-
-@@ -323,8 +322,19 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(
- /* Change state to STATE_LOCAL_OFFER */
- neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER;
-
-+ /* When there is no active local SDP in state PJMEDIA_SDP_NEG_STATE_DONE,
-+ * it means that the previous initial SDP nego must have been failed,
-+ * so we'll just set the local SDP offer here.
-+ */
-+ if (!neg->active_local_sdp) {
-+ neg->initial_sdp_tmp = NULL;
-+ neg->initial_sdp = pjmedia_sdp_session_clone(pool, local);
-+ neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, local);
-+
-+ return PJ_SUCCESS;
-+ }
-+
- /* Init vars */
-- pj_bzero(media_used, sizeof(media_used));
- old_offer = neg->active_local_sdp;
- new_offer = pjmedia_sdp_session_clone(pool, local);
-
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
deleted file mode 100644
index a2db220..0000000
--- a/third-party/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch
+++ /dev/null
@@ -1,212 +0,0 @@
-From bdbeb7c4b2b11efc2e59f5dee7aa4360a2bc9fff Mon Sep 17 00:00:00 2001
-From: sauwming <ming at teluu.com>
-Date: Thu, 22 Apr 2021 14:03:28 +0800
-Subject: [PATCH 90/90] Skip unsupported digest algorithm (#2408)
-
-Co-authored-by: Nanang Izzuddin <nanang at teluu.com>
----
- pjsip/src/pjsip/sip_auth_client.c | 32 +++++--
- tests/pjsua/scripts-sipp/uas-auth-two-algo.py | 7 ++
- .../pjsua/scripts-sipp/uas-auth-two-algo.xml | 83 +++++++++++++++++++
- 3 files changed, 117 insertions(+), 5 deletions(-)
- create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.py
- create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.xml
-
-diff --git a/pjsip/src/pjsip/sip_auth_client.c b/pjsip/src/pjsip/sip_auth_client.c
-index 828b04db9..7eb2f5cd1 100644
---- a/pjsip/src/pjsip/sip_auth_client.c
-+++ b/pjsip/src/pjsip/sip_auth_client.c
-@@ -1042,7 +1042,7 @@ static pj_status_t process_auth( pj_pool_t *req_pool,
- pjsip_hdr *hdr;
- pj_status_t status;
-
-- /* See if we have sent authorization header for this realm */
-+ /* See if we have sent authorization header for this realm (and scheme) */
- hdr = tdata->msg->hdr.next;
- while (hdr != &tdata->msg->hdr) {
- if ((hchal->type == PJSIP_H_WWW_AUTHENTICATE &&
-@@ -1052,7 +1052,8 @@ static pj_status_t process_auth( pj_pool_t *req_pool,
- {
- sent_auth = (pjsip_authorization_hdr*) hdr;
- if (pj_stricmp(&hchal->challenge.common.realm,
-- &sent_auth->credential.common.realm )==0)
-+ &sent_auth->credential.common.realm)==0 &&
-+ pj_stricmp(&hchal->scheme, &sent_auth->scheme)==0)
- {
- /* If this authorization has empty response, remove it. */
- if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&
-@@ -1062,6 +1063,14 @@ static pj_status_t process_auth( pj_pool_t *req_pool,
- hdr = hdr->next;
- pj_list_erase(sent_auth);
- continue;
-+ } else
-+ if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&
-+ pj_stricmp(&sent_auth->credential.digest.algorithm,
-+ &hchal->challenge.digest.algorithm)!=0)
-+ {
-+ /* Same 'digest' scheme but different algo */
-+ hdr = hdr->next;
-+ continue;
- } else {
- /* Found previous authorization attempt */
- break;
-@@ -1155,9 +1164,10 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
- {
- pjsip_tx_data *tdata;
- const pjsip_hdr *hdr;
-- unsigned chal_cnt;
-+ unsigned chal_cnt, auth_cnt;
- pjsip_via_hdr *via;
- pj_status_t status;
-+ pj_status_t last_auth_err;
-
- PJ_ASSERT_RETURN(sess && rdata && old_request && new_request,
- PJ_EINVAL);
-@@ -1178,6 +1188,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
- */
- hdr = rdata->msg_info.msg->hdr.next;
- chal_cnt = 0;
-+ auth_cnt = 0;
-+ last_auth_err = PJSIP_EAUTHNOAUTH;
- while (hdr != &rdata->msg_info.msg->hdr) {
- pjsip_cached_auth *cached_auth;
- const pjsip_www_authenticate_hdr *hchal;
-@@ -1222,8 +1234,13 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
- */
- status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri,
- tdata, sess, cached_auth, &hauth);
-- if (status != PJ_SUCCESS)
-- return status;
-+ if (status != PJ_SUCCESS) {
-+ last_auth_err = status;
-+
-+ /* Process next header. */
-+ hdr = hdr->next;
-+ continue;
-+ }
-
- if (pj_pool_get_used_size(cached_auth->pool) >
- PJSIP_AUTH_CACHED_POOL_MAX_SIZE)
-@@ -1236,12 +1253,17 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
-
- /* Process next header. */
- hdr = hdr->next;
-+ auth_cnt++;
- }
-
- /* Check if challenge is present */
- if (chal_cnt == 0)
- return PJSIP_EAUTHNOCHAL;
-
-+ /* Check if any authorization header has been created */
-+ if (auth_cnt == 0)
-+ return last_auth_err;
-+
- /* Remove branch param in Via header. */
- via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
- via->branch_param.slen = 0;
-diff --git a/tests/pjsua/scripts-sipp/uas-auth-two-algo.py b/tests/pjsua/scripts-sipp/uas-auth-two-algo.py
-new file mode 100644
-index 000000000..c79c9f6d3
---- /dev/null
-+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.py
-@@ -0,0 +1,7 @@
-+# $Id$
-+#
-+import inc_const as const
-+
-+PJSUA = ["--null-audio --max-calls=1 --id=sip:a at localhost --username=a --realm=* --registrar=$SIPP_URI"]
-+
-+PJSUA_EXPECTS = [[0, "registration success", ""]]
-diff --git a/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml
-new file mode 100644
-index 000000000..bd4871940
---- /dev/null
-+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml
-@@ -0,0 +1,83 @@
-+<?xml version="1.0" encoding="ISO-8859-1" ?>
-+<!DOCTYPE scenario SYSTEM "sipp.dtd">
-+
-+<scenario name="Basic UAS responder">
-+ <recv request="REGISTER" crlf="true">
-+ </recv>
-+
-+ <send>
-+ <![CDATA[
-+ SIP/2.0 100 Trying
-+ [last_Via:];received=1.1.1.1;rport=1111
-+ [last_From:]
-+ [last_To:];tag=[call_number]
-+ [last_Call-ID:]
-+ [last_CSeq:]
-+ Content-Length: 0
-+ ]]>
-+ </send>
-+
-+ <send>
-+ <![CDATA[
-+ SIP/2.0 401 Unauthorized
-+ [last_Via:];received=1.1.1.1;rport=1111
-+ [last_From:]
-+ [last_To:];tag=[call_number]
-+ [last_Call-ID:]
-+ [last_CSeq:]
-+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=SHA-256, qop="auth"
-+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=MD5, qop="auth"
-+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=MD2, qop="auth"
-+ Content-Length: 0
-+ ]]>
-+ </send>
-+
-+ <recv request="REGISTER" crlf="true">
-+ <action>
-+ <ereg regexp=".*"
-+ search_in="hdr"
-+ header="Authorization:"
-+ assign_to="have_auth" />
-+ </action>
-+ </recv>
-+
-+ <nop next="resp_okay" test="have_auth" />
-+
-+ <send next="end">
-+ <![CDATA[
-+ SIP/2.0 403 no auth
-+ [last_Via:];received=1.1.1.1;rport=1111
-+ [last_From:]
-+ [last_To:];tag=[call_number]
-+ [last_Call-ID:]
-+ [last_CSeq:]
-+ [last_Contact:]
-+ Content-Length: 0
-+ ]]>
-+ </send>
-+
-+ <label id="resp_okay" />
-+
-+ <send>
-+ <![CDATA[
-+ SIP/2.0 200 OK
-+ [last_Via:];received=1.1.1.1;rport=1111
-+ [last_From:]
-+ [last_To:];tag=[call_number]
-+ [last_Call-ID:]
-+ [last_CSeq:]
-+ [last_Contact:]
-+ Content-Length: 0
-+ ]]>
-+ </send>
-+
-+ <label id="end" />
-+
-+ <!-- definition of the response time repartition table (unit is ms) -->
-+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
-+
-+ <!-- definition of the call length repartition table (unit is ms) -->
-+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
-+
-+</scenario>
-+
---
-2.31.1
-
diff --git a/third-party/pjproject/patches/0100-fix-double-stun-free.patch b/third-party/pjproject/patches/0100-fix-double-stun-free.patch
deleted file mode 100644
index b1cfcfd..0000000
--- a/third-party/pjproject/patches/0100-fix-double-stun-free.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-commit f0ff5817d0647bdecd1ec99488db9378e304cf83
-Author: sauwming <ming at teluu.com>
-Date: Mon May 17 09:56:27 2021 +0800
-
- Fix double free of stun session (#2709)
-
-diff --git a/pjnath/include/pjnath/stun_session.h b/pjnath/include/pjnath/stun_session.h
-index bee630ab4..afca06911 100644
---- a/pjnath/include/pjnath/stun_session.h
-+++ b/pjnath/include/pjnath/stun_session.h
-@@ -341,6 +341,7 @@ struct pj_stun_tx_data
- pj_pool_t *pool; /**< Pool. */
- pj_stun_session *sess; /**< The STUN session. */
- pj_stun_msg *msg; /**< The STUN message. */
-+ pj_bool_t is_destroying; /**< Is destroying? */
-
- void *token; /**< The token. */
-
-diff --git a/pjnath/src/pjnath/stun_session.c b/pjnath/src/pjnath/stun_session.c
-index f2b4f7058..d436b94bf 100644
---- a/pjnath/src/pjnath/stun_session.c
-+++ b/pjnath/src/pjnath/stun_session.c
-@@ -167,16 +167,27 @@ static void tdata_on_destroy(void *arg)
- {
- pj_stun_tx_data *tdata = (pj_stun_tx_data*)arg;
-
-+ if (tdata->grp_lock) {
-+ pj_grp_lock_dec_ref(tdata->sess->grp_lock);
-+ }
-+
- pj_pool_safe_release(&tdata->pool);
- }
-
- static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)
- {
-- TRACE_((THIS_FILE, "tdata %p destroy request, force=%d, tsx=%p", tdata,
-- force, tdata->client_tsx));
-+ TRACE_((THIS_FILE,
-+ "tdata %p destroy request, force=%d, tsx=%p, destroying=%d",
-+ tdata, force, tdata->client_tsx, tdata->is_destroying));
-+
-+ /* Just return if destroy has been requested before */
-+ if (tdata->is_destroying)
-+ return;
-
- /* STUN session may have been destroyed, except when tdata is cached. */
-
-+ tdata->is_destroying = PJ_TRUE;
-+
- if (tdata->res_timer.id != PJ_FALSE) {
- pj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap,
- &tdata->res_timer, PJ_FALSE);
-@@ -189,7 +200,6 @@ static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)
- pj_stun_client_tsx_set_data(tdata->client_tsx, NULL);
- }
- if (tdata->grp_lock) {
-- pj_grp_lock_dec_ref(tdata->sess->grp_lock);
- pj_grp_lock_dec_ref(tdata->grp_lock);
- } else {
- tdata_on_destroy(tdata);
-@@ -200,11 +210,11 @@ static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)
- /* "Probably" this is to absorb retransmission */
- pj_time_val delay = {0, 300};
- pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay);
-+ tdata->is_destroying = PJ_FALSE;
-
- } else {
- pj_list_erase(tdata);
- if (tdata->grp_lock) {
-- pj_grp_lock_dec_ref(tdata->sess->grp_lock);
- pj_grp_lock_dec_ref(tdata->grp_lock);
- } else {
- tdata_on_destroy(tdata);
-@@ -238,7 +248,7 @@ static void on_cache_timeout(pj_timer_heap_t *timer_heap,
- sess = tdata->sess;
-
- pj_grp_lock_acquire(sess->grp_lock);
-- if (sess->is_destroying) {
-+ if (sess->is_destroying || tdata->is_destroying) {
- pj_grp_lock_release(sess->grp_lock);
- return;
- }
diff --git a/third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch b/third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch
deleted file mode 100644
index 81781f2..0000000
--- a/third-party/pjproject/patches/0110-tls-parent-listener-destroyed.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From bb92c97ea512aa0ef316c9b2335c7d57b84dfc9a Mon Sep 17 00:00:00 2001
-From: Nanang Izzuddin <nanang at teluu.com>
-Date: Wed, 16 Jun 2021 12:12:35 +0700
-Subject: [PATCH 1/2] - Avoid SSL socket parent/listener getting destroyed
- during handshake by increasing parent's reference count. - Add missing SSL
- socket close when the newly accepted SSL socket is discarded in SIP TLS
- transport.
-
----
- pjlib/src/pj/ssl_sock_imp_common.c | 44 +++++++++++++++++++++--------
- pjsip/src/pjsip/sip_transport_tls.c | 23 ++++++++++++++-
- 2 files changed, 55 insertions(+), 12 deletions(-)
-
-diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c
-index bc468bcb3..abec31805 100644
---- a/pjlib/src/pj/ssl_sock_imp_common.c
-+++ b/pjlib/src/pj/ssl_sock_imp_common.c
-@@ -224,6 +224,8 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
-
- /* Accepting */
- if (ssock->is_server) {
-+ pj_bool_t ret = PJ_TRUE;
-+
- if (status != PJ_SUCCESS) {
- /* Handshake failed in accepting, destroy our self silently. */
-
-@@ -241,6 +243,12 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
- status);
- }
-
-+ /* Decrement ref count of parent */
-+ if (ssock->parent->param.grp_lock) {
-+ pj_grp_lock_dec_ref(ssock->parent->param.grp_lock);
-+ ssock->parent = NULL;
-+ }
-+
- /* Originally, this is a workaround for ticket #985. However,
- * a race condition may occur in multiple worker threads
- * environment when we are destroying SSL objects while other
-@@ -284,23 +292,29 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
-
- return PJ_FALSE;
- }
-+
- /* Notify application the newly accepted SSL socket */
- if (ssock->param.cb.on_accept_complete2) {
-- pj_bool_t ret;
- ret = (*ssock->param.cb.on_accept_complete2)
- (ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr,
- pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr),
- status);
-- if (ret == PJ_FALSE)
-- return PJ_FALSE;
- } else if (ssock->param.cb.on_accept_complete) {
-- pj_bool_t ret;
- ret = (*ssock->param.cb.on_accept_complete)
- (ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr,
- pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr));
-- if (ret == PJ_FALSE)
-- return PJ_FALSE;
- }
-+
-+ /* Decrement ref count of parent and reset parent (we don't need it
-+ * anymore, right?).
-+ */
-+ if (ssock->parent->param.grp_lock) {
-+ pj_grp_lock_dec_ref(ssock->parent->param.grp_lock);
-+ ssock->parent = NULL;
-+ }
-+
-+ if (ret == PJ_FALSE)
-+ return PJ_FALSE;
- }
-
- /* Connecting */
-@@ -864,9 +878,13 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
- if (status != PJ_SUCCESS)
- goto on_return;
-
-+ /* Set parent and add ref count (avoid parent destroy during handshake) */
-+ ssock->parent = ssock_parent;
-+ if (ssock->parent->param.grp_lock)
-+ pj_grp_lock_add_ref(ssock->parent->param.grp_lock);
-+
- /* Update new SSL socket attributes */
- ssock->sock = newsock;
-- ssock->parent = ssock_parent;
- ssock->is_server = PJ_TRUE;
- if (ssock_parent->cert) {
- status = pj_ssl_sock_set_certificate(ssock, ssock->pool,
-@@ -913,16 +931,20 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
- ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool,
- ssock->param.async_cnt,
- sizeof(void*));
-- if (!ssock->asock_rbuf)
-- return PJ_ENOMEM;
-+ if (!ssock->asock_rbuf) {
-+ status = PJ_ENOMEM;
-+ goto on_return;
-+ }
-
- for (i = 0; i<ssock->param.async_cnt; ++i) {
-- ssock->asock_rbuf[i] = (void*) pj_pool_alloc(
-+ ssock->asock_rbuf[i] = (void*) pj_pool_alloc(
- ssock->pool,
- ssock->param.read_buffer_size +
- sizeof(read_data_t*));
-- if (!ssock->asock_rbuf[i])
-- return PJ_ENOMEM;
-+ if (!ssock->asock_rbuf[i]) {
-+ status = PJ_ENOMEM;
-+ goto on_return;
-+ }
- }
-
- /* Create active socket */
-diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c
-index 17b7ae3de..ce524d53f 100644
---- a/pjsip/src/pjsip/sip_transport_tls.c
-+++ b/pjsip/src/pjsip/sip_transport_tls.c
-@@ -1325,9 +1325,26 @@ static pj_bool_t on_accept_complete2(pj_ssl_sock_t *ssock,
- PJ_UNUSED_ARG(src_addr_len);
-
- listener = (struct tls_listener*) pj_ssl_sock_get_user_data(ssock);
-+ if (!listener) {
-+ /* Listener already destroyed, e.g: after TCP accept but before SSL
-+ * handshake is completed.
-+ */
-+ if (new_ssock && accept_status == PJ_SUCCESS) {
-+ /* Close the SSL socket if the accept op is successful */
-+ PJ_LOG(4,(THIS_FILE,
-+ "Incoming TLS connection from %s (sock=%d) is discarded "
-+ "because listener is already destroyed",
-+ pj_sockaddr_print(src_addr, addr, sizeof(addr), 3),
-+ new_ssock));
-+
-+ pj_ssl_sock_close(new_ssock);
-+ }
-+
-+ return PJ_FALSE;
-+ }
-
- if (accept_status != PJ_SUCCESS) {
-- if (listener && listener->tls_setting.on_accept_fail_cb) {
-+ if (listener->tls_setting.on_accept_fail_cb) {
- pjsip_tls_on_accept_fail_param param;
- pj_ssl_sock_info ssi;
-
-@@ -1350,6 +1367,8 @@ static pj_bool_t on_accept_complete2(pj_ssl_sock_t *ssock,
- PJ_ASSERT_RETURN(new_ssock, PJ_TRUE);
-
- if (!listener->is_registered) {
-+ pj_ssl_sock_close(new_ssock);
-+
- if (listener->tls_setting.on_accept_fail_cb) {
- pjsip_tls_on_accept_fail_param param;
- pj_bzero(¶m, sizeof(param));
-@@ -1401,6 +1420,8 @@ static pj_bool_t on_accept_complete2(pj_ssl_sock_t *ssock,
- ssl_info.grp_lock, &tls);
-
- if (status != PJ_SUCCESS) {
-+ pj_ssl_sock_close(new_ssock);
-+
- if (listener->tls_setting.on_accept_fail_cb) {
- pjsip_tls_on_accept_fail_param param;
- pj_bzero(¶m, sizeof(param));
diff --git a/third-party/pjproject/patches/0111-ssl-premature-destroy.patch b/third-party/pjproject/patches/0111-ssl-premature-destroy.patch
deleted file mode 100644
index 9de2915..0000000
--- a/third-party/pjproject/patches/0111-ssl-premature-destroy.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From 68c69f516f95df1faa42e5647e9ce7cfdc41ac38 Mon Sep 17 00:00:00 2001
-From: Nanang Izzuddin <nanang at teluu.com>
-Date: Wed, 16 Jun 2021 12:15:29 +0700
-Subject: [PATCH 2/2] - Fix silly mistake: accepted active socket created
- without group lock in SSL socket. - Replace assertion with normal validation
- check of SSL socket instance in OpenSSL verification callback (verify_cb())
- to avoid crash, e.g: if somehow race condition with SSL socket destroy
- happens or OpenSSL application data index somehow gets corrupted.
-
----
- pjlib/src/pj/ssl_sock_imp_common.c | 3 +-
- pjlib/src/pj/ssl_sock_ossl.c | 45 +++++++++++++++++++++++++-----
- 2 files changed, 40 insertions(+), 8 deletions(-)
-
-diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c
-index bc468bcb3..c2b8a846b 100644
---- a/pjlib/src/pj/ssl_sock_imp_common.c
-+++ b/pjlib/src/pj/ssl_sock_imp_common.c
-@@ -927,6 +927,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
-
- /* Create active socket */
- pj_activesock_cfg_default(&asock_cfg);
-+ asock_cfg.grp_lock = ssock->param.grp_lock;
- asock_cfg.async_cnt = ssock->param.async_cnt;
- asock_cfg.concurrency = ssock->param.concurrency;
- asock_cfg.whole_data = PJ_TRUE;
-@@ -942,7 +943,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
- goto on_return;
-
- pj_grp_lock_add_ref(glock);
-- asock_cfg.grp_lock = ssock->param.grp_lock = glock;
-+ ssock->param.grp_lock = glock;
- pj_grp_lock_add_handler(ssock->param.grp_lock, ssock->pool, ssock,
- ssl_on_destroy);
- }
-diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
-index a95b339a5..56841f80a 100644
---- a/pjlib/src/pj/ssl_sock_ossl.c
-+++ b/pjlib/src/pj/ssl_sock_ossl.c
-@@ -327,7 +327,8 @@ static pj_status_t STATUS_FROM_SSL_ERR(char *action, pj_ssl_sock_t *ssock,
- ERROR_LOG("STATUS_FROM_SSL_ERR", err, ssock);
- }
-
-- ssock->last_err = err;
-+ if (ssock)
-+ ssock->last_err = err;
- return GET_STATUS_FROM_SSL_ERR(err);
- }
-
-@@ -344,7 +345,8 @@ static pj_status_t STATUS_FROM_SSL_ERR2(char *action, pj_ssl_sock_t *ssock,
- /* Dig for more from OpenSSL error queue */
- SSLLogErrors(action, ret, err, len, ssock);
-
-- ssock->last_err = ssl_err;
-+ if (ssock)
-+ ssock->last_err = ssl_err;
- return GET_STATUS_FROM_SSL_ERR(ssl_err);
- }
-
-@@ -587,6 +589,13 @@ static pj_status_t init_openssl(void)
-
- /* Create OpenSSL application data index for SSL socket */
- sslsock_idx = SSL_get_ex_new_index(0, "SSL socket", NULL, NULL, NULL);
-+ if (sslsock_idx == -1) {
-+ status = STATUS_FROM_SSL_ERR2("Init", NULL, -1, ERR_get_error(), 0);
-+ PJ_LOG(1,(THIS_FILE,
-+ "Fatal error: failed to get application data index for "
-+ "SSL socket"));
-+ return status;
-+ }
-
- return status;
- }
-@@ -614,21 +623,36 @@ static int password_cb(char *buf, int num, int rwflag, void *user_data)
- }
-
-
--/* SSL password callback. */
-+/* SSL certificate verification result callback.
-+ * Note that this callback seems to be always called from library worker
-+ * thread, e.g: active socket on_read_complete callback, which should have
-+ * already been equipped with race condition avoidance mechanism (should not
-+ * be destroyed while callback is being invoked).
-+ */
- static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
- {
-- pj_ssl_sock_t *ssock;
-- SSL *ossl_ssl;
-+ pj_ssl_sock_t *ssock = NULL;
-+ SSL *ossl_ssl = NULL;
- int err;
-
- /* Get SSL instance */
- ossl_ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
- SSL_get_ex_data_X509_STORE_CTX_idx());
-- pj_assert(ossl_ssl);
-+ if (!ossl_ssl) {
-+ PJ_LOG(1,(THIS_FILE,
-+ "SSL verification callback failed to get SSL instance"));
-+ goto on_return;
-+ }
-
- /* Get SSL socket instance */
- ssock = SSL_get_ex_data(ossl_ssl, sslsock_idx);
-- pj_assert(ssock);
-+ if (!ssock) {
-+ /* SSL socket may have been destroyed */
-+ PJ_LOG(1,(THIS_FILE,
-+ "SSL verification callback failed to get SSL socket "
-+ "instance (sslsock_idx=%d).", sslsock_idx));
-+ goto on_return;
-+ }
-
- /* Store verification status */
- err = X509_STORE_CTX_get_error(x509_ctx);
-@@ -706,6 +730,7 @@ static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
- if (PJ_FALSE == ssock->param.verify_peer)
- preverify_ok = 1;
-
-+on_return:
- return preverify_ok;
- }
-
-@@ -1213,6 +1238,12 @@ static void ssl_destroy(pj_ssl_sock_t *ssock)
- static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
- {
- ossl_sock_t *ossock = (ossl_sock_t *)ssock;
-+
-+ /* Detach from SSL instance */
-+ if (ossock->ossl_ssl) {
-+ SSL_set_ex_data(ossock->ossl_ssl, sslsock_idx, NULL);
-+ }
-+
- /**
- * Avoid calling SSL_shutdown() if handshake wasn't completed.
- * OpenSSL 1.0.2f complains if SSL_shutdown() is called during an
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
deleted file mode 100644
index 1b1fcad..0000000
--- a/third-party/pjproject/patches/0120-pjmedia_sdp_attr_get_rtpmap-Strip-param-trailing-whi.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 2ae784030b0d9cf217c3d562af20e4967f19a3dc Mon Sep 17 00:00:00 2001
-From: George Joseph <gjoseph at sangoma.com>
-Date: Tue, 14 Sep 2021 10:47:29 -0600
-Subject: [PATCH] pjmedia_sdp_attr_get_rtpmap: Strip param trailing whitespace
-
-Use pj_scan_get() to parse the param part of rtpmap so
-trailing whitespace is automatically stripped.
-
-Fixes #2827
----
- pjmedia/src/pjmedia/sdp.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/pjmedia/src/pjmedia/sdp.c b/pjmedia/src/pjmedia/sdp.c
-index 5d05a0d9c..3448749c9 100644
---- a/pjmedia/src/pjmedia/sdp.c
-+++ b/pjmedia/src/pjmedia/sdp.c
-@@ -313,9 +313,9 @@ PJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtpmap( const pjmedia_sdp_attr *attr,
-
- /* Expecting either '/' or EOF */
- if (*scanner.curptr == '/') {
-+ /* Skip the '/' */
- pj_scan_get_char(&scanner);
-- rtpmap->param.ptr = scanner.curptr;
-- rtpmap->param.slen = scanner.end - scanner.curptr;
-+ pj_scan_get(&scanner, &cs_token, &rtpmap->param);
- } else {
- rtpmap->param.slen = 0;
- }
---
-2.31.1
-
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
deleted file mode 100644
index 91feefb..0000000
--- a/third-party/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch
+++ /dev/null
@@ -1,661 +0,0 @@
-From 0ed41eb5fd0e4192e1b7dc374f819d17aef3e805 Mon Sep 17 00:00:00 2001
-From: George Joseph <gtjoseph at users.noreply.github.com>
-Date: Tue, 21 Dec 2021 19:32:22 -0700
-Subject: [PATCH] sip_inv: Additional multipart support (#2919) (#2920)
-
----
- pjsip/include/pjsip-ua/sip_inv.h | 108 ++++++++++-
- pjsip/src/pjsip-ua/sip_inv.c | 240 ++++++++++++++++++++-----
- pjsip/src/test/inv_offer_answer_test.c | 103 ++++++++++-
- 3 files changed, 394 insertions(+), 57 deletions(-)
-
-diff --git a/pjsip/include/pjsip-ua/sip_inv.h b/pjsip/include/pjsip-ua/sip_inv.h
-index 14f2d23fa..c33551786 100644
---- a/pjsip/include/pjsip-ua/sip_inv.h
-+++ b/pjsip/include/pjsip-ua/sip_inv.h
-@@ -451,11 +451,11 @@ struct pjsip_inv_session
-
-
- /**
-- * This structure represents SDP information in a pjsip_rx_data. Application
-- * retrieve this information by calling #pjsip_rdata_get_sdp_info(). This
-+ * This structure represents SDP information in a pjsip_(rx|tx)_data. Application
-+ * retrieve this information by calling #pjsip_get_sdp_info(). This
- * mechanism supports multipart message body.
- */
--typedef struct pjsip_rdata_sdp_info
-+typedef struct pjsip_sdp_info
- {
- /**
- * Pointer and length of the text body in the incoming message. If
-@@ -475,7 +475,15 @@ typedef struct pjsip_rdata_sdp_info
- */
- pjmedia_sdp_session *sdp;
-
--} pjsip_rdata_sdp_info;
-+} pjsip_sdp_info;
-+
-+/**
-+ * For backwards compatibility and completeness,
-+ * pjsip_rdata_sdp_info and pjsip_tdata_sdp_info
-+ * are typedef'd to pjsip_sdp_info.
-+ */
-+typedef pjsip_sdp_info pjsip_rdata_sdp_info;
-+typedef pjsip_sdp_info pjsip_tdata_sdp_info;
-
-
- /**
-@@ -1045,6 +1053,44 @@ PJ_DECL(pj_status_t) pjsip_create_sdp_body(pj_pool_t *pool,
- pjmedia_sdp_session *sdp,
- pjsip_msg_body **p_body);
-
-+/**
-+ * This is a utility function to create a multipart body with the
-+ * SIP body as the first part.
-+ *
-+ * @param pool Pool to allocate memory.
-+ * @param sdp SDP session to be put in the SIP message body.
-+ * @param p_body Pointer to receive SIP message body containing
-+ * the SDP session.
-+ *
-+ * @return PJ_SUCCESS on success.
-+ */
-+PJ_DECL(pj_status_t) pjsip_create_multipart_sdp_body( pj_pool_t *pool,
-+ pjmedia_sdp_session *sdp,
-+ pjsip_msg_body **p_body);
-+
-+/**
-+ * Retrieve SDP information from a message body. Application should
-+ * prefer to use this function rather than parsing the SDP manually since
-+ * this function supports multipart message body.
-+ *
-+ * This function will only parse the SDP once, the first time it is called
-+ * on the same message. Subsequent call on the same message will just pick
-+ * up the already parsed SDP from the message.
-+ *
-+ * @param pool Pool to allocate memory.
-+ * @param body The message body.
-+ * @param msg_media_type From the rdata or tdata Content-Type header, if available.
-+ * If NULL, the content_type from the body will be used.
-+ * @param search_media_type The media type to search for.
-+ * If NULL, "application/sdp" will be used.
-+ *
-+ * @return The SDP info.
-+ */
-+PJ_DECL(pjsip_sdp_info*) pjsip_get_sdp_info(pj_pool_t *pool,
-+ pjsip_msg_body *body,
-+ pjsip_media_type *msg_media_type,
-+ const pjsip_media_type *search_media_type);
-+
- /**
- * Retrieve SDP information from an incoming message. Application should
- * prefer to use this function rather than parsing the SDP manually since
-@@ -1061,6 +1107,60 @@ PJ_DECL(pj_status_t) pjsip_create_sdp_body(pj_pool_t *pool,
- PJ_DECL(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata);
-
-
-+/**
-+ * Retrieve SDP information from an incoming message. Application should
-+ * prefer to use this function rather than parsing the SDP manually since
-+ * this function supports multipart message body.
-+ *
-+ * This function will only parse the SDP once, the first time it is called
-+ * on the same message. Subsequent call on the same message will just pick
-+ * up the already parsed SDP from the message.
-+ *
-+ * @param rdata The incoming message.
-+ * @param search_media_type The SDP media type to search for.
-+ * If NULL, "application/sdp" will be used.
-+ *
-+ * @return The SDP info.
-+ */
-+PJ_DECL(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info2(
-+ pjsip_rx_data *rdata,
-+ const pjsip_media_type *search_media_type);
-+
-+/**
-+ * Retrieve SDP information from an outgoing message. Application should
-+ * prefer to use this function rather than parsing the SDP manually since
-+ * this function supports multipart message body.
-+ *
-+ * This function will only parse the SDP once, the first time it is called
-+ * on the same message. Subsequent call on the same message will just pick
-+ * up the already parsed SDP from the message.
-+ *
-+ * @param tdata The outgoing message.
-+ *
-+ * @return The SDP info.
-+ */
-+PJ_DECL(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info(pjsip_tx_data *tdata);
-+
-+/**
-+ * Retrieve SDP information from an outgoing message. Application should
-+ * prefer to use this function rather than parsing the SDP manually since
-+ * this function supports multipart message body.
-+ *
-+ * This function will only parse the SDP once, the first time it is called
-+ * on the same message. Subsequent call on the same message will just pick
-+ * up the already parsed SDP from the message.
-+ *
-+ * @param tdata The outgoing message.
-+ * @param search_media_type The SDP media type to search for.
-+ * If NULL, "application/sdp" will be used.
-+ *
-+ * @return The SDP info.
-+ */
-+PJ_DECL(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info2(
-+ pjsip_tx_data *tdata,
-+ const pjsip_media_type *search_media_type);
-+
-+
- PJ_END_DECL
-
- /**
-diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
-index ca225015b..b68ae0f16 100644
---- a/pjsip/src/pjsip-ua/sip_inv.c
-+++ b/pjsip/src/pjsip-ua/sip_inv.c
-@@ -118,6 +118,8 @@ static pj_status_t handle_timer_response(pjsip_inv_session *inv,
- static pj_bool_t inv_check_secure_dlg(pjsip_inv_session *inv,
- pjsip_event *e);
-
-+static int print_sdp(pjsip_msg_body *body, char *buf, pj_size_t len);
-+
- static void (*inv_state_handler[])( pjsip_inv_session *inv, pjsip_event *e) =
- {
- &inv_on_state_null,
-@@ -946,66 +948,170 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uac( pjsip_dialog *dlg,
- return PJ_SUCCESS;
- }
-
--PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata)
-+PJ_DEF(pjsip_sdp_info*) pjsip_get_sdp_info(pj_pool_t *pool,
-+ pjsip_msg_body *body,
-+ pjsip_media_type *msg_media_type,
-+ const pjsip_media_type *search_media_type)
- {
-- pjsip_rdata_sdp_info *sdp_info;
-- pjsip_msg_body *body = rdata->msg_info.msg->body;
-- pjsip_ctype_hdr *ctype_hdr = rdata->msg_info.ctype;
-- pjsip_media_type app_sdp;
-+ pjsip_sdp_info *sdp_info;
-+ pjsip_media_type search_type;
-+ pjsip_media_type multipart_mixed;
-+ pjsip_media_type multipart_alternative;
-+ pjsip_media_type *msg_type;
-+ pj_status_t status;
-
-- sdp_info = (pjsip_rdata_sdp_info*)
-- rdata->endpt_info.mod_data[mod_inv.mod.id];
-- if (sdp_info)
-- return sdp_info;
-+ sdp_info = PJ_POOL_ZALLOC_T(pool,
-+ pjsip_sdp_info);
-
-- sdp_info = PJ_POOL_ZALLOC_T(rdata->tp_info.pool,
-- pjsip_rdata_sdp_info);
- PJ_ASSERT_RETURN(mod_inv.mod.id >= 0, sdp_info);
-- rdata->endpt_info.mod_data[mod_inv.mod.id] = sdp_info;
-
-- pjsip_media_type_init2(&app_sdp, "application", "sdp");
-+ if (!body) {
-+ return sdp_info;
-+ }
-
-- if (body && ctype_hdr &&
-- pj_stricmp(&ctype_hdr->media.type, &app_sdp.type)==0 &&
-- pj_stricmp(&ctype_hdr->media.subtype, &app_sdp.subtype)==0)
-+ if (msg_media_type) {
-+ msg_type = msg_media_type;
-+ } else {
-+ if (body->content_type.type.slen == 0) {
-+ return sdp_info;
-+ }
-+ msg_type = &body->content_type;
-+ }
-+
-+ if (!search_media_type) {
-+ pjsip_media_type_init2(&search_type, "application", "sdp");
-+ } else {
-+ pj_memcpy(&search_type, search_media_type, sizeof(search_type));
-+ }
-+
-+ pjsip_media_type_init2(&multipart_mixed, "multipart", "mixed");
-+ pjsip_media_type_init2(&multipart_alternative, "multipart", "alternative");
-+
-+ if (pjsip_media_type_cmp(msg_type, &search_type, PJ_FALSE) == 0)
- {
-- sdp_info->body.ptr = (char*)body->data;
-- sdp_info->body.slen = body->len;
-- } else if (body && ctype_hdr &&
-- pj_stricmp2(&ctype_hdr->media.type, "multipart")==0 &&
-- (pj_stricmp2(&ctype_hdr->media.subtype, "mixed")==0 ||
-- pj_stricmp2(&ctype_hdr->media.subtype, "alternative")==0))
-+ /*
-+ * If the print_body function is print_sdp, we know that
-+ * body->data is a pjmedia_sdp_session object and came from
-+ * a tx_data. If not, it's the text representation of the
-+ * sdp from an rx_data.
-+ */
-+ if (body->print_body == print_sdp) {
-+ sdp_info->sdp = body->data;
-+ } else {
-+ sdp_info->body.ptr = (char*)body->data;
-+ sdp_info->body.slen = body->len;
-+ }
-+ } else if (pjsip_media_type_cmp(&multipart_mixed, msg_type, PJ_FALSE) == 0 ||
-+ pjsip_media_type_cmp(&multipart_alternative, msg_type, PJ_FALSE) == 0)
- {
-- pjsip_multipart_part *part;
-+ pjsip_multipart_part *part;
-+ part = pjsip_multipart_find_part(body, &search_type, NULL);
-+ if (part) {
-+ if (part->body->print_body == print_sdp) {
-+ sdp_info->sdp = part->body->data;
-+ } else {
-+ sdp_info->body.ptr = (char*)part->body->data;
-+ sdp_info->body.slen = part->body->len;
-+ }
-+ }
-+ }
-
-- part = pjsip_multipart_find_part(body, &app_sdp, NULL);
-- if (part) {
-- sdp_info->body.ptr = (char*)part->body->data;
-- sdp_info->body.slen = part->body->len;
-- }
-+ /*
-+ * If the body was already a pjmedia_sdp_session, we can just
-+ * return it. If not and there wasn't a text representation
-+ * of the sdp either, we can also just return.
-+ */
-+ if (sdp_info->sdp || !sdp_info->body.ptr) {
-+ return sdp_info;
- }
-
-- if (sdp_info->body.ptr) {
-- pj_status_t status;
-- status = pjmedia_sdp_parse(rdata->tp_info.pool,
-- sdp_info->body.ptr,
-- sdp_info->body.slen,
-- &sdp_info->sdp);
-- if (status == PJ_SUCCESS)
-- status = pjmedia_sdp_validate2(sdp_info->sdp, PJ_FALSE);
-+ /*
-+ * If the body was the text representation of teh SDP, we need
-+ * to parse it to create a pjmedia_sdp_session object.
-+ */
-+ status = pjmedia_sdp_parse(pool,
-+ sdp_info->body.ptr,
-+ sdp_info->body.slen,
-+ &sdp_info->sdp);
-+ if (status == PJ_SUCCESS)
-+ status = pjmedia_sdp_validate2(sdp_info->sdp, PJ_FALSE);
-
-- if (status != PJ_SUCCESS) {
-- sdp_info->sdp = NULL;
-- PJ_PERROR(1,(THIS_FILE, status,
-- "Error parsing/validating SDP body"));
-- }
-+ if (status != PJ_SUCCESS) {
-+ sdp_info->sdp = NULL;
-+ PJ_PERROR(1, (THIS_FILE, status,
-+ "Error parsing/validating SDP body"));
-+ }
-+
-+ sdp_info->sdp_err = status;
-+
-+ return sdp_info;
-+}
-
-- sdp_info->sdp_err = status;
-+PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info2(
-+ pjsip_rx_data *rdata,
-+ const pjsip_media_type *search_media_type)
-+{
-+ pjsip_media_type *msg_media_type = NULL;
-+ pjsip_rdata_sdp_info *sdp_info;
-+
-+ if (rdata->endpt_info.mod_data[mod_inv.mod.id]) {
-+ return (pjsip_rdata_sdp_info *)rdata->endpt_info.mod_data[mod_inv.mod.id];
-+ }
-+
-+ /*
-+ * rdata should have a Content-Type header at this point but we'll
-+ * make sure.
-+ */
-+ if (rdata->msg_info.ctype) {
-+ msg_media_type = &rdata->msg_info.ctype->media;
-+ }
-+ sdp_info = pjsip_get_sdp_info(rdata->tp_info.pool,
-+ rdata->msg_info.msg->body,
-+ msg_media_type,
-+ search_media_type);
-+ rdata->endpt_info.mod_data[mod_inv.mod.id] = sdp_info;
-+
-+ return sdp_info;
-+}
-+
-+PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata)
-+{
-+ return pjsip_rdata_get_sdp_info2(rdata, NULL);
-+}
-+
-+PJ_DEF(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info2(
-+ pjsip_tx_data *tdata,
-+ const pjsip_media_type *search_media_type)
-+{
-+ pjsip_ctype_hdr *ctype_hdr = NULL;
-+ pjsip_media_type *msg_media_type = NULL;
-+ pjsip_tdata_sdp_info *sdp_info;
-+
-+ if (tdata->mod_data[mod_inv.mod.id]) {
-+ return (pjsip_tdata_sdp_info *)tdata->mod_data[mod_inv.mod.id];
-+ }
-+ /*
-+ * tdata won't usually have a Content-Type header at this point
-+ * but we'll check just the same,
-+ */
-+ ctype_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTENT_TYPE, NULL);
-+ if (ctype_hdr) {
-+ msg_media_type = &ctype_hdr->media;
- }
-
-+ sdp_info = pjsip_get_sdp_info(tdata->pool,
-+ tdata->msg->body,
-+ msg_media_type,
-+ search_media_type);
-+ tdata->mod_data[mod_inv.mod.id] = sdp_info;
-+
- return sdp_info;
- }
-
-+PJ_DEF(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info(pjsip_tx_data *tdata)
-+{
-+ return pjsip_tdata_get_sdp_info2(tdata, NULL);
-+}
-
- /*
- * Verify incoming INVITE request.
-@@ -1730,13 +1836,55 @@ PJ_DEF(pj_status_t) pjsip_create_sdp_body( pj_pool_t *pool,
- return PJ_SUCCESS;
- }
-
-+static pjsip_multipart_part* create_sdp_part(pj_pool_t *pool, pjmedia_sdp_session *sdp)
-+{
-+ pjsip_multipart_part *sdp_part;
-+ pjsip_media_type media_type;
-+
-+ pjsip_media_type_init2(&media_type, "application", "sdp");
-+
-+ sdp_part = pjsip_multipart_create_part(pool);
-+ PJ_ASSERT_RETURN(sdp_part != NULL, NULL);
-+
-+ sdp_part->body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);
-+ PJ_ASSERT_RETURN(sdp_part->body != NULL, NULL);
-+
-+ pjsip_media_type_cp(pool, &sdp_part->body->content_type, &media_type);
-+
-+ sdp_part->body->data = sdp;
-+ sdp_part->body->clone_data = clone_sdp;
-+ sdp_part->body->print_body = print_sdp;
-+
-+ return sdp_part;
-+}
-+
-+PJ_DEF(pj_status_t) pjsip_create_multipart_sdp_body(pj_pool_t *pool,
-+ pjmedia_sdp_session *sdp,
-+ pjsip_msg_body **p_body)
-+{
-+ pjsip_media_type media_type;
-+ pjsip_msg_body *multipart;
-+ pjsip_multipart_part *sdp_part;
-+
-+ pjsip_media_type_init2(&media_type, "multipart", "mixed");
-+ multipart = pjsip_multipart_create(pool, &media_type, NULL);
-+ PJ_ASSERT_RETURN(multipart != NULL, PJ_ENOMEM);
-+
-+ sdp_part = create_sdp_part(pool, sdp);
-+ PJ_ASSERT_RETURN(sdp_part != NULL, PJ_ENOMEM);
-+ pjsip_multipart_add_part(pool, multipart, sdp_part);
-+ *p_body = multipart;
-+
-+ return PJ_SUCCESS;
-+}
-+
- static pjsip_msg_body *create_sdp_body(pj_pool_t *pool,
- const pjmedia_sdp_session *c_sdp)
- {
- pjsip_msg_body *body;
- pj_status_t status;
-
-- status = pjsip_create_sdp_body(pool,
-+ status = pjsip_create_sdp_body(pool,
- pjmedia_sdp_session_clone(pool, c_sdp),
- &body);
-
-@@ -2059,6 +2207,7 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
- )
- )
- {
-+ pjsip_sdp_info *tdata_sdp_info;
- const pjmedia_sdp_session *reoffer_sdp = NULL;
-
- PJ_LOG(4,(inv->obj_name, "Received %s response "
-@@ -2067,14 +2216,15 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
- (st_code/10==18? "early" : "final" )));
-
- /* Retrieve original SDP offer from INVITE request */
-- reoffer_sdp = (const pjmedia_sdp_session*)
-- tsx->last_tx->msg->body->data;
-+ tdata_sdp_info = pjsip_tdata_get_sdp_info(tsx->last_tx);
-+ reoffer_sdp = tdata_sdp_info->sdp;
-
- /* Feed the original offer to negotiator */
- status = pjmedia_sdp_neg_modify_local_offer2(inv->pool_prov,
- inv->neg,
- inv->sdp_neg_flags,
- reoffer_sdp);
-+
- if (status != PJ_SUCCESS) {
- PJ_LOG(1,(inv->obj_name, "Error updating local offer for "
- "forked 2xx/18x response (err=%d)", status));
-diff --git a/pjsip/src/test/inv_offer_answer_test.c b/pjsip/src/test/inv_offer_answer_test.c
-index ad5fcd409..9cdd2654b 100644
---- a/pjsip/src/test/inv_offer_answer_test.c
-+++ b/pjsip/src/test/inv_offer_answer_test.c
-@@ -137,6 +137,7 @@ typedef struct inv_test_param_t
- pj_bool_t need_established;
- unsigned count;
- oa_t oa[4];
-+ pj_bool_t multipart_body;
- } inv_test_param_t;
-
- typedef struct inv_test_t
-@@ -257,6 +258,17 @@ static void on_media_update(pjsip_inv_session *inv_ses,
- }
- }
-
-+ /* Special handling for standard offer/answer */
-+ if (inv_test.param.count == 1 &&
-+ inv_test.param.oa[0] == OFFERER_UAC &&
-+ inv_test.param.need_established)
-+ {
-+ jobs[job_cnt].type = ESTABLISH_CALL;
-+ jobs[job_cnt].who = PJSIP_ROLE_UAS;
-+ job_cnt++;
-+ TRACE_((THIS_FILE, " C+++"));
-+ }
-+
- pj_assert(job_cnt <= PJ_ARRAY_SIZE(jobs));
- }
- }
-@@ -333,6 +345,15 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata)
- NULL, &tdata);
- pj_assert(status == PJ_SUCCESS);
-
-+ /* Use multipart body, if configured */
-+ if (sdp && inv_test.param.multipart_body) {
-+ status = pjsip_create_multipart_sdp_body(
-+ tdata->pool,
-+ pjmedia_sdp_session_clone(tdata->pool, sdp),
-+ &tdata->msg->body);
-+ }
-+ pj_assert(status == PJ_SUCCESS);
-+
- status = pjsip_inv_send_msg(inv_test.uas, tdata);
- pj_assert(status == PJ_SUCCESS);
-
-@@ -426,6 +447,7 @@ static int perform_test(inv_test_param_t *param)
- sdp = NULL;
-
- status = pjsip_inv_create_uac(dlg, sdp, inv_test.param.inv_option, &inv_test.uac);
-+ //inv_test.uac->create_multipart = param->multipart_body;
- PJ_ASSERT_RETURN(status==PJ_SUCCESS, -20);
-
- TRACE_((THIS_FILE, " Sending INVITE %s offer", (sdp ? "with" : "without")));
-@@ -436,8 +458,17 @@ static int perform_test(inv_test_param_t *param)
- status = pjsip_inv_invite(inv_test.uac, &tdata);
- PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30);
-
-+ /* Use multipart body, if configured */
-+ if (sdp && param->multipart_body) {
-+ status = pjsip_create_multipart_sdp_body(
-+ tdata->pool,
-+ pjmedia_sdp_session_clone(tdata->pool, sdp),
-+ &tdata->msg->body);
-+ }
-+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, -40);
-+
- status = pjsip_inv_send_msg(inv_test.uac, tdata);
-- PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30);
-+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, -50);
-
- /*
- * Wait until test completes
-@@ -525,13 +556,14 @@ static inv_test_param_t test_params[] =
- 200/INVITE (answer) <--
- ACK -->
- */
--#if 0
-+#if 1
- {
- "Standard INVITE with offer",
- 0,
- PJ_TRUE,
- 1,
-- { OFFERER_UAC }
-+ { OFFERER_UAC },
-+ PJ_FALSE
- },
-
- {
-@@ -539,7 +571,25 @@ static inv_test_param_t test_params[] =
- PJSIP_INV_REQUIRE_100REL,
- PJ_TRUE,
- 1,
-- { OFFERER_UAC }
-+ { OFFERER_UAC },
-+ PJ_FALSE
-+ },
-+ {
-+ "Standard INVITE with offer, with Multipart",
-+ 0,
-+ PJ_TRUE,
-+ 1,
-+ { OFFERER_UAC },
-+ PJ_TRUE
-+ },
-+
-+ {
-+ "Standard INVITE with offer, with 100rel, with Multipart",
-+ PJSIP_INV_REQUIRE_100REL,
-+ PJ_TRUE,
-+ 1,
-+ { OFFERER_UAC },
-+ PJ_TRUE
- },
- #endif
-
-@@ -555,7 +605,8 @@ static inv_test_param_t test_params[] =
- 0,
- PJ_TRUE,
- 1,
-- { OFFERER_UAS }
-+ { OFFERER_UAS },
-+ PJ_FALSE
- },
-
- {
-@@ -563,7 +614,25 @@ static inv_test_param_t test_params[] =
- PJSIP_INV_REQUIRE_100REL,
- PJ_TRUE,
- 1,
-- { OFFERER_UAS }
-+ { OFFERER_UAS },
-+ PJ_FALSE
-+ },
-+ {
-+ "INVITE with no offer, with Multipart",
-+ 0,
-+ PJ_TRUE,
-+ 1,
-+ { OFFERER_UAS },
-+ PJ_TRUE
-+ },
-+
-+ {
-+ "INVITE with no offer, with 100rel, with Multipart",
-+ PJSIP_INV_REQUIRE_100REL,
-+ PJ_TRUE,
-+ 1,
-+ { OFFERER_UAS },
-+ PJ_TRUE
- },
- #endif
-
-@@ -584,14 +653,24 @@ static inv_test_param_t test_params[] =
- 0,
- PJ_TRUE,
- 2,
-- { OFFERER_UAC, OFFERER_UAC }
-+ { OFFERER_UAC, OFFERER_UAC },
-+ PJ_FALSE
-+ },
-+ {
-+ "INVITE and UPDATE by UAC, with Multipart",
-+ 0,
-+ PJ_TRUE,
-+ 2,
-+ { OFFERER_UAC, OFFERER_UAC },
-+ PJ_TRUE
- },
- {
- "INVITE and UPDATE by UAC, with 100rel",
- PJSIP_INV_REQUIRE_100REL,
- PJ_TRUE,
- 2,
-- { OFFERER_UAC, OFFERER_UAC }
-+ { OFFERER_UAC, OFFERER_UAC },
-+ PJ_FALSE
- },
- #endif
-
-@@ -617,6 +696,14 @@ static inv_test_param_t test_params[] =
- 4,
- { OFFERER_UAC, OFFERER_UAS, OFFERER_UAC, OFFERER_UAS }
- },
-+ {
-+ "INVITE and many UPDATE by UAC and UAS, with Multipart",
-+ 0,
-+ PJ_TRUE,
-+ 4,
-+ { OFFERER_UAC, OFFERER_UAS, OFFERER_UAC, OFFERER_UAS },
-+ PJ_TRUE
-+ },
-
- };
-
---
-2.33.1
-
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
deleted file mode 100644
index 22df638..0000000
--- a/third-party/pjproject/patches/0140-Fix-incorrect-unescaping-of-tokens-during-parsing-29.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From 3faf1d2b4da553bbaee04f9a13a5d084b381e5fb Mon Sep 17 00:00:00 2001
-From: sauwming <ming at teluu.com>
-Date: Tue, 4 Jan 2022 15:28:49 +0800
-Subject: [PATCH] Fix incorrect unescaping of tokens during parsing (#2933)
-
----
- pjsip/src/pjsip/sip_parser.c | 29 +++++++++++++++++++++++++----
- pjsip/src/test/msg_test.c | 6 +++---
- 2 files changed, 28 insertions(+), 7 deletions(-)
-
-diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c
-index c2add3299..b9a7c6a5c 100644
---- a/pjsip/src/pjsip/sip_parser.c
-+++ b/pjsip/src/pjsip/sip_parser.c
-@@ -378,17 +378,23 @@ static pj_status_t init_parser()
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
- pj_cis_add_str( &pconst.pjsip_TOKEN_SPEC, TOKEN);
-
-+ /* Token is allowed to have '%' so we do not need this. */
-+ /*
- status = pj_cis_dup(&pconst.pjsip_TOKEN_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
- pj_cis_del_str(&pconst.pjsip_TOKEN_SPEC_ESC, "%");
-+ */
-
- status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC, &pconst.pjsip_TOKEN_SPEC);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
- pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, "[:]");
-
-+ /* Token is allowed to have '%' */
-+ /*
- status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC_ESC);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
- pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC_ESC, "[:]");
-+ */
-
- status = pj_cis_dup(&pconst.pjsip_HOST_SPEC, &pconst.pjsip_ALNUM_SPEC);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
-@@ -1210,7 +1216,11 @@ static void parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,
- unsigned option)
- {
- /* pname */
-- parser_get_and_unescape(scanner, pool, spec, esc_spec, pname);
-+ if (!esc_spec) {
-+ pj_scan_get(scanner, spec, pname);
-+ } else {
-+ parser_get_and_unescape(scanner, pool, spec, esc_spec, pname);
-+ }
-
- /* init pvalue */
- pvalue->ptr = NULL;
-@@ -1240,7 +1250,12 @@ static void parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,
- // pj_scan_get_until_ch(scanner, ']', pvalue);
- // pj_scan_get_char(scanner);
- } else if(pj_cis_match(spec, *scanner->curptr)) {
-- parser_get_and_unescape(scanner, pool, spec, esc_spec, pvalue);
-+ if (!esc_spec) {
-+ pj_scan_get(scanner, spec, pvalue);
-+ } else {
-+ parser_get_and_unescape(scanner, pool, spec, esc_spec,
-+ pvalue);
-+ }
- }
- }
- }
-@@ -1252,7 +1267,10 @@ PJ_DEF(void) pjsip_parse_param_imp(pj_scanner *scanner, pj_pool_t *pool,
- unsigned option)
- {
- parse_param_imp(scanner, pool, pname, pvalue, &pconst.pjsip_TOKEN_SPEC,
-- &pconst.pjsip_TOKEN_SPEC_ESC, option);
-+ // Token does not need to be unescaped.
-+ // Refer to PR #2933.
-+ // &pconst.pjsip_TOKEN_SPEC_ESC,
-+ NULL, option);
- }
-
-
-@@ -2168,7 +2186,10 @@ static void int_parse_via_param( pjsip_via_hdr *hdr, pj_scanner *scanner,
- pj_scan_get_char(scanner);
- parse_param_imp(scanner, pool, &pname, &pvalue,
- &pconst.pjsip_VIA_PARAM_SPEC,
-- &pconst.pjsip_VIA_PARAM_SPEC_ESC,
-+ // Token does not need to be unescaped.
-+ // Refer to PR #2933.
-+ // &pconst.pjsip_VIA_PARAM_SPEC_ESC,
-+ NULL,
- 0);
-
- if (!parser_stricmp(pname, pconst.pjsip_BRANCH_STR) && pvalue.slen) {
-diff --git a/pjsip/src/test/msg_test.c b/pjsip/src/test/msg_test.c
-index c511e1cf6..24e3d405d 100644
---- a/pjsip/src/test/msg_test.c
-+++ b/pjsip/src/test/msg_test.c
-@@ -953,7 +953,7 @@ static int hdr_test_subject_utf(pjsip_hdr *h);
-
-
- #define GENERIC_PARAM "p0=a;p1=\"ab:;cd\";p2=ab%3acd;p3"
--#define GENERIC_PARAM_PARSED "p0=a;p1=\"ab:;cd\";p2=ab:cd;p3"
-+#define GENERIC_PARAM_PARSED "p0=a;p1=\"ab:;cd\";p2=ab%3acd;p3"
- #define PARAM_CHAR "][/:&+$"
- #define SIMPLE_ADDR_SPEC "sip:host"
- #define ADDR_SPEC SIMPLE_ADDR_SPEC ";"PARAM_CHAR"="PARAM_CHAR ";p1=\";\""
-@@ -1401,7 +1401,7 @@ static int generic_param_test(pjsip_param *param_head)
- param = param->next;
- if (pj_strcmp2(¶m->name, "p2"))
- return -956;
-- if (pj_strcmp2(¶m->value, "ab:cd"))
-+ if (pj_strcmp2(¶m->value, "ab%3acd"))
- return -957;
-
- param = param->next;
-@@ -1621,7 +1621,7 @@ static int hdr_test_content_type(pjsip_hdr *h)
- prm = prm->next;
- if (prm == &hdr->media.param) return -1960;
- if (pj_strcmp2(&prm->name, "p2")) return -1961;
-- if (pj_strcmp2(&prm->value, "ab:cd")) return -1962;
-+ if (pj_strcmp2(&prm->value, "ab%3acd")) return -1962;
-
- prm = prm->next;
- if (prm == &hdr->media.param) return -1970;
---
-2.32.0
-
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
deleted file mode 100644
index 6ddb346..0000000
--- a/third-party/pjproject/patches/0150-Create-generic-pjsip_hdr_find-functions.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-From 7e3dfd8a15fd0f98dbf0e04d2d7a5bded90ee401 Mon Sep 17 00:00:00 2001
-From: George Joseph <gjoseph at sangoma.com>
-Date: Tue, 11 Jan 2022 09:27:23 -0700
-Subject: [PATCH] Create generic pjsip_hdr_find functions
-
-pjsip_msg_find_hdr(), pjsip_msg_find_hdr_by_name(), and
-pjsip_msg_find_hdr_by_names() require a pjsip_msg to be passed in
-so if you need to search a header list that's not in a pjsip_msg,
-you have to do it yourself. This commit adds generic versions of
-those 3 functions that take in the actual header list head instead
-of a pjsip_msg so if you need to search a list of headers in
-something like a pjsip_multipart_part, you can do so easily.
----
- pjsip/include/pjsip/sip_msg.h | 53 +++++++++++++++++++++++++++++++++++
- pjsip/src/pjsip/sip_msg.c | 51 +++++++++++++++++++++++----------
- 2 files changed, 89 insertions(+), 15 deletions(-)
-
-diff --git a/pjsip/include/pjsip/sip_msg.h b/pjsip/include/pjsip/sip_msg.h
-index 4c9100d39..e3502e94e 100644
---- a/pjsip/include/pjsip/sip_msg.h
-+++ b/pjsip/include/pjsip/sip_msg.h
-@@ -362,6 +362,59 @@ PJ_DECL(void*) pjsip_hdr_shallow_clone( pj_pool_t *pool, const void *hdr );
- */
- PJ_DECL(int) pjsip_hdr_print_on( void *hdr, char *buf, pj_size_t len);
-
-+/**
-+ * Find a header in a header list by the header type.
-+ *
-+ * @param hdr_list The "head" of the header list.
-+ * @param type The header type to find.
-+ * @param start The first header field where the search should begin.
-+ * If NULL is specified, then the search will begin from the
-+ * first header, otherwise the search will begin at the
-+ * specified header.
-+ *
-+ * @return The header field, or NULL if no header with the specified
-+ * type is found.
-+ */
-+PJ_DECL(void*) pjsip_hdr_find( const void *hdr_list,
-+ pjsip_hdr_e type,
-+ const void *start);
-+
-+/**
-+ * Find a header in a header list by its name.
-+ *
-+ * @param hdr_list The "head" of the header list.
-+ * @param name The header name to find.
-+ * @param start The first header field where the search should begin.
-+ * If NULL is specified, then the search will begin from the
-+ * first header, otherwise the search will begin at the
-+ * specified header.
-+ *
-+ * @return The header field, or NULL if no header with the specified
-+ * type is found.
-+ */
-+PJ_DECL(void*) pjsip_hdr_find_by_name( const void *hdr_list,
-+ const pj_str_t *name,
-+ const void *start);
-+
-+/**
-+ * Find a header in a header list by its name and short name version.
-+ *
-+ * @param hdr_list The "head" of the header list.
-+ * @param name The header name to find.
-+ * @param sname The short name version of the header name.
-+ * @param start The first header field where the search should begin.
-+ * If NULL is specified, then the search will begin from the
-+ * first header, otherwise the search will begin at the
-+ * specified header.
-+ *
-+ * @return The header field, or NULL if no header with the specified
-+ * type is found.
-+ */
-+PJ_DECL(void*) pjsip_hdr_find_by_names( const void *hdr_list,
-+ const pj_str_t *name,
-+ const pj_str_t *sname,
-+ const void *start);
-+
- /**
- * @}
- */
-diff --git a/pjsip/src/pjsip/sip_msg.c b/pjsip/src/pjsip/sip_msg.c
-index 6ba3054da..2a6a96af0 100644
---- a/pjsip/src/pjsip/sip_msg.c
-+++ b/pjsip/src/pjsip/sip_msg.c
-@@ -356,13 +356,13 @@ PJ_DEF(pjsip_msg*) pjsip_msg_clone( pj_pool_t *pool, const pjsip_msg *src)
- return dst;
- }
-
--PJ_DEF(void*) pjsip_msg_find_hdr( const pjsip_msg *msg,
-- pjsip_hdr_e hdr_type, const void *start)
-+PJ_DEF(void*) pjsip_hdr_find( const void *hdr_list,
-+ pjsip_hdr_e hdr_type, const void *start)
- {
-- const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=&msg->hdr;
-+ const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=hdr_list;
-
- if (hdr == NULL) {
-- hdr = msg->hdr.next;
-+ hdr = end->next;
- }
- for (; hdr!=end; hdr = hdr->next) {
- if (hdr->type == hdr_type)
-@@ -371,14 +371,14 @@ PJ_DEF(void*) pjsip_msg_find_hdr( const pjsip_msg *msg,
- return NULL;
- }
-
--PJ_DEF(void*) pjsip_msg_find_hdr_by_name( const pjsip_msg *msg,
-- const pj_str_t *name,
-- const void *start)
-+PJ_DEF(void*) pjsip_hdr_find_by_name( const void *hdr_list,
-+ const pj_str_t *name,
-+ const void *start)
- {
-- const pjsip_hdr *hdr=(const pjsip_hdr*)start, *end=&msg->hdr;
-+ const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=hdr_list;
-
- if (hdr == NULL) {
-- hdr = msg->hdr.next;
-+ hdr = end->next;
- }
- for (; hdr!=end; hdr = hdr->next) {
- if (pj_stricmp(&hdr->name, name) == 0)
-@@ -387,15 +387,15 @@ PJ_DEF(void*) pjsip_msg_find_hdr_by_name( const pjsip_msg *msg,
- return NULL;
- }
-
--PJ_DEF(void*) pjsip_msg_find_hdr_by_names( const pjsip_msg *msg,
-- const pj_str_t *name,
-- const pj_str_t *sname,
-- const void *start)
-+PJ_DEF(void*) pjsip_hdr_find_by_names( const void *hdr_list,
-+ const pj_str_t *name,
-+ const pj_str_t *sname,
-+ const void *start)
- {
-- const pjsip_hdr *hdr=(const pjsip_hdr*)start, *end=&msg->hdr;
-+ const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=hdr_list;
-
- if (hdr == NULL) {
-- hdr = msg->hdr.next;
-+ hdr = end->next;
- }
- for (; hdr!=end; hdr = hdr->next) {
- if (pj_stricmp(&hdr->name, name) == 0)
-@@ -406,6 +406,27 @@ PJ_DEF(void*) pjsip_msg_find_hdr_by_names( const pjsip_msg *msg,
- return NULL;
- }
-
-+PJ_DEF(void*) pjsip_msg_find_hdr( const pjsip_msg *msg,
-+ pjsip_hdr_e hdr_type, const void *start)
-+{
-+ return pjsip_hdr_find(&msg->hdr, hdr_type, start);
-+}
-+
-+PJ_DEF(void*) pjsip_msg_find_hdr_by_name( const pjsip_msg *msg,
-+ const pj_str_t *name,
-+ const void *start)
-+{
-+ return pjsip_hdr_find_by_name(&msg->hdr, name, start);
-+}
-+
-+PJ_DEF(void*) pjsip_msg_find_hdr_by_names( const pjsip_msg *msg,
-+ const pj_str_t *name,
-+ const pj_str_t *sname,
-+ const void *start)
-+{
-+ return pjsip_hdr_find_by_names(&msg->hdr, name, sname, start);
-+}
-+
- PJ_DEF(void*) pjsip_msg_find_remove_hdr( pjsip_msg *msg,
- pjsip_hdr_e hdr_type, void *start)
- {
---
-2.34.1
-
diff --git a/third-party/pjproject/patches/0160-Additional-multipart-improvements.patch b/third-party/pjproject/patches/0160-Additional-multipart-improvements.patch
deleted file mode 100644
index 373f9b8..0000000
--- a/third-party/pjproject/patches/0160-Additional-multipart-improvements.patch
+++ /dev/null
@@ -1,644 +0,0 @@
-From b7ecff22e77887626fd8e8608c4dd73bc7b7366f Mon Sep 17 00:00:00 2001
-From: George Joseph <gjoseph at sangoma.com>
-Date: Tue, 18 Jan 2022 06:14:31 -0700
-Subject: [PATCH] Additional multipart improvements
-
-Added the following APIs:
-pjsip_multipart_find_part_by_header()
-pjsip_multipart_find_part_by_header_str()
-pjsip_multipart_find_part_by_cid_str()
-pjsip_multipart_find_part_by_cid_uri()
----
- pjsip/include/pjsip/sip_multipart.h | 83 ++++++++++
- pjsip/src/pjsip/sip_multipart.c | 223 +++++++++++++++++++++++++++
- pjsip/src/test/multipart_test.c | 225 +++++++++++++++++++++++++++-
- 3 files changed, 530 insertions(+), 1 deletion(-)
-
-diff --git a/pjsip/include/pjsip/sip_multipart.h b/pjsip/include/pjsip/sip_multipart.h
-index 1c05767c5..c6b82b0b4 100644
---- a/pjsip/include/pjsip/sip_multipart.h
-+++ b/pjsip/include/pjsip/sip_multipart.h
-@@ -153,6 +153,89 @@ pjsip_multipart_find_part( const pjsip_msg_body *mp,
- const pjsip_media_type *content_type,
- const pjsip_multipart_part *start);
-
-+/**
-+ * Find a body inside multipart bodies which has a header matching the
-+ * supplied one. Most useful for finding a part with a specific Content-ID.
-+ *
-+ * @param pool Memory pool to use for temp space.
-+ * @param mp The multipart body.
-+ * @param search_hdr Header to search for.
-+ * @param start If specified, the search will begin at
-+ * start->next part. Otherwise it will begin at
-+ * the first part in the multipart bodies.
-+ *
-+ * @return The first part which has a header matching the
-+ * specified one, or NULL if not found.
-+ */
-+PJ_DECL(pjsip_multipart_part*)
-+pjsip_multipart_find_part_by_header(pj_pool_t *pool,
-+ const pjsip_msg_body *mp,
-+ void *search_hdr,
-+ const pjsip_multipart_part *start);
-+
-+/**
-+ * Find a body inside multipart bodies which has a header matching the
-+ * supplied name and value. Most useful for finding a part with a specific
-+ * Content-ID.
-+ *
-+ * @param pool Memory pool to use for temp space.
-+ * @param mp The multipart body.
-+ * @param hdr_name Header name to search for.
-+ * @param hdr_value Header value search for.
-+ * @param start If specified, the search will begin at
-+ * start->next part. Otherwise it will begin at
-+ * the first part in the multipart bodies.
-+ *
-+ * @return The first part which has a header matching the
-+ * specified one, or NULL if not found.
-+ */
-+PJ_DECL(pjsip_multipart_part*)
-+pjsip_multipart_find_part_by_header_str(pj_pool_t *pool,
-+ const pjsip_msg_body *mp,
-+ const pj_str_t *hdr_name,
-+ const pj_str_t *hdr_value,
-+ const pjsip_multipart_part *start);
-+
-+
-+
-+/**
-+ * Find a body inside multipart bodies which has a Content-ID value matching the
-+ * supplied "cid" URI in pj_str form. The "cid:" scheme will be assumed if the
-+ * URL doesn't start with it. Enclosing angle brackets will also be handled
-+ * correctly if they exist.
-+ *
-+ * @see RFC2392 Content-ID and Message-ID Uniform Resource Locators
-+ *
-+ * @param pool Memory pool to use for temp space.
-+ * @param mp The multipart body.
-+ * @param cid The "cid" URI to search for in pj_str form.
-+ *
-+ * @return The first part which has a Content-ID header matching the
-+ * specified "cid" URI. or NULL if not found.
-+ */
-+PJ_DECL(pjsip_multipart_part*)
-+pjsip_multipart_find_part_by_cid_str(pj_pool_t *pool,
-+ const pjsip_msg_body *mp,
-+ pj_str_t *cid);
-+
-+/**
-+ * Find a body inside multipart bodies which has a Content-ID value matching the
-+ * supplied "cid" URI.
-+ *
-+ * @see RFC2392 Content-ID and Message-ID Uniform Resource Locators
-+ *
-+ * @param pool Memory pool to use for temp space.
-+ * @param mp The multipart body.
-+ * @param cid The "cid" URI to search for.
-+ *
-+ * @return The first part which had a Content-ID header matching the
-+ * specified "cid" URI. or NULL if not found.
-+ */
-+PJ_DECL(pjsip_multipart_part*)
-+pjsip_multipart_find_part_by_cid_uri(pj_pool_t *pool,
-+ const pjsip_msg_body *mp,
-+ pjsip_other_uri *cid_uri);
-+
- /**
- * Parse multipart message.
- *
-diff --git a/pjsip/src/pjsip/sip_multipart.c b/pjsip/src/pjsip/sip_multipart.c
-index e7d722d2e..9d8be55b0 100644
---- a/pjsip/src/pjsip/sip_multipart.c
-+++ b/pjsip/src/pjsip/sip_multipart.c
-@@ -19,6 +19,7 @@
- #include <pjsip/sip_multipart.h>
- #include <pjsip/sip_parser.h>
- #include <pjlib-util/scanner.h>
-+#include <pjlib-util/string.h>
- #include <pj/assert.h>
- #include <pj/ctype.h>
- #include <pj/errno.h>
-@@ -416,6 +417,220 @@ pjsip_multipart_find_part( const pjsip_msg_body *mp,
- return NULL;
- }
-
-+/*
-+ * Find a body inside multipart bodies which has the header and value.
-+ */
-+PJ_DEF(pjsip_multipart_part*)
-+pjsip_multipart_find_part_by_header_str(pj_pool_t *pool,
-+ const pjsip_msg_body *mp,
-+ const pj_str_t *hdr_name,
-+ const pj_str_t *hdr_value,
-+ const pjsip_multipart_part *start)
-+{
-+ struct multipart_data *m_data;
-+ pjsip_multipart_part *part;
-+ pjsip_hdr *found_hdr;
-+ pj_str_t found_hdr_str;
-+ pj_str_t found_hdr_value;
-+ pj_size_t expected_hdr_slen;
-+ pj_size_t buf_size;
-+ int hdr_name_len;
-+#define REASONABLE_PADDING 32
-+#define SEPARATOR_LEN 2
-+ /* Must specify mandatory params */
-+ PJ_ASSERT_RETURN(mp && hdr_name && hdr_value, NULL);
-+
-+ /* mp must really point to an actual multipart msg body */
-+ PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);
-+
-+ /*
-+ * We'll need to "print" each header we find to test it but
-+ * allocating a buffer of PJSIP_MAX_URL_SIZE is overkill.
-+ * Instead, we'll allocate one large enough to hold the search
-+ * header name, the ": " separator, the search hdr value, and
-+ * the NULL terminator. If we can't print the found header
-+ * into that buffer then it can't be a match.
-+ *
-+ * Some header print functions such as generic_int require enough
-+ * space to print the maximum possible header length so we'll
-+ * add a reasonable amount to the print buffer size.
-+ */
-+ expected_hdr_slen = hdr_name->slen + SEPARATOR_LEN + hdr_value->slen;
-+ buf_size = expected_hdr_slen + REASONABLE_PADDING;
-+ found_hdr_str.ptr = pj_pool_alloc(pool, buf_size);
-+ found_hdr_str.slen = 0;
-+ hdr_name_len = hdr_name->slen + SEPARATOR_LEN;
-+
-+ m_data = (struct multipart_data*)mp->data;
-+
-+ if (start)
-+ part = start->next;
-+ else
-+ part = m_data->part_head.next;
-+
-+ while (part != &m_data->part_head) {
-+ found_hdr = NULL;
-+ while ((found_hdr = pjsip_hdr_find_by_name(&part->hdr, hdr_name,
-+ (found_hdr ? found_hdr->next : NULL))) != NULL) {
-+
-+ found_hdr_str.slen = pjsip_hdr_print_on((void*) found_hdr, found_hdr_str.ptr, buf_size);
-+ /*
-+ * If the buffer was too small (slen = -1) or the result wasn't
-+ * the same length as the search header, it can't be a match.
-+ */
-+ if (found_hdr_str.slen != expected_hdr_slen) {
-+ continue;
-+ }
-+ /*
-+ * Set the value overlay to start at the found header value...
-+ */
-+ found_hdr_value.ptr = found_hdr_str.ptr + hdr_name_len;
-+ found_hdr_value.slen = found_hdr_str.slen - hdr_name_len;
-+ /* ...and compare it to the supplied header value. */
-+ if (pj_strcmp(hdr_value, &found_hdr_value) == 0) {
-+ return part;
-+ }
-+ }
-+ part = part->next;
-+ }
-+ return NULL;
-+#undef SEPARATOR_LEN
-+#undef REASONABLE_PADDING
-+}
-+
-+PJ_DEF(pjsip_multipart_part*)
-+pjsip_multipart_find_part_by_header(pj_pool_t *pool,
-+ const pjsip_msg_body *mp,
-+ void *search_for,
-+ const pjsip_multipart_part *start)
-+{
-+ struct multipart_data *m_data;
-+ pjsip_hdr *search_hdr = search_for;
-+ pj_str_t search_buf;
-+
-+ /* Must specify mandatory params */
-+ PJ_ASSERT_RETURN(mp && search_hdr, NULL);
-+
-+ /* mp must really point to an actual multipart msg body */
-+ PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);
-+
-+ /*
-+ * Unfortunately, there isn't enough information to determine
-+ * the maximum printed size of search_hdr at this point so we
-+ * have to allocate a reasonable max.
-+ */
-+ search_buf.ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
-+ search_buf.slen = pjsip_hdr_print_on(search_hdr, search_buf.ptr, PJSIP_MAX_URL_SIZE - 1);
-+ if (search_buf.slen <= 0) {
-+ return NULL;
-+ }
-+ /*
-+ * Set the header value to start after the header name plus the ":", then
-+ * strip leading and trailing whitespace.
-+ */
-+ search_buf.ptr += (search_hdr->name.slen + 1);
-+ search_buf.slen -= (search_hdr->name.slen + 1);
-+ pj_strtrim(&search_buf);
-+
-+ return pjsip_multipart_find_part_by_header_str(pool, mp, &search_hdr->name, &search_buf, start);
-+}
-+
-+/*
-+ * Convert a Content-ID URI to it's corresponding header value.
-+ * RFC2392 says...
-+ * A "cid" URL is converted to the corresponding Content-ID message
-+ * header by removing the "cid:" prefix, converting the % encoded
-+ * character(s) to their equivalent US-ASCII characters, and enclosing
-+ * the remaining parts with an angle bracket pair, "<" and ">".
-+ *
-+ * This implementation will accept URIs with or without the "cid:"
-+ * scheme and optional angle brackets.
-+ */
-+static pj_str_t cid_uri_to_hdr_value(pj_pool_t *pool, pj_str_t *cid_uri)
-+{
-+ pj_size_t cid_len = pj_strlen(cid_uri);
-+ pj_size_t alloc_len = cid_len + 2 /* for the leading and trailing angle brackets */;
-+ pj_str_t uri_overlay;
-+ pj_str_t cid_hdr;
-+ pj_str_t hdr_overlay;
-+
-+ pj_strassign(&uri_overlay, cid_uri);
-+ /* If the URI is already enclosed in angle brackets, remove them. */
-+ if (uri_overlay.ptr[0] == '<') {
-+ uri_overlay.ptr++;
-+ uri_overlay.slen -= 2;
-+ }
-+ /* If the URI starts with the "cid:" scheme, skip over it. */
-+ if (pj_strncmp2(&uri_overlay, "cid:", 4) == 0) {
-+ uri_overlay.ptr += 4;
-+ uri_overlay.slen -= 4;
-+ }
-+ /* Start building */
-+ cid_hdr.ptr = pj_pool_alloc(pool, alloc_len);
-+ cid_hdr.ptr[0] = '<';
-+ cid_hdr.slen = 1;
-+ hdr_overlay.ptr = cid_hdr.ptr + 1;
-+ hdr_overlay.slen = 0;
-+ pj_strcpy_unescape(&hdr_overlay, &uri_overlay);
-+ cid_hdr.slen += hdr_overlay.slen;
-+ cid_hdr.ptr[cid_hdr.slen] = '>';
-+ cid_hdr.slen++;
-+
-+ return cid_hdr;
-+}
-+
-+PJ_DEF(pjsip_multipart_part*)
-+pjsip_multipart_find_part_by_cid_str(pj_pool_t *pool,
-+ const pjsip_msg_body *mp,
-+ pj_str_t *cid)
-+{
-+ struct multipart_data *m_data;
-+ pjsip_multipart_part *part;
-+ pjsip_generic_string_hdr *found_hdr;
-+ pj_str_t found_hdr_value;
-+ static pj_str_t hdr_name = { "Content-ID", 10};
-+ pj_str_t hdr_value;
-+
-+ PJ_ASSERT_RETURN(pool && mp && cid && (pj_strlen(cid) > 0), NULL);
-+
-+ hdr_value = cid_uri_to_hdr_value(pool, cid);
-+ if (pj_strlen(&hdr_value) == 0) {
-+ return NULL;
-+ }
-+
-+ m_data = (struct multipart_data*)mp->data;
-+ part = m_data->part_head.next;
-+
-+ while (part != &m_data->part_head) {
-+ found_hdr = NULL;
-+ while ((found_hdr = pjsip_hdr_find_by_name(&part->hdr, &hdr_name,
-+ (found_hdr ? found_hdr->next : NULL))) != NULL) {
-+ if (pj_strcmp(&hdr_value, &found_hdr->hvalue) == 0) {
-+ return part;
-+ }
-+ }
-+ part = part->next;
-+ }
-+ return NULL;
-+}
-+
-+PJ_DEF(pjsip_multipart_part*)
-+pjsip_multipart_find_part_by_cid_uri(pj_pool_t *pool,
-+ const pjsip_msg_body *mp,
-+ pjsip_other_uri *cid_uri)
-+{
-+ PJ_ASSERT_RETURN(pool && mp && cid_uri, NULL);
-+
-+ if (pj_strcmp2(&cid_uri->scheme, "cid") != 0) {
-+ return NULL;
-+ }
-+ /*
-+ * We only need to pass the URI content so we
-+ * can do that directly.
-+ */
-+ return pjsip_multipart_find_part_by_cid_str(pool, mp, &cid_uri->content);
-+}
-+
- /* Parse a multipart part. "pct" is parent content-type */
- static pjsip_multipart_part *parse_multipart_part(pj_pool_t *pool,
- char *start,
-@@ -584,6 +799,7 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,
- (int)boundary.slen, boundary.ptr));
- }
-
-+
- /* Build the delimiter:
- * delimiter = "--" boundary
- */
-@@ -630,6 +846,8 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,
- if (*curptr=='\r') ++curptr;
- if (*curptr!='\n') {
- /* Expecting a newline here */
-+ PJ_LOG(2, (THIS_FILE, "Failed to find newline"));
-+
- return NULL;
- }
- ++curptr;
-@@ -645,6 +863,7 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,
- curptr = pj_strstr(&subbody, &delim);
- if (!curptr) {
- /* We're really expecting end delimiter to be found. */
-+ PJ_LOG(2, (THIS_FILE, "Failed to find end-delimiter"));
- return NULL;
- }
- }
-@@ -670,9 +889,13 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,
- part = parse_multipart_part(pool, start_body, end_body - start_body,
- ctype);
- if (part) {
-+ TRACE_((THIS_FILE, "Adding part"));
- pjsip_multipart_add_part(pool, body, part);
-+ } else {
-+ PJ_LOG(2, (THIS_FILE, "Failed to add part"));
- }
- }
-+ TRACE_((THIS_FILE, "pjsip_multipart_parse finished: %p", body));
-
- return body;
- }
-diff --git a/pjsip/src/test/multipart_test.c b/pjsip/src/test/multipart_test.c
-index 4f16e68bf..97267a290 100644
---- a/pjsip/src/test/multipart_test.c
-+++ b/pjsip/src/test/multipart_test.c
-@@ -28,6 +28,7 @@
- typedef pj_status_t (*verify_ptr)(pj_pool_t*,pjsip_msg_body*);
-
- static pj_status_t verify1(pj_pool_t *pool, pjsip_msg_body *body);
-+static pj_status_t verify2(pj_pool_t *pool, pjsip_msg_body *body);
-
- static struct test_t
- {
-@@ -68,7 +69,41 @@ static struct test_t
- "This is epilogue, which should be ignored too",
-
- &verify1
-+ },
-+ {
-+ /* Content-type */
-+ "multipart", "mixed", "12345",
-+
-+ /* Body: */
-+ "This is the prolog, which should be ignored.\r\n"
-+ "--12345\r\n"
-+ "Content-Type: text/plain\r\n"
-+ "Content-ID: <header1 at example.org>\r\n"
-+ "Content-ID: <\"header1\"@example.org>\r\n"
-+ "Content-Length: 13\r\n"
-+ "\r\n"
-+ "has header1\r\n"
-+ "--12345 \t\r\n"
-+ "Content-Type: application/pidf+xml\r\n"
-+ "Content-ID: <my header2 at example.org>\r\n"
-+ "Content-ID: <my\xffheader2 at example.org>\r\n"
-+ "Content-Length: 13\r\n"
-+ "\r\n"
-+ "has header2\r\n"
-+ "--12345\r\n"
-+ "Content-Type: text/plain\r\n"
-+ "Content-ID: <my header3 at example.org>\r\n"
-+ "Content-ID: <header1 at example.org>\r\n"
-+ "Content-ID: <my header4 at example.org>\r\n"
-+ "Content-Length: 13\r\n"
-+ "\r\n"
-+ "has header4\r\n"
-+ "--12345--\r\n"
-+ "This is epilogue, which should be ignored too",
-+
-+ &verify2
- }
-+
- };
-
- static void init_media_type(pjsip_media_type *mt,
-@@ -87,6 +122,192 @@ static void init_media_type(pjsip_media_type *mt,
- }
- }
-
-+static int verify_hdr(pj_pool_t *pool, pjsip_msg_body *multipart_body,
-+ void *hdr, char *part_body)
-+{
-+ pjsip_media_type mt;
-+ pjsip_multipart_part *part;
-+ pj_str_t the_body;
-+
-+
-+ part = pjsip_multipart_find_part_by_header(pool, multipart_body, hdr, NULL);
-+ if (!part) {
-+ return -1;
-+ }
-+
-+ the_body.ptr = (char*)part->body->data;
-+ the_body.slen = part->body->len;
-+
-+ if (pj_strcmp2(&the_body, part_body) != 0) {
-+ return -2;
-+ }
-+
-+ return 0;
-+}
-+
-+static int verify_cid_str(pj_pool_t *pool, pjsip_msg_body *multipart_body,
-+ pj_str_t cid_url, char *part_body)
-+{
-+ pjsip_media_type mt;
-+ pjsip_multipart_part *part;
-+ pj_str_t the_body;
-+
-+ part = pjsip_multipart_find_part_by_cid_str(pool, multipart_body, &cid_url);
-+ if (!part) {
-+ return -3;
-+ }
-+
-+ the_body.ptr = (char*)part->body->data;
-+ the_body.slen = part->body->len;
-+
-+ if (pj_strcmp2(&the_body, part_body) != 0) {
-+ return -4;
-+ }
-+
-+ return 0;
-+}
-+
-+static int verify_cid_uri(pj_pool_t *pool, pjsip_msg_body *multipart_body,
-+ pjsip_other_uri *cid_uri, char *part_body)
-+{
-+ pjsip_media_type mt;
-+ pjsip_multipart_part *part;
-+ pj_str_t the_body;
-+
-+ part = pjsip_multipart_find_part_by_cid_uri(pool, multipart_body, cid_uri);
-+ if (!part) {
-+ return -5;
-+ }
-+
-+ the_body.ptr = (char*)part->body->data;
-+ the_body.slen = part->body->len;
-+
-+ if (pj_strcmp2(&the_body, part_body) != 0) {
-+ return -6;
-+ }
-+
-+ return 0;
-+}
-+
-+static pj_status_t verify2(pj_pool_t *pool, pjsip_msg_body *body)
-+{
-+ int rc = 0;
-+ int rcbase = 300;
-+ pjsip_other_uri *cid_uri;
-+ pjsip_ctype_hdr *ctype_hdr = pjsip_ctype_hdr_create(pool);
-+
-+ ctype_hdr->media.type = pj_str("application");
-+ ctype_hdr->media.subtype = pj_str("pidf+xml");
-+
-+ rc = verify_hdr(pool, body, ctype_hdr, "has header2");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("cid:header1 at example.org"), "has header1");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("%22header1%22 at example.org"), "has header1");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "<cid:%22header1%22 at example.org>",
-+ strlen("<cid:%22header1%22 at example.org>"), 0));
-+ rcbase += 10;
-+ rc = verify_cid_uri(pool, body, cid_uri, "has header1");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("<cid:my%20header2 at example.org>"), "has header2");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("cid:my%ffheader2 at example.org"), "has header2");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "<cid:my%ffheader2 at example.org>",
-+ strlen("<cid:my%ffheader2 at example.org>"), 0));
-+ rcbase += 10;
-+ rc = verify_cid_uri(pool, body, cid_uri, "has header2");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("cid:my%20header3 at example.org"), "has header4");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("<cid:my%20header4 at example.org>"), "has header4");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "<cid:my%20header4 at example.org>",
-+ strlen("<cid:my%20header4 at example.org>"), 0));
-+ rcbase += 10;
-+ rc = verify_cid_uri(pool, body, cid_uri, "has header4");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("<my%20header3 at example.org>"), "has header4");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ /* These should all fail for malformed or missing URI */
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("cid:"), "has header4");
-+ if (!rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str(""), "has header4");
-+ if (!rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("<>"), "has header4");
-+ if (!rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("<cid>"), "has header4");
-+ if (!rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ /*
-+ * This is going to pass but the ' ' in the uri is un-encoded which is invalid
-+ * so we should never see it.
-+ */
-+ rcbase += 10;
-+ rc = verify_cid_str(pool, body, pj_str("cid:my header3 at example.org"), "has header4");
-+ if (rc) {
-+ return (rc - rcbase);
-+ }
-+
-+ return 0;
-+}
-+
- static int verify_part(pjsip_multipart_part *part,
- char *h_content_type,
- char *h_content_subtype,
-@@ -236,8 +457,10 @@ static int parse_test(void)
-
- pj_strdup2_with_null(pool, &str, p_tests[i].msg);
- body = pjsip_multipart_parse(pool, str.ptr, str.slen, &ctype, 0);
-- if (!body)
-+ if (!body) {
-+ pj_pool_release(pool);
- return -100;
-+ }
-
- if (p_tests[i].verify) {
- rc = p_tests[i].verify(pool, body);
---
-2.34.1
-
diff --git a/third-party/pjproject/pjproject-2.10.tar.bz2.md5 b/third-party/pjproject/pjproject-2.10.tar.bz2.md5
deleted file mode 100644
index 57261b4..0000000
--- a/third-party/pjproject/pjproject-2.10.tar.bz2.md5
+++ /dev/null
@@ -1,2 +0,0 @@
-5d0202f79a7aeb14873c45b0e4c14a70 *pjproject-2.10.zip
-4fffc49b461133f0a4143b05a22fb30e pjproject-2.10.tar.bz2
diff --git a/third-party/pjproject/pjproject-2.12.tar.bz2.md5 b/third-party/pjproject/pjproject-2.12.tar.bz2.md5
new file mode 100644
index 0000000..ab9b9d4
--- /dev/null
+++ b/third-party/pjproject/pjproject-2.12.tar.bz2.md5
@@ -0,0 +1 @@
+ad796d38f5f0357cb5b2fe1b4460b581 pjproject-2.12.tar.bz2
diff --git a/third-party/versions.mak b/third-party/versions.mak
index 2a59cf4..b95d687 100644
--- a/third-party/versions.mak
+++ b/third-party/versions.mak
@@ -1,2 +1,2 @@
JANSSON_VERSION = 2.14
-PJPROJECT_VERSION = 2.10
+PJPROJECT_VERSION = 2.12
--
To view, visit https://gerrit.asterisk.org/c/asterisk/+/18112
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: 18
Gerrit-Change-Id: Id39ece02dedb7b9f739e0e37ea47d76854af7191
Gerrit-Change-Number: 18112
Gerrit-PatchSet: 1
Gerrit-Owner: Joshua Colp <jcolp at sangoma.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20220228/22056cf2/attachment-0001.html>
More information about the asterisk-code-review
mailing list