From f5120a46371ff75f401c1cb724c3880811bfbae0 Mon Sep 17 00:00:00 2001 From: Sebastian Kemper Date: Sat, 3 Dec 2022 15:41:32 +0100 Subject: [PATCH] pjproject: bump to 2.12.1 This is a manual cherry-pick of a57228588602e5217b95f1e9ded0b76402cb6c72 and 472f1ac7ac867b8fbc2841c56e7d61935dba9d52. The only difference is that the uclibc-related patches were not dropped, because uclibc is used in OpenWrt 21.02. - add "--disable-android-mediacodec" to configure - add EXCLUDE_APP=1 to "make" calls so some apps aren't built (speeds up the build a bit) - drop "sed" call as no longer needed - update 0004-config_site.patch to sync up with Asterisk 18.14.0 - update 0006-fix-pkg_config-file.patch as there were some changes in this area upstream - add 0007-execinfo.patch to prevent errors due to missing - sync patches with Asterisk 18.14.0 - backports two security fixes (c4d3498 and 450baca) from pjproject 2.13, source: asterisk 20.0.1 Signed-off-by: Sebastian Kemper --- libs/pjproject/Makefile | 12 +- .../patches/0003-non-gnu-pthreads.patch | 4 +- libs/pjproject/patches/0004-config_site.patch | 8 +- .../0005-remove-hardcoded-lstdc++.patch | 4 +- .../patches/0006-fix-pkg_config-file.patch | 15 +- libs/pjproject/patches/0007-execinfo.patch | 71 ++ .../patches/0011-sip_inv_patch.patch | 37 - .../patches/0020-pjlib_cancel_timer_0.patch | 35 - .../0050-fix-race-parallel-build.patch | 68 -- ...one-sdp-for-sip-timer-refresh-invite.patch | 27 - ...correct-copying-when-creating-cancel.patch | 32 - .../0080-fix-sdp-neg-modify-local-offer.patch | 31 - ...ip-unsupported-digest-algorithm-2408.patch | 201 ------ .../0100-allow_multiple_auth_headers.patch | 397 +++++++++++ .../patches/0100-fix-double-stun-free.patch | 78 --- .../0110-tls-parent-listener-destroyed.patch | 162 ----- .../patches/0111-ssl-premature-destroy.patch | 132 ---- ..._get_rtpmap-Strip-param-trailing-whi.patch | 27 - ...ditional-multipart-support-2919-2920.patch | 653 ------------------ ...escaping-of-tokens-during-parsing-29.patch | 116 ---- ...ate-generic-pjsip_hdr_find-functions.patch | 169 ----- ...60-Additional-multipart-improvements.patch | 635 ----------------- .../patches/0170-stun-integer-underflow.patch | 21 - .../patches/0171-dialog-set-free.patch | 109 --- .../patches/0172-prevent-multipart-oob.patch | 37 - ...verflow-in-pjlib-scanner-and-pjmedia.patch | 297 ++++++++ ...hen-parsing-message-as-a-STUN-client.patch | 39 ++ 27 files changed, 827 insertions(+), 2590 deletions(-) create mode 100644 libs/pjproject/patches/0007-execinfo.patch delete mode 100644 libs/pjproject/patches/0011-sip_inv_patch.patch delete mode 100644 libs/pjproject/patches/0020-pjlib_cancel_timer_0.patch delete mode 100644 libs/pjproject/patches/0050-fix-race-parallel-build.patch delete mode 100644 libs/pjproject/patches/0060-clone-sdp-for-sip-timer-refresh-invite.patch delete mode 100644 libs/pjproject/patches/0070-fix-incorrect-copying-when-creating-cancel.patch delete mode 100644 libs/pjproject/patches/0080-fix-sdp-neg-modify-local-offer.patch delete mode 100644 libs/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch create mode 100644 libs/pjproject/patches/0100-allow_multiple_auth_headers.patch delete mode 100644 libs/pjproject/patches/0100-fix-double-stun-free.patch delete mode 100644 libs/pjproject/patches/0110-tls-parent-listener-destroyed.patch delete mode 100644 libs/pjproject/patches/0111-ssl-premature-destroy.patch delete mode 100644 libs/pjproject/patches/0120-pjmedia_sdp_attr_get_rtpmap-Strip-param-trailing-whi.patch delete mode 100644 libs/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch delete mode 100644 libs/pjproject/patches/0140-Fix-incorrect-unescaping-of-tokens-during-parsing-29.patch delete mode 100644 libs/pjproject/patches/0150-Create-generic-pjsip_hdr_find-functions.patch delete mode 100644 libs/pjproject/patches/0160-Additional-multipart-improvements.patch delete mode 100644 libs/pjproject/patches/0170-stun-integer-underflow.patch delete mode 100644 libs/pjproject/patches/0171-dialog-set-free.patch delete mode 100644 libs/pjproject/patches/0172-prevent-multipart-oob.patch create mode 100644 libs/pjproject/patches/0200-potential-buffer-overflow-in-pjlib-scanner-and-pjmedia.patch create mode 100644 libs/pjproject/patches/0201-potential-stack-buffer-overflow-when-parsing-message-as-a-STUN-client.patch diff --git a/libs/pjproject/Makefile b/libs/pjproject/Makefile index 5e7b645..f1fe59b 100644 --- a/libs/pjproject/Makefile +++ b/libs/pjproject/Makefile @@ -10,14 +10,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=pjproject -PKG_VERSION:=2.10 -PKG_RELEASE:=7 +PKG_VERSION:=2.12.1 +PKG_RELEASE:=1 # download "vX.Y.tar.gz" as "pjproject-vX.Y.tar.gz" PKG_SOURCE_URL_FILE:=$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_URL_FILE) PKG_SOURCE_URL:=https://github.com/pjsip/$(PKG_NAME)/archive -PKG_HASH:=936a4c5b98601b52325463a397ddf11ab4106c6a7b04f8dc7cdd377efbb597de +PKG_HASH:=d0feef6963b07934e821ba4328aecb4c36358515c1b3e507da5874555d713533 PKG_INSTALL:=1 PKG_LICENSE:=GPL-2.0 @@ -60,6 +60,7 @@ endef CONFIGURE_ARGS+= \ $(if $(CONFIG_SOFT_FLOAT),--disable-floating-point) \ + --disable-android-mediacodec \ --disable-bcg729 \ --disable-darwin-ssl \ --disable-ext-sound \ @@ -94,8 +95,8 @@ CONFIGURE_ARGS+= \ TARGET_CFLAGS+=$(TARGET_CPPFLAGS) define Build/Compile - $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) dep - $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) + $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) EXCLUDE_APP=1 dep + $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) EXCLUDE_APP=1 endef PJPROJECT_LIBS:= \ @@ -110,7 +111,6 @@ define Build/InstallDev $(foreach m,$(PJPROJECT_LIBS),$(CP) $(PKG_INSTALL_DIR)/usr/lib/$(m)* $(1)/usr/lib;) $(INSTALL_DIR) $(1)/usr/lib/pkgconfig - $(SED) 's|$(TARGET_CFLAGS)||g' $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libpjproject.pc $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libpjproject.pc \ $(1)/usr/lib/pkgconfig endef diff --git a/libs/pjproject/patches/0003-non-gnu-pthreads.patch b/libs/pjproject/patches/0003-non-gnu-pthreads.patch index b44cd70..5b03ce5 100644 --- a/libs/pjproject/patches/0003-non-gnu-pthreads.patch +++ b/libs/pjproject/patches/0003-non-gnu-pthreads.patch @@ -1,6 +1,6 @@ --- a/pjlib/src/pj/os_core_unix.c +++ b/pjlib/src/pj/os_core_unix.c -@@ -1139,7 +1139,7 @@ static pj_status_t init_mutex(pj_mutex_t +@@ -1247,7 +1247,7 @@ static pj_status_t init_mutex(pj_mutex_t return PJ_RETURN_OS_ERROR(rc); if (type == PJ_MUTEX_SIMPLE) { @@ -9,7 +9,7 @@ defined(PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE) rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); #elif (defined(PJ_RTEMS) && PJ_RTEMS!=0) || \ -@@ -1149,7 +1149,7 @@ static pj_status_t init_mutex(pj_mutex_t +@@ -1257,7 +1257,7 @@ static pj_status_t init_mutex(pj_mutex_t rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); #endif } else { diff --git a/libs/pjproject/patches/0004-config_site.patch b/libs/pjproject/patches/0004-config_site.patch index b5e6d86..3a1e1b9 100644 --- a/libs/pjproject/patches/0004-config_site.patch +++ b/libs/pjproject/patches/0004-config_site.patch @@ -1,6 +1,6 @@ --- /dev/null +++ b/pjlib/include/pj/config_site.h -@@ -0,0 +1,79 @@ +@@ -0,0 +1,83 @@ +/* + * Asterisk config_site.h + */ @@ -70,7 +70,7 @@ +/* Increase limits to allow more formats */ +#define PJMEDIA_MAX_SDP_FMT 64 +#define PJMEDIA_MAX_SDP_BANDW 4 -+#define PJMEDIA_MAX_SDP_ATTR (PJMEDIA_MAX_SDP_FMT*2 + 4) ++#define PJMEDIA_MAX_SDP_ATTR (PJMEDIA_MAX_SDP_FMT*3 + 4) +#define PJMEDIA_MAX_SDP_MEDIA 16 + +/* @@ -80,3 +80,7 @@ + */ +#define PJSIP_TCP_KEEP_ALIVE_INTERVAL 0 +#define PJSIP_TLS_KEEP_ALIVE_INTERVAL 0 ++ ++#define PJSIP_TSX_UAS_CONTINUE_ON_TP_ERROR 0 ++#define PJ_SSL_SOCK_OSSL_USE_THREAD_CB 0 ++#define PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER 1 diff --git a/libs/pjproject/patches/0005-remove-hardcoded-lstdc++.patch b/libs/pjproject/patches/0005-remove-hardcoded-lstdc++.patch index d1db8da..93e9114 100644 --- a/libs/pjproject/patches/0005-remove-hardcoded-lstdc++.patch +++ b/libs/pjproject/patches/0005-remove-hardcoded-lstdc++.patch @@ -1,13 +1,13 @@ --- a/build.mak.in +++ b/build.mak.in -@@ -296,7 +296,6 @@ export APP_LDLIBS := $(PJSUA_LIB_LDLIB) +@@ -328,7 +328,6 @@ export APP_LDLIBS := $(PJSUA_LIB_LDLIB) $(PJLIB_LDLIB) \ @LIBS@ export APP_LDXXLIBS := $(PJSUA2_LIB_LDLIB) \ - -lstdc++ \ $(APP_LDLIBS) - # Here are the variabels to use if application is using the library + # Here are the variables to use if application is using the library --- a/pjsip/build/Makefile +++ b/pjsip/build/Makefile @@ -152,8 +152,7 @@ export PJSUA2_LIB_LDFLAGS += $(PJSUA_LIB diff --git a/libs/pjproject/patches/0006-fix-pkg_config-file.patch b/libs/pjproject/patches/0006-fix-pkg_config-file.patch index b8e9391..c9d82b4 100644 --- a/libs/pjproject/patches/0006-fix-pkg_config-file.patch +++ b/libs/pjproject/patches/0006-fix-pkg_config-file.patch @@ -13,13 +13,12 @@ Description: Multimedia communication library --- a/build.mak.in +++ b/build.mak.in -@@ -314,8 +314,7 @@ export PJ_LIBXX_FILES := $(APP_LIBXX_FIL - # And here are the variables to use if application is using the - # library from the install location (i.e. --prefix) +@@ -348,6 +348,6 @@ export PJ_LIBXX_FILES := $(APP_LIBXX_FIL export PJ_INSTALL_DIR := @prefix@ --export PJ_INSTALL_INC_DIR := @includedir@ + export PJ_INSTALL_INC_DIR := @includedir@ export PJ_INSTALL_LIB_DIR := @libdir@ --export PJ_INSTALL_CFLAGS := -I$(PJ_INSTALL_INC_DIR) -DPJ_AUTOCONF=1 @CFLAGS@ -+export PJ_INSTALL_CFLAGS := -DPJ_AUTOCONF=1 @CFLAGS@ - export PJ_INSTALL_CXXFLAGS := @CXXFLAGS@ $(PJ_INSTALL_CFLAGS) - export PJ_INSTALL_LDFLAGS := -L$(PJ_INSTALL_LIB_DIR) $(APP_LDLIBS) +-export PJ_INSTALL_CFLAGS := -I$(PJ_INSTALL_INC_DIR) -DPJ_AUTOCONF=1 @ac_cflags@ ++export PJ_INSTALL_CFLAGS := -DPJ_AUTOCONF=1 @ac_cflags@ + export PJ_INSTALL_LDFLAGS_PRIVATE := $(APP_THIRD_PARTY_LIBS) $(APP_THIRD_PARTY_EXT) @LIBS@ +-export PJ_INSTALL_LDFLAGS := -L$(PJ_INSTALL_LIB_DIR) $(filter-out $(PJ_INSTALL_LDFLAGS_PRIVATE),$(APP_LDXXLIBS)) ++export PJ_INSTALL_LDFLAGS := $(filter-out $(PJ_INSTALL_LDFLAGS_PRIVATE),$(APP_LDXXLIBS)) diff --git a/libs/pjproject/patches/0007-execinfo.patch b/libs/pjproject/patches/0007-execinfo.patch new file mode 100644 index 0000000..be1b954 --- /dev/null +++ b/libs/pjproject/patches/0007-execinfo.patch @@ -0,0 +1,71 @@ +In upstream commit b236337 unit tests were extended to print stack traces when +crashing, using GNU extensions. But this won't work with musl etc. (no +"execinfo.h"), so we need to update the condition to make sure this is only +done when glibc is used. + +--- a/pjlib-util/src/pjlib-util-test/main.c ++++ b/pjlib-util/src/pjlib-util-test/main.c +@@ -33,7 +33,7 @@ static void init_signals() + sigaction(SIGALRM, &act, NULL); + } + +-#elif PJ_LINUX || PJ_DARWINOS ++#elif (defined(PJ_LINUX) && PJ_LINUX!=0 && defined(__GLIBC__)) || PJ_DARWINOS + + #include + #include +--- a/pjlib/src/pjlib-test/main.c ++++ b/pjlib/src/pjlib-test/main.c +@@ -54,7 +54,7 @@ static void init_signals() + sigaction(SIGALRM, &act, NULL); + } + +-#elif PJ_LINUX || PJ_DARWINOS ++#elif (defined(PJ_LINUX) && PJ_LINUX!=0 && defined(__GLIBC__)) || PJ_DARWINOS + + #include + #include +--- a/pjmedia/src/test/main.c ++++ b/pjmedia/src/test/main.c +@@ -32,7 +32,7 @@ + #endif + + +-#if PJ_LINUX || PJ_DARWINOS ++#if (defined(PJ_LINUX) && PJ_LINUX!=0 && defined(__GLIBC__)) || PJ_DARWINOS + + #include + #include +--- a/pjnath/src/pjnath-test/main.c ++++ b/pjnath/src/pjnath-test/main.c +@@ -32,7 +32,7 @@ static void init_signals() + sigaction(SIGALRM, &act, NULL); + } + +-#elif PJ_LINUX || PJ_DARWINOS ++#elif (defined(PJ_LINUX) && PJ_LINUX!=0 && defined(__GLIBC__)) || PJ_DARWINOS + + #include + #include +--- a/pjsip-apps/src/pjsua/main.c ++++ b/pjsip-apps/src/pjsua/main.c +@@ -80,7 +80,7 @@ static void setup_signal_handler(void) + SetConsoleCtrlHandler(&CtrlHandler, TRUE); + } + +-#elif PJ_LINUX || PJ_DARWINOS ++#elif (defined(PJ_LINUX) && PJ_LINUX!=0 && defined(__GLIBC__)) || PJ_DARWINOS + + #include + #include +--- a/pjsip/src/test/main.c ++++ b/pjsip/src/test/main.c +@@ -36,7 +36,7 @@ static void usage(void) + list_tests(); + } + +-#if PJ_LINUX || PJ_DARWINOS ++#if (defined(PJ_LINUX) && PJ_LINUX!=0 && defined(__GLIBC__)) || PJ_DARWINOS + + #include + #include diff --git a/libs/pjproject/patches/0011-sip_inv_patch.patch b/libs/pjproject/patches/0011-sip_inv_patch.patch deleted file mode 100644 index c410b9a..0000000 --- a/libs/pjproject/patches/0011-sip_inv_patch.patch +++ /dev/null @@ -1,37 +0,0 @@ -commit c3c1bf45cae2a35003aa16c267d59f97027f9c5e -Author: Kevin Harwell -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 - ---- 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_sess - (*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/libs/pjproject/patches/0020-pjlib_cancel_timer_0.patch b/libs/pjproject/patches/0020-pjlib_cancel_timer_0.patch deleted file mode 100644 index 3fe6294..0000000 --- a/libs/pjproject/patches/0020-pjlib_cancel_timer_0.patch +++ /dev/null @@ -1,35 +0,0 @@ -commit 40dd48d10911f4ff9b8dfbf16428fbc9acc434ba -Author: Riza Sulistyo -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. - ---- 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; - ---- 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/libs/pjproject/patches/0050-fix-race-parallel-build.patch b/libs/pjproject/patches/0050-fix-race-parallel-build.patch deleted file mode 100644 index 3a48d41..0000000 --- a/libs/pjproject/patches/0050-fix-race-parallel-build.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 78683646c8bc670ec730a42494e075f671a08e28 Mon Sep 17 00:00:00 2001 -From: Guido Falsi -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(-) - ---- 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),$<) ---- a/pjsip/build/Makefile -+++ b/pjsip/build/Makefile -@@ -261,7 +261,7 @@ $(PJSUA_LIB_LIB) $(PJSUA_LIB_SONAME): $( - - 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/libs/pjproject/patches/0060-clone-sdp-for-sip-timer-refresh-invite.patch b/libs/pjproject/patches/0060-clone-sdp-for-sip-timer-refresh-invite.patch deleted file mode 100644 index 0fda06d..0000000 --- a/libs/pjproject/patches/0060-clone-sdp-for-sip-timer-refresh-invite.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/pjmedia/src/pjmedia/sdp_neg.c -+++ b/pjmedia/src/pjmedia/sdp_neg.c -@@ -906,7 +906,7 @@ static pj_status_t process_m_answer( pj_ - * 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 @@ static pj_status_t process_answer(pj_poo - 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/libs/pjproject/patches/0070-fix-incorrect-copying-when-creating-cancel.patch b/libs/pjproject/patches/0070-fix-incorrect-copying-when-creating-cancel.patch deleted file mode 100644 index c8e4b4c..0000000 --- a/libs/pjproject/patches/0070-fix-incorrect-copying-when-creating-cancel.patch +++ /dev/null @@ -1,32 +0,0 @@ -From ce18018cc17bef8f80c08686e3a7b28384ef3ba5 Mon Sep 17 00:00:00 2001 -From: sauwming -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(-) - ---- 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_c - 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. - */ diff --git a/libs/pjproject/patches/0080-fix-sdp-neg-modify-local-offer.patch b/libs/pjproject/patches/0080-fix-sdp-neg-modify-local-offer.patch deleted file mode 100644 index 889d012..0000000 --- a/libs/pjproject/patches/0080-fix-sdp-neg-modify-local-offer.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- 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_modi - { - 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_modi - /* 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/libs/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch b/libs/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch deleted file mode 100644 index c779f67..0000000 --- a/libs/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch +++ /dev/null @@ -1,201 +0,0 @@ -From bdbeb7c4b2b11efc2e59f5dee7aa4360a2bc9fff Mon Sep 17 00:00:00 2001 -From: sauwming -Date: Thu, 22 Apr 2021 14:03:28 +0800 -Subject: [PATCH 90/90] Skip unsupported digest algorithm (#2408) - -Co-authored-by: Nanang Izzuddin ---- - 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 - ---- 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 - 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 - { - 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 - 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_reini - { - 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_reini - */ - 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_reini - */ - 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_reini - - /* 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; ---- /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@localhost --username=a --realm=* --registrar=$SIPP_URI"] -+ -+PJSUA_EXPECTS = [[0, "registration success", ""]] ---- /dev/null -+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml -@@ -0,0 +1,83 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ diff --git a/libs/pjproject/patches/0100-allow_multiple_auth_headers.patch b/libs/pjproject/patches/0100-allow_multiple_auth_headers.patch new file mode 100644 index 0000000..39bc83f --- /dev/null +++ b/libs/pjproject/patches/0100-allow_multiple_auth_headers.patch @@ -0,0 +1,397 @@ +commit 8e95490e37938f45d9d812905246036c3185b94f +Author: Riza Sulistyo +Date: Thu Mar 24 12:53:03 2022 +0700 + + Add compile time option to allow multiple Authorization header (#3010) + +--- a/pjsip/include/pjsip/sip_config.h ++++ b/pjsip/include/pjsip/sip_config.h +@@ -1280,6 +1280,18 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void) + # define PJSIP_AUTH_CNONCE_USE_DIGITS_ONLY 1 + #endif + ++/** ++ * Allow client to send multiple Authorization header when receiving multiple ++ * WWW-Authenticate header fields. If this is disabled, the stack will send ++ * Authorization header field containing credentials that match the ++ * topmost header field. ++ * ++ * Default is 0 ++ */ ++#ifndef PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER ++# define PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER 0 ++#endif ++ + /***************************************************************************** + * SIP Event framework and presence settings. + */ +@@ -1458,6 +1470,11 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void) + # define PJSIP_INV_ACCEPT_UNKNOWN_BODY PJ_FALSE + #endif + ++/** ++ * Dump configuration to log with verbosity equal to info(3). ++ */ ++PJ_DECL(void) pjsip_dump_config(void); ++ + PJ_END_DECL + + /** +--- a/pjsip/src/pjsip/sip_auth_client.c ++++ b/pjsip/src/pjsip/sip_auth_client.c +@@ -1367,7 +1367,7 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini + chal_cnt = 0; + auth_cnt = 0; + last_auth_err = PJSIP_EAUTHNOAUTH; +- while (hdr != &rdata->msg_info.msg->hdr && auth_cnt == 0) { ++ while (hdr != &rdata->msg_info.msg->hdr) { + pjsip_cached_auth *cached_auth; + const pjsip_www_authenticate_hdr *hchal; + pjsip_authorization_hdr *hauth; +@@ -1431,6 +1431,11 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini + /* Process next header. */ + hdr = hdr->next; + auth_cnt++; ++ ++#if defined(PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER) && \ ++ PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER==0 ++ break; ++#endif + } + + /* Check if challenge is present */ +--- a/pjsip/src/pjsip/sip_config.c ++++ b/pjsip/src/pjsip/sip_config.c +@@ -19,6 +19,9 @@ + */ + + #include ++#include ++ ++static const char *id = "sip_config.c"; + + /* pjsip configuration instance, initialized with default values */ + pjsip_cfg_t pjsip_sip_cfg_var = +@@ -65,6 +68,195 @@ pjsip_cfg_t pjsip_sip_cfg_var = + } + }; + ++PJ_DEF(void) pjsip_dump_config(void) ++{ ++ PJ_LOG(3, (id, "Dumping PJSIP configurations:")); ++ PJ_LOG(3, (id, " PJSIP_MAX_DIALOG_COUNT : %d", ++ PJSIP_MAX_DIALOG_COUNT)); ++ PJ_LOG(3, (id, " PJSIP_MAX_TRANSPORTS : %d", ++ PJSIP_MAX_TRANSPORTS)); ++ PJ_LOG(3, (id, " PJSIP_TPMGR_HTABLE_SIZE : %d", ++ PJSIP_TPMGR_HTABLE_SIZE)); ++ PJ_LOG(3, (id, " PJSIP_MAX_URL_SIZE : %d", ++ PJSIP_MAX_URL_SIZE)); ++ PJ_LOG(3, (id, " PJSIP_MAX_MODULE : %d", ++ PJSIP_MAX_MODULE)); ++ PJ_LOG(3, (id, " PJSIP_MAX_PKT_LEN : %d", ++ PJSIP_MAX_PKT_LEN)); ++ PJ_LOG(3, (id, " PJSIP_HANDLE_EVENTS_HAS_SLEEP_ON_ERR : %d", ++ PJSIP_HANDLE_EVENTS_HAS_SLEEP_ON_ERR)); ++ PJ_LOG(3, (id, " PJSIP_ACCEPT_MULTIPLE_SDP_ANSWERS : %d", ++ PJSIP_ACCEPT_MULTIPLE_SDP_ANSWERS)); ++ PJ_LOG(3, (id, " PJSIP_UDP_SIZE_THRESHOLD : %d", ++ PJSIP_UDP_SIZE_THRESHOLD)); ++ PJ_LOG(3, (id, " PJSIP_INCLUDE_ALLOW_HDR_IN_DLG : %d", ++ PJSIP_INCLUDE_ALLOW_HDR_IN_DLG)); ++ PJ_LOG(3, (id, " PJSIP_SAFE_MODULE : %d", ++ PJSIP_SAFE_MODULE)); ++ PJ_LOG(3, (id, " PJSIP_CHECK_VIA_SENT_BY : %d", ++ PJSIP_CHECK_VIA_SENT_BY)); ++ PJ_LOG(3, (id, " PJSIP_UNESCAPE_IN_PLACE : %d", ++ PJSIP_UNESCAPE_IN_PLACE)); ++ PJ_LOG(3, (id, " PJSIP_MAX_NET_EVENTS : %d", ++ PJSIP_MAX_NET_EVENTS)); ++ PJ_LOG(3, (id, " PJSIP_MAX_TIMED_OUT_ENTRIES : %d", ++ PJSIP_MAX_TIMED_OUT_ENTRIES)); ++ PJ_LOG(3, (id, " PJSIP_TRANSPORT_IDLE_TIME : %d", ++ PJSIP_TRANSPORT_IDLE_TIME)); ++ PJ_LOG(3, (id, " PJSIP_TRANSPORT_SERVER_IDLE_TIME : %d", ++ PJSIP_TRANSPORT_SERVER_IDLE_TIME)); ++ PJ_LOG(3, (id, " PJSIP_MAX_TRANSPORT_USAGE : %d", ++ PJSIP_MAX_TRANSPORT_USAGE)); ++ PJ_LOG(3, (id, " PJSIP_TCP_TRANSPORT_BACKLOG : %d", ++ PJSIP_TCP_TRANSPORT_BACKLOG)); ++ PJ_LOG(3, (id, " PJSIP_TCP_TRANSPORT_REUSEADDR : %d", ++ PJSIP_TCP_TRANSPORT_REUSEADDR)); ++ PJ_LOG(3, (id, " PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER : %d", ++ PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER)); ++ PJ_LOG(3, (id, " PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER : %d", ++ PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER)); ++ PJ_LOG(3, (id, " PJSIP_TCP_KEEP_ALIVE_INTERVAL : %d", ++ PJSIP_TCP_KEEP_ALIVE_INTERVAL)); ++ PJ_LOG(3, (id, " PJSIP_POOL_INC_TRANSPORT : %d", ++ PJSIP_POOL_INC_TRANSPORT)); ++ PJ_LOG(3, (id, " PJSIP_POOL_LEN_TDATA : %d", ++ PJSIP_POOL_LEN_TDATA)); ++ PJ_LOG(3, (id, " PJSIP_POOL_INC_TDATA : %d", ++ PJSIP_POOL_INC_TDATA)); ++ PJ_LOG(3, (id, " PJSIP_POOL_LEN_UA : %d", ++ PJSIP_POOL_LEN_UA)); ++ PJ_LOG(3, (id, " PJSIP_POOL_INC_UA : %d", ++ PJSIP_POOL_INC_UA)); ++ PJ_LOG(3, (id, " PJSIP_POOL_EVSUB_LEN : %d", ++ PJSIP_POOL_EVSUB_LEN)); ++ PJ_LOG(3, (id, " PJSIP_POOL_EVSUB_INC : %d", ++ PJSIP_POOL_EVSUB_INC)); ++ PJ_LOG(3, (id, " PJSIP_MAX_FORWARDS_VALUE : %d", ++ PJSIP_MAX_FORWARDS_VALUE)); ++ PJ_LOG(3, (id, " PJSIP_RFC3261_BRANCH_ID : %s", ++ PJSIP_RFC3261_BRANCH_ID)); ++ PJ_LOG(3, (id, " PJSIP_RFC3261_BRANCH_LEN : %d", ++ PJSIP_RFC3261_BRANCH_LEN)); ++ PJ_LOG(3, (id, " PJSIP_POOL_TSX_LAYER_LEN : %d", ++ PJSIP_POOL_TSX_LAYER_LEN)); ++ PJ_LOG(3, (id, " PJSIP_POOL_TSX_LAYER_INC : %d", ++ PJSIP_POOL_TSX_LAYER_INC)); ++ PJ_LOG(3, (id, " PJSIP_POOL_TSX_LEN : %d", ++ PJSIP_POOL_TSX_LEN)); ++ PJ_LOG(3, (id, " PJSIP_POOL_TSX_INC : %d", ++ PJSIP_POOL_TSX_INC)); ++ PJ_LOG(3, (id, " PJSIP_TSX_1XX_RETRANS_DELAY : %d", ++ PJSIP_TSX_1XX_RETRANS_DELAY)); ++ PJ_LOG(3, (id, " PJSIP_TSX_UAS_CONTINUE_ON_TP_ERROR : %d", ++ PJSIP_TSX_UAS_CONTINUE_ON_TP_ERROR)); ++ PJ_LOG(3, (id, " PJSIP_MAX_TSX_KEY_LEN : %d", ++ PJSIP_MAX_TSX_KEY_LEN)); ++ PJ_LOG(3, (id, " PJSIP_POOL_LEN_USER_AGENT : %d", ++ PJSIP_POOL_LEN_USER_AGENT)); ++ PJ_LOG(3, (id, " PJSIP_POOL_INC_USER_AGENT : %d", ++ PJSIP_POOL_INC_USER_AGENT)); ++ PJ_LOG(3, (id, " PJSIP_MAX_BRANCH_LEN : %d", ++ PJSIP_MAX_HNAME_LEN)); ++ PJ_LOG(3, (id, " PJSIP_POOL_LEN_DIALOG : %d", ++ PJSIP_POOL_LEN_DIALOG)); ++ PJ_LOG(3, (id, " PJSIP_POOL_INC_DIALOG : %d", ++ PJSIP_POOL_INC_DIALOG)); ++ PJ_LOG(3, (id, " PJSIP_MAX_HEADER_TYPES : %d", ++ PJSIP_MAX_HEADER_TYPES)); ++ PJ_LOG(3, (id, " PJSIP_MAX_URI_TYPES : %d", ++ PJSIP_MAX_URI_TYPES)); ++ PJ_LOG(3, (id, " PJSIP_AUTH_HEADER_CACHING : %d", ++ PJSIP_AUTH_HEADER_CACHING)); ++ PJ_LOG(3, (id, " PJSIP_AUTH_AUTO_SEND_NEXT : %d", ++ PJSIP_AUTH_AUTO_SEND_NEXT)); ++ PJ_LOG(3, (id, " PJSIP_AUTH_QOP_SUPPORT : %d", ++ PJSIP_AUTH_QOP_SUPPORT)); ++ PJ_LOG(3, (id, " PJSIP_MAX_STALE_COUNT : %d", ++ PJSIP_MAX_STALE_COUNT)); ++ PJ_LOG(3, (id, " PJSIP_HAS_DIGEST_AKA_AUTH : %d", ++ PJSIP_HAS_DIGEST_AKA_AUTH)); ++ PJ_LOG(3, (id, " PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH : %d", ++ PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH)); ++ PJ_LOG(3, (id, " PJSIP_REGISTER_ALLOW_EXP_REFRESH : %d", ++ PJSIP_REGISTER_ALLOW_EXP_REFRESH)); ++ PJ_LOG(3, (id, " PJSIP_AUTH_CACHED_POOL_MAX_SIZE : %d", ++ PJSIP_AUTH_CACHED_POOL_MAX_SIZE)); ++ PJ_LOG(3, (id, " PJSIP_AUTH_CNONCE_USE_DIGITS_ONLY : %d", ++ PJSIP_AUTH_CNONCE_USE_DIGITS_ONLY)); ++ PJ_LOG(3, (id, " PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER : %d", ++ PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER)); ++ PJ_LOG(3, (id, " PJSIP_EVSUB_TIME_UAC_REFRESH : %d", ++ PJSIP_EVSUB_TIME_UAC_REFRESH)); ++ PJ_LOG(3, (id, " PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH : %d", ++ PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH)); ++ PJ_LOG(3, (id, " PJSIP_EVSUB_TIME_UAC_TERMINATE : %d", ++ PJSIP_EVSUB_TIME_UAC_TERMINATE)); ++ PJ_LOG(3, (id, " PJSIP_EVSUB_TIME_UAC_WAIT_NOTIFY : %d", ++ PJSIP_EVSUB_TIME_UAC_WAIT_NOTIFY)); ++ PJ_LOG(3, (id, " PJSIP_PRES_DEFAULT_EXPIRES : %d", ++ PJSIP_PRES_DEFAULT_EXPIRES)); ++ PJ_LOG(3, (id, " PJSIP_PRES_BAD_CONTENT_RESPONSE : %d", ++ PJSIP_PRES_BAD_CONTENT_RESPONSE)); ++ PJ_LOG(3, (id, " PJSIP_PRES_PIDF_ADD_TIMESTAMP : %d", ++ PJSIP_PRES_PIDF_ADD_TIMESTAMP)); ++ PJ_LOG(3, (id, " PJSIP_SESS_TIMER_DEF_SE : %d", ++ PJSIP_SESS_TIMER_DEF_SE)); ++ PJ_LOG(3, (id, " PJSIP_SESS_TIMER_RETRY_DELAY : %d", ++ PJSIP_SESS_TIMER_RETRY_DELAY)); ++ PJ_LOG(3, (id, " PJSIP_PUBLISHC_QUEUE_REQUEST : %d", ++ PJSIP_PUBLISHC_QUEUE_REQUEST)); ++ PJ_LOG(3, (id, " PJSIP_MWI_DEFAULT_EXPIRES : %d", ++ PJSIP_MWI_DEFAULT_EXPIRES)); ++ PJ_LOG(3, (id, " PJSIP_HAS_TX_DATA_LIST : %d", ++ PJSIP_HAS_TX_DATA_LIST)); ++ PJ_LOG(3, (id, " PJSIP_INV_ACCEPT_UNKNOWN_BODY : %d", ++ PJSIP_INV_ACCEPT_UNKNOWN_BODY)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.allow_port_in_fromto_hdr : %d", ++ pjsip_cfg()->endpt.allow_port_in_fromto_hdr)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.accept_replace_in_early_state : %d", ++ pjsip_cfg()->endpt.accept_replace_in_early_state)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.allow_tx_hash_in_uri : %d", ++ pjsip_cfg()->endpt.allow_tx_hash_in_uri)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.disable_rport : %d", ++ pjsip_cfg()->endpt.disable_rport)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.disable_tcp_switch : %d", ++ pjsip_cfg()->endpt.disable_tcp_switch)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.disable_tls_switch : %d", ++ pjsip_cfg()->endpt.disable_tls_switch)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.follow_early_media_fork : %d", ++ pjsip_cfg()->endpt.follow_early_media_fork)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.req_has_via_alias : %d", ++ pjsip_cfg()->endpt.req_has_via_alias)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.resolve_hostname_to_get_interface:%d", ++ pjsip_cfg()->endpt.resolve_hostname_to_get_interface)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.disable_secure_dlg_check : %d", ++ pjsip_cfg()->endpt.disable_secure_dlg_check)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.use_compact_form : %d", ++ pjsip_cfg()->endpt.use_compact_form)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.accept_multiple_sdp_answers : %d", ++ pjsip_cfg()->endpt.accept_multiple_sdp_answers)); ++ PJ_LOG(3, (id, " pjsip_cfg()->endpt.keep_inv_after_tsx_timeout : %d", ++ pjsip_cfg()->endpt.keep_inv_after_tsx_timeout)); ++ PJ_LOG(3, (id, " pjsip_cfg()->tsx.max_count : %d", ++ pjsip_cfg()->tsx.max_count)); ++ PJ_LOG(3, (id, " pjsip_cfg()->tsx.t1 : %d", ++ pjsip_cfg()->tsx.t1)); ++ PJ_LOG(3, (id, " pjsip_cfg()->tsx.t2 : %d", ++ pjsip_cfg()->tsx.t2)); ++ PJ_LOG(3, (id, " pjsip_cfg()->tsx.t4 : %d", ++ pjsip_cfg()->tsx.t4)); ++ PJ_LOG(3, (id, " pjsip_cfg()->td : %d", ++ pjsip_cfg()->tsx.td)); ++ PJ_LOG(3, (id, " pjsip_cfg()->regc.check_contact : %d", ++ pjsip_cfg()->regc.check_contact)); ++ PJ_LOG(3, (id, " pjsip_cfg()->regc.add_xuid_param : %d", ++ pjsip_cfg()->regc.add_xuid_param)); ++ PJ_LOG(3, (id, " pjsip_cfg()->tcp.keep_alive_interval : %d", ++ pjsip_cfg()->tcp.keep_alive_interval)); ++ PJ_LOG(3, (id, " pjsip_cfg()->tls.keep_alive_interval : %d", ++ pjsip_cfg()->tls.keep_alive_interval)); ++} ++ + + #ifdef PJ_DLL + PJ_DEF(pjsip_cfg_t*) pjsip_cfg(void) +--- a/pjsip/src/pjsua-lib/pjsua_core.c ++++ b/pjsip/src/pjsua-lib/pjsua_core.c +@@ -3443,8 +3443,10 @@ PJ_DEF(void) pjsua_dump(pj_bool_t detail + old_decor = pj_log_get_decor(); + pj_log_set_decor(old_decor & (PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_CR)); + +- if (detail) ++ if (detail) { + pj_dump_config(); ++ pjsip_dump_config(); ++ } + + pjsip_endpt_dump(pjsua_get_pjsip_endpt(), detail); + +--- a/tests/pjsua/inc_sip.py ++++ b/tests/pjsua/inc_sip.py +@@ -306,9 +306,11 @@ class RecvfromTransaction: + body = None + # Pattern to be expected on pjsua when receiving the response + expect = "" ++ # Required config ++ pj_config = "" + + def __init__(self, title, resp_code, check_cseq=True, +- include=[], exclude=[], cmds=[], resp_hdr=[], resp_body=None, expect=""): ++ include=[], exclude=[], cmds=[], resp_hdr=[], resp_body=None, expect="", pj_config=""): + self.title = title + self.cmds = cmds + self.include = include +@@ -317,6 +319,7 @@ class RecvfromTransaction: + self.resp_hdr = resp_hdr + self.body = resp_body + self.expect = expect ++ self.pj_config=pj_config + + + class RecvfromCfg: +@@ -328,15 +331,18 @@ class RecvfromCfg: + transaction = None + # Use TCP? + tcp = False ++ # Required config ++ pj_config = "" + + # Note: + # Any "$PORT" string in the pjsua_args will be replaced + # by server port +- def __init__(self, name, pjsua_args, transaction, tcp=False): ++ def __init__(self, name, pjsua_args, transaction, tcp=False, pj_config=""): + self.name = name + self.inst_param = cfg.InstanceParam("pjsua", pjsua_args) + self.transaction = transaction + self.tcp=tcp ++ self.pj_config=pj_config + + + +--- a/tests/pjsua/mod_recvfrom.py ++++ b/tests/pjsua/mod_recvfrom.py +@@ -18,10 +18,20 @@ def test_func(test): + local_port=srv_port, + tcp=cfg_file.recvfrom_cfg.tcp) + ++ config = pjsua.get_config(cfg_file.recvfrom_cfg.pj_config) ++ print "Config : " + config ++ + last_cseq = 0 + last_method = "" + last_call_id = "" + for t in cfg_file.recvfrom_cfg.transaction: ++ # Check if transaction requires configuration ++ if t.pj_config != "": ++ r = re.compile(t.pj_config, re.I) ++ if r.search(config) == None: ++ print "Configuration : " + t.pj_config + " not found, skipping" ++ continue ++ + # Print transaction title + if t.title != "": + dlg.trace(t.title) +--- a/tests/pjsua/run.py ++++ b/tests/pjsua/run.py +@@ -249,6 +249,10 @@ class Expect(threading.Thread): + time.sleep(0.01) + return None + ++ def get_config(self, key_config): ++ self.send("dd") ++ line = self.expect(key_config); ++ return line + + def sync_stdout(self): + if not self.use_telnet: +--- a/tests/pjsua/scripts-recvfrom/215_reg_good_multi_ok.py ++++ b/tests/pjsua/scripts-recvfrom/215_reg_good_multi_ok.py +@@ -14,16 +14,27 @@ req1 = sip.RecvfromTransaction("Initial + expect="SIP/2.0 401" + ) + +-req2 = sip.RecvfromTransaction("Registration retry with auth", 200, ++req2 = sip.RecvfromTransaction("Registration retry with auth (not allowed multiple auth)", 200, + include=["REGISTER sip", +- # Must only have 1 Auth hdr since #2887 + "Authorization:", # [\\s\\S]+Authorization:" + "realm=\"python1\"", # "realm=\"python2\"", + "username=\"theuser1\"", # "username=\"theuser2\"", + "nonce=\"1234\"", # "nonce=\"6789\"", + "response="], +- expect="registration success" ++ expect="registration success", ++ pj_config="PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER.*: 0" + ) + ++req3 = sip.RecvfromTransaction("Registration retry with auth (allowed multiple auth)", 200, ++ include=["REGISTER sip", ++ "Authorization:[\\s\\S]+Authorization:", # Must have 2 Auth hdrs ++ "realm=\"python1\"", "realm=\"python2\"", ++ "username=\"theuser1\"", "username=\"theuser2\"", ++ "nonce=\"1234\"", "nonce=\"6789\"", ++ "response="], ++ expect="registration success", ++ pj_config="PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER.*: 1" ++ ) ++ + recvfrom_cfg = sip.RecvfromCfg("Multiple authentication challenges", +- pjsua, [req1, req2]) ++ pjsua, [req1, req2, req3], pj_config="PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER") diff --git a/libs/pjproject/patches/0100-fix-double-stun-free.patch b/libs/pjproject/patches/0100-fix-double-stun-free.patch deleted file mode 100644 index f1691b9..0000000 --- a/libs/pjproject/patches/0100-fix-double-stun-free.patch +++ /dev/null @@ -1,78 +0,0 @@ -commit f0ff5817d0647bdecd1ec99488db9378e304cf83 -Author: sauwming -Date: Mon May 17 09:56:27 2021 +0800 - - Fix double free of stun session (#2709) - ---- 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. */ - ---- 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_dat - 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_dat - /* "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_he - 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/libs/pjproject/patches/0110-tls-parent-listener-destroyed.patch b/libs/pjproject/patches/0110-tls-parent-listener-destroyed.patch deleted file mode 100644 index e496fe4..0000000 --- a/libs/pjproject/patches/0110-tls-parent-listener-destroyed.patch +++ /dev/null @@ -1,162 +0,0 @@ -From bb92c97ea512aa0ef316c9b2335c7d57b84dfc9a Mon Sep 17 00:00:00 2001 -From: Nanang Izzuddin -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(-) - ---- 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(p - - /* 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(p - 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(p - - 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_complet - 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_complet - 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; iparam.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 */ ---- 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_ - 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_ - 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_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/libs/pjproject/patches/0111-ssl-premature-destroy.patch b/libs/pjproject/patches/0111-ssl-premature-destroy.patch deleted file mode 100644 index 3345393..0000000 --- a/libs/pjproject/patches/0111-ssl-premature-destroy.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 68c69f516f95df1faa42e5647e9ce7cfdc41ac38 Mon Sep 17 00:00:00 2001 -From: Nanang Izzuddin -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(-) - ---- a/pjlib/src/pj/ssl_sock_imp_common.c -+++ b/pjlib/src/pj/ssl_sock_imp_common.c -@@ -949,6 +949,7 @@ static pj_bool_t asock_on_accept_complet - - /* 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; -@@ -964,7 +965,7 @@ static pj_bool_t asock_on_accept_complet - 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); - } ---- 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(c - 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( - /* 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 nu - } - - --/* 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, X - 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 *s - 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/libs/pjproject/patches/0120-pjmedia_sdp_attr_get_rtpmap-Strip-param-trailing-whi.patch b/libs/pjproject/patches/0120-pjmedia_sdp_attr_get_rtpmap-Strip-param-trailing-whi.patch deleted file mode 100644 index a3e668c..0000000 --- a/libs/pjproject/patches/0120-pjmedia_sdp_attr_get_rtpmap-Strip-param-trailing-whi.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 2ae784030b0d9cf217c3d562af20e4967f19a3dc Mon Sep 17 00:00:00 2001 -From: George Joseph -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(-) - ---- 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 - - /* 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; - } diff --git a/libs/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch b/libs/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch deleted file mode 100644 index 8db8aab..0000000 --- a/libs/pjproject/patches/0130-sip_inv-Additional-multipart-support-2919-2920.patch +++ /dev/null @@ -1,653 +0,0 @@ -From 0ed41eb5fd0e4192e1b7dc374f819d17aef3e805 Mon Sep 17 00:00:00 2001 -From: George Joseph -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(-) - ---- 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; - - - /** -@@ -1046,6 +1054,44 @@ PJ_DECL(pj_status_t) pjsip_create_sdp_bo - 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 - * this function supports multipart message body. -@@ -1061,6 +1107,60 @@ PJ_DECL(pj_status_t) pjsip_create_sdp_bo - 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 - - /** ---- 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 - 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, -@@ -956,66 +958,170 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uac - return PJ_SUCCESS; - } - --PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata) --{ -- 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; -+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_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; -+} -+ -+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; - -- sdp_info->sdp_err = status; -+ 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. -@@ -1740,13 +1846,55 @@ PJ_DEF(pj_status_t) pjsip_create_sdp_bod - 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); - -@@ -2069,6 +2217,7 @@ static pj_status_t inv_check_sdp_in_inco - ) - ) - { -+ pjsip_sdp_info *tdata_sdp_info; - const pjmedia_sdp_session *reoffer_sdp = NULL; - - PJ_LOG(4,(inv->obj_name, "Received %s response " -@@ -2077,14 +2226,15 @@ static pj_status_t inv_check_sdp_in_inco - (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)); ---- 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_se - } - } - -+ /* 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_ - 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 - 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 - 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 -+ }, - - }; - diff --git a/libs/pjproject/patches/0140-Fix-incorrect-unescaping-of-tokens-during-parsing-29.patch b/libs/pjproject/patches/0140-Fix-incorrect-unescaping-of-tokens-during-parsing-29.patch deleted file mode 100644 index deb9d8c..0000000 --- a/libs/pjproject/patches/0140-Fix-incorrect-unescaping-of-tokens-during-parsing-29.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 3faf1d2b4da553bbaee04f9a13a5d084b381e5fb Mon Sep 17 00:00:00 2001 -From: sauwming -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(-) - ---- 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 - 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 - // 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_sc - 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_v - 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) { ---- 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_hd - - - #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_para - 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_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; diff --git a/libs/pjproject/patches/0150-Create-generic-pjsip_hdr_find-functions.patch b/libs/pjproject/patches/0150-Create-generic-pjsip_hdr_find-functions.patch deleted file mode 100644 index 5979a3b..0000000 --- a/libs/pjproject/patches/0150-Create-generic-pjsip_hdr_find-functions.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 7e3dfd8a15fd0f98dbf0e04d2d7a5bded90ee401 Mon Sep 17 00:00:00 2001 -From: George Joseph -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(-) - ---- a/pjsip/include/pjsip/sip_msg.h -+++ b/pjsip/include/pjsip/sip_msg.h -@@ -363,6 +363,59 @@ PJ_DECL(void*) pjsip_hdr_shallow_clone( - 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); -+ -+/** - * @} - */ - ---- a/pjsip/src/pjsip/sip_msg.c -+++ b/pjsip/src/pjsip/sip_msg.c -@@ -334,13 +334,13 @@ PJ_DEF(pjsip_msg*) pjsip_msg_clone( pj_p - 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) -@@ -349,14 +349,14 @@ PJ_DEF(void*) pjsip_msg_find_hdr( const - 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) -@@ -365,15 +365,15 @@ PJ_DEF(void*) pjsip_msg_find_hdr_by_nam - 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) -@@ -384,6 +384,27 @@ PJ_DEF(void*) pjsip_msg_find_hdr_by_nam - 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) - { diff --git a/libs/pjproject/patches/0160-Additional-multipart-improvements.patch b/libs/pjproject/patches/0160-Additional-multipart-improvements.patch deleted file mode 100644 index 3de67b5..0000000 --- a/libs/pjproject/patches/0160-Additional-multipart-improvements.patch +++ /dev/null @@ -1,635 +0,0 @@ -From b7ecff22e77887626fd8e8608c4dd73bc7b7366f Mon Sep 17 00:00:00 2001 -From: George Joseph -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(-) - ---- a/pjsip/include/pjsip/sip_multipart.h -+++ b/pjsip/include/pjsip/sip_multipart.h -@@ -154,6 +154,89 @@ pjsip_multipart_find_part( const pjsip_m - 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. - * - * @param pool Memory pool. ---- a/pjsip/src/pjsip/sip_multipart.c -+++ b/pjsip/src/pjsip/sip_multipart.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -416,6 +417,220 @@ pjsip_multipart_find_part( const pjsip_m - 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_ - (int)boundary.slen, boundary.ptr)); - } - -+ - /* Build the delimiter: - * delimiter = "--" boundary - */ -@@ -630,6 +846,8 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_ - 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_ - 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_ - 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; - } ---- 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: \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: \r\n" -+ "Content-ID: \r\n" -+ "Content-Length: 13\r\n" -+ "\r\n" -+ "has header2\r\n" -+ "--12345\r\n" -+ "Content-Type: text/plain\r\n" -+ "Content-ID: \r\n" -+ "Content-ID: \r\n" -+ "Content-ID: \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_ - } - } - -+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@example.org"), "has header1"); -+ if (rc) { -+ return (rc - rcbase); -+ } -+ -+ rcbase += 10; -+ rc = verify_cid_str(pool, body, pj_str("%22header1%22@example.org"), "has header1"); -+ if (rc) { -+ return (rc - rcbase); -+ } -+ -+ cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "", -+ strlen(""), 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(""), "has header2"); -+ if (rc) { -+ return (rc - rcbase); -+ } -+ -+ rcbase += 10; -+ rc = verify_cid_str(pool, body, pj_str("cid:my%ffheader2@example.org"), "has header2"); -+ if (rc) { -+ return (rc - rcbase); -+ } -+ -+ cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "", -+ strlen(""), 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@example.org"), "has header4"); -+ if (rc) { -+ return (rc - rcbase); -+ } -+ -+ rcbase += 10; -+ rc = verify_cid_str(pool, body, pj_str(""), "has header4"); -+ if (rc) { -+ return (rc - rcbase); -+ } -+ -+ cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "", -+ strlen(""), 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(""), "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(""), "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@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); diff --git a/libs/pjproject/patches/0170-stun-integer-underflow.patch b/libs/pjproject/patches/0170-stun-integer-underflow.patch deleted file mode 100644 index 519dc81..0000000 --- a/libs/pjproject/patches/0170-stun-integer-underflow.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 15663e3f37091069b8c98a7fce680dc04bc8e865 Mon Sep 17 00:00:00 2001 -From: sauwming -Date: Tue, 10 Aug 2021 11:53:25 +0800 -Subject: [PATCH] Merge pull request from GHSA-2qpg-f6wf-w984 - ---- - pjnath/src/pjnath/stun_msg.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/pjnath/src/pjnath/stun_msg.c -+++ b/pjnath/src/pjnath/stun_msg.c -@@ -1763,6 +1763,9 @@ static pj_status_t decode_errcode_attr(p - /* Get pointer to the string in the message */ - value.ptr = ((char*)buf + ATTR_HDR_LEN + 4); - value.slen = attr->hdr.length - 4; -+ /* Make sure the length is never negative */ -+ if (value.slen < 0) -+ value.slen = 0; - - /* Copy the string to the attribute */ - pj_strdup(pool, &attr->reason, &value); diff --git a/libs/pjproject/patches/0171-dialog-set-free.patch b/libs/pjproject/patches/0171-dialog-set-free.patch deleted file mode 100644 index d113117..0000000 --- a/libs/pjproject/patches/0171-dialog-set-free.patch +++ /dev/null @@ -1,109 +0,0 @@ -From db3235953baa56d2fb0e276ca510fefca751643f Mon Sep 17 00:00:00 2001 -From: Nanang Izzuddin -Date: Mon, 21 Feb 2022 06:24:52 +0700 -Subject: [PATCH] Merge pull request from GHSA-ffff-m5fm-qm62 - -* Update pjsip_ua_unregister_dlg(): -- update the hash key if the dialog being unregistered is used as hash key. -- add an assertion check to make sure that the dlg_set to be removed is valid (can be found in the hash table). - -* Change hash key string comparison method. ---- - pjsip/src/pjsip/sip_ua_layer.c | 48 +++++++++++++++++++++++++++++----- - 1 file changed, 42 insertions(+), 6 deletions(-) - ---- a/pjsip/src/pjsip/sip_ua_layer.c -+++ b/pjsip/src/pjsip/sip_ua_layer.c -@@ -65,6 +65,9 @@ struct dlg_set - /* This is the buffer to store this entry in the hash table. */ - pj_hash_entry_buf ht_entry; - -+ /* Entry key in the hash table */ -+ pj_str_t ht_key; -+ - /* List of dialog in this dialog set. */ - struct dlg_set_head dlg_list; - }; -@@ -321,6 +324,7 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl - * Create the dialog set and add this dialog to it. - */ - dlg_set = alloc_dlgset_node(); -+ dlg_set->ht_key = dlg->local.info->tag; - pj_list_init(&dlg_set->dlg_list); - pj_list_push_back(&dlg_set->dlg_list, dlg); - -@@ -328,8 +332,8 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl - - /* Register the dialog set in the hash table. */ - pj_hash_set_np_lower(mod_ua.dlg_table, -- dlg->local.info->tag.ptr, -- (unsigned)dlg->local.info->tag.slen, -+ dlg_set->ht_key.ptr, -+ (unsigned)dlg_set->ht_key.slen, - dlg->local.tag_hval, dlg_set->ht_entry, - dlg_set); - } -@@ -339,14 +343,15 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl - struct dlg_set *dlg_set; - - dlg_set = alloc_dlgset_node(); -+ dlg_set->ht_key = dlg->local.info->tag; - pj_list_init(&dlg_set->dlg_list); - pj_list_push_back(&dlg_set->dlg_list, dlg); - - dlg->dlg_set = dlg_set; - - pj_hash_set_np_lower(mod_ua.dlg_table, -- dlg->local.info->tag.ptr, -- (unsigned)dlg->local.info->tag.slen, -+ dlg_set->ht_key.ptr, -+ (unsigned)dlg_set->ht_key.slen, - dlg->local.tag_hval, dlg_set->ht_entry, dlg_set); - } - -@@ -391,12 +396,43 @@ PJ_DEF(pj_status_t) pjsip_ua_unregister_ - - /* If dialog list is empty, remove the dialog set from the hash table. */ - if (pj_list_empty(&dlg_set->dlg_list)) { -- pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg->local.info->tag.ptr, -- (unsigned)dlg->local.info->tag.slen, -+ -+ /* Verify that the dialog set is valid */ -+ pj_assert(pj_hash_get_lower(mod_ua.dlg_table, dlg_set->ht_key.ptr, -+ (unsigned)dlg_set->ht_key.slen, -+ &dlg->local.tag_hval) == dlg_set); -+ -+ pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg_set->ht_key.ptr, -+ (unsigned)dlg_set->ht_key.slen, - dlg->local.tag_hval, NULL); - - /* Return dlg_set to free nodes. */ - pj_list_push_back(&mod_ua.free_dlgset_nodes, dlg_set); -+ } else { -+ /* If the just unregistered dialog is being used as hash key, -+ * reset the dlg_set entry with a new key (i.e: from the first dialog -+ * in dlg_set). -+ */ -+ if (dlg_set->ht_key.ptr == dlg->local.info->tag.ptr && -+ dlg_set->ht_key.slen == dlg->local.info->tag.slen) -+ { -+ pjsip_dialog* key_dlg = dlg_set->dlg_list.next; -+ -+ /* Verify that the old & new keys share the hash value */ -+ pj_assert(key_dlg->local.tag_hval == dlg->local.tag_hval); -+ -+ pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg_set->ht_key.ptr, -+ (unsigned)dlg_set->ht_key.slen, -+ dlg->local.tag_hval, NULL); -+ -+ dlg_set->ht_key = key_dlg->local.info->tag; -+ -+ pj_hash_set_np_lower(mod_ua.dlg_table, -+ dlg_set->ht_key.ptr, -+ (unsigned)dlg_set->ht_key.slen, -+ key_dlg->local.tag_hval, dlg_set->ht_entry, -+ dlg_set); -+ } - } - - /* Unlock user agent. */ diff --git a/libs/pjproject/patches/0172-prevent-multipart-oob.patch b/libs/pjproject/patches/0172-prevent-multipart-oob.patch deleted file mode 100644 index d3de936..0000000 --- a/libs/pjproject/patches/0172-prevent-multipart-oob.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 077b465c33f0aec05a49cd2ca456f9a1b112e896 Mon Sep 17 00:00:00 2001 -From: sauwming -Date: Wed, 26 Jan 2022 13:28:57 +0800 -Subject: [PATCH] Merge pull request from GHSA-7fw8-54cv-r7pm - ---- - pjlib-util/src/pjlib-util/scanner.c | 13 +++++++++---- - 1 file changed, 9 insertions(+), 4 deletions(-) - ---- a/pjlib-util/src/pjlib-util/scanner.c -+++ b/pjlib-util/src/pjlib-util/scanner.c -@@ -444,16 +444,21 @@ PJ_DEF(void) pj_scan_get_n( pj_scanner * - - PJ_DEF(int) pj_scan_get_char( pj_scanner *scanner ) - { -- int chr = *scanner->curptr; -+ register char *s = scanner->curptr; -+ int chr; - -- if (!chr) { -+ if (s >= scanner->end || !*s) { - pj_scan_syntax_err(scanner); - return 0; - } - -- ++scanner->curptr; -+ chr = *s; - -- if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) { -+ ++s; -+ scanner->curptr = s; -+ if (PJ_SCAN_CHECK_EOF(s) && PJ_SCAN_IS_PROBABLY_SPACE(*s) && -+ scanner->skip_ws) -+ { - pj_scan_skip_whitespace(scanner); - } - return chr; diff --git a/libs/pjproject/patches/0200-potential-buffer-overflow-in-pjlib-scanner-and-pjmedia.patch b/libs/pjproject/patches/0200-potential-buffer-overflow-in-pjlib-scanner-and-pjmedia.patch new file mode 100644 index 0000000..ebe92b6 --- /dev/null +++ b/libs/pjproject/patches/0200-potential-buffer-overflow-in-pjlib-scanner-and-pjmedia.patch @@ -0,0 +1,297 @@ +From c4d34984ec92b3d5252a7d5cddd85a1d3a8001ae Mon Sep 17 00:00:00 2001 +From: sauwming +Date: Mon, 3 Oct 2022 08:07:22 +0800 +Subject: [PATCH] Merge pull request from GHSA-fq45-m3f7-3mhj + +* Initial patch + +* Use 'pj_scan_is_eof(scanner)' + +Co-authored-by: Aaron Lichtman + +* Use 'pj_scan_is_eof(scanner)' + +Co-authored-by: Aaron Lichtman + +* Use 'pj_scan_is_eof(scanner)' + +Co-authored-by: Aaron Lichtman + +* Use `!pj_scan_is_eof` instead of manually checking `scanner->curptr < scanner->end` + +Co-authored-by: Maksim Mukosey + +* Update pjlib-util/src/pjlib-util/scanner.c + +Co-authored-by: Aaron Lichtman + +* Update pjlib-util/src/pjlib-util/scanner.c + +Co-authored-by: Aaron Lichtman + +* Update pjlib-util/src/pjlib-util/scanner.c + +Co-authored-by: Aaron Lichtman + +* Revert '>=' back to '>' in pj_scan_stricmp_alnum() + +* Fix error compiles. + +Co-authored-by: Nanang Izzuddin +Co-authored-by: Aaron Lichtman +Co-authored-by: Maksim Mukosey +--- + pjlib-util/src/pjlib-util/scanner.c | 41 +++++++++++++++++++---------- + pjmedia/src/pjmedia/rtp.c | 11 +++++--- + pjmedia/src/pjmedia/sdp.c | 24 ++++++++++------- + 3 files changed, 48 insertions(+), 28 deletions(-) + +--- a/pjlib-util/src/pjlib-util/scanner.c ++++ b/pjlib-util/src/pjlib-util/scanner.c +@@ -195,7 +195,13 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj + + PJ_DEF(void) pj_scan_skip_line( pj_scanner *scanner ) + { +- char *s = pj_memchr(scanner->curptr, '\n', scanner->end - scanner->curptr); ++ char *s; ++ ++ if (pj_scan_is_eof(scanner)) { ++ return; ++ } ++ ++ s = pj_memchr(scanner->curptr, '\n', scanner->end - scanner->curptr); + if (!s) { + scanner->curptr = scanner->end; + } else { +@@ -264,8 +270,7 @@ PJ_DEF(void) pj_scan_get( pj_scanner *sc + + pj_assert(pj_cis_match(spec,0)==0); + +- /* EOF is detected implicitly */ +- if (!pj_cis_match(spec, *s)) { ++ if (pj_scan_is_eof(scanner) || !pj_cis_match(spec, *s)) { + pj_scan_syntax_err(scanner); + return; + } +@@ -299,8 +304,7 @@ PJ_DEF(void) pj_scan_get_unescape( pj_sc + /* Must not match character '%' */ + pj_assert(pj_cis_match(spec,'%')==0); + +- /* EOF is detected implicitly */ +- if (!pj_cis_match(spec, *s) && *s != '%') { ++ if (pj_scan_is_eof(scanner) || !pj_cis_match(spec, *s) && *s != '%') { + pj_scan_syntax_err(scanner); + return; + } +@@ -436,7 +440,9 @@ PJ_DEF(void) pj_scan_get_n( pj_scanner * + + scanner->curptr += N; + +- if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) { ++ if (!pj_scan_is_eof(scanner) && ++ PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) ++ { + pj_scan_skip_whitespace(scanner); + } + } +@@ -467,15 +473,16 @@ PJ_DEF(int) pj_scan_get_char( pj_scanner + + PJ_DEF(void) pj_scan_get_newline( pj_scanner *scanner ) + { +- if (!PJ_SCAN_IS_NEWLINE(*scanner->curptr)) { ++ if (pj_scan_is_eof(scanner) || !PJ_SCAN_IS_NEWLINE(*scanner->curptr)) { + pj_scan_syntax_err(scanner); + return; + } + ++ /* We have checked scanner->curptr validity above */ + if (*scanner->curptr == '\r') { + ++scanner->curptr; + } +- if (*scanner->curptr == '\n') { ++ if (!pj_scan_is_eof(scanner) && *scanner->curptr == '\n') { + ++scanner->curptr; + } + +@@ -520,7 +527,9 @@ PJ_DEF(void) pj_scan_get_until( pj_scann + + scanner->curptr = s; + +- if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) { ++ if (!pj_scan_is_eof(scanner) && PJ_SCAN_IS_PROBABLY_SPACE(*s) && ++ scanner->skip_ws) ++ { + pj_scan_skip_whitespace(scanner); + } + } +@@ -544,7 +553,9 @@ PJ_DEF(void) pj_scan_get_until_ch( pj_sc + + scanner->curptr = s; + +- if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) { ++ if (!pj_scan_is_eof(scanner) && PJ_SCAN_IS_PROBABLY_SPACE(*s) && ++ scanner->skip_ws) ++ { + pj_scan_skip_whitespace(scanner); + } + } +@@ -570,7 +581,9 @@ PJ_DEF(void) pj_scan_get_until_chr( pj_s + + scanner->curptr = s; + +- if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) { ++ if (!pj_scan_is_eof(scanner) && PJ_SCAN_IS_PROBABLY_SPACE(*s) && ++ scanner->skip_ws) ++ { + pj_scan_skip_whitespace(scanner); + } + } +@@ -585,7 +598,9 @@ PJ_DEF(void) pj_scan_advance_n( pj_scann + + scanner->curptr += N; + +- if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws) { ++ if (!pj_scan_is_eof(scanner) && ++ PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws) ++ { + pj_scan_skip_whitespace(scanner); + } + } +@@ -636,5 +651,3 @@ PJ_DEF(void) pj_scan_restore_state( pj_s + scanner->line = state->line; + scanner->start_line = state->start_line; + } +- +- +--- a/pjmedia/src/pjmedia/rtp.c ++++ b/pjmedia/src/pjmedia/rtp.c +@@ -188,6 +188,11 @@ PJ_DEF(pj_status_t) pjmedia_rtp_decode_r + /* Payload is located right after header plus CSRC */ + offset = sizeof(pjmedia_rtp_hdr) + ((*hdr)->cc * sizeof(pj_uint32_t)); + ++ /* Check that offset is less than packet size */ ++ if (offset >= pkt_len) { ++ return PJMEDIA_RTP_EINLEN; ++ } ++ + /* Decode RTP extension. */ + if ((*hdr)->x) { + if (offset + sizeof (pjmedia_rtp_ext_hdr) > (unsigned)pkt_len) +@@ -202,8 +207,8 @@ PJ_DEF(pj_status_t) pjmedia_rtp_decode_r + dec_hdr->ext_len = 0; + } + +- /* Check that offset is less than packet size */ +- if (offset > pkt_len) ++ /* Check again that offset is still less than packet size */ ++ if (offset >= pkt_len) + return PJMEDIA_RTP_EINLEN; + + /* Find and set payload. */ +@@ -393,5 +398,3 @@ void pjmedia_rtp_seq_update( pjmedia_rtp + seq_status->status.value = st.status.value; + } + } +- +- +--- a/pjmedia/src/pjmedia/sdp.c ++++ b/pjmedia/src/pjmedia/sdp.c +@@ -983,13 +983,13 @@ static void parse_version(pj_scanner *sc + ctx->last_error = PJMEDIA_SDP_EINVER; + + /* check equal sign */ +- if (*(scanner->curptr+1) != '=') { ++ if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return; + } + + /* check version is 0 */ +- if (*(scanner->curptr+2) != '0') { ++ if (scanner->curptr+2 >= scanner->end || *(scanner->curptr+2) != '0') { + on_scanner_error(scanner); + return; + } +@@ -1006,7 +1006,7 @@ static void parse_origin(pj_scanner *sca + ctx->last_error = PJMEDIA_SDP_EINORIGIN; + + /* check equal sign */ +- if (*(scanner->curptr+1) != '=') { ++ if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return; + } +@@ -1052,7 +1052,7 @@ static void parse_time(pj_scanner *scann + ctx->last_error = PJMEDIA_SDP_EINTIME; + + /* check equal sign */ +- if (*(scanner->curptr+1) != '=') { ++ if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return; + } +@@ -1080,7 +1080,7 @@ static void parse_generic_line(pj_scanne + ctx->last_error = PJMEDIA_SDP_EINSDP; + + /* check equal sign */ +- if (*(scanner->curptr+1) != '=') { ++ if ((scanner->curptr+1 >= scanner->end) || *(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return; + } +@@ -1149,7 +1149,7 @@ static void parse_media(pj_scanner *scan + ctx->last_error = PJMEDIA_SDP_EINMEDIA; + + /* check the equal sign */ +- if (*(scanner->curptr+1) != '=') { ++ if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return; + } +@@ -1164,6 +1164,10 @@ static void parse_media(pj_scanner *scan + /* port */ + pj_scan_get(scanner, &cs_token, &str); + med->desc.port = (unsigned short)pj_strtoul(&str); ++ if (pj_scan_is_eof(scanner)) { ++ on_scanner_error(scanner); ++ return; ++ } + if (*scanner->curptr == '/') { + /* port count */ + pj_scan_get_char(scanner); +@@ -1175,7 +1179,7 @@ static void parse_media(pj_scanner *scan + } + + if (pj_scan_get_char(scanner) != ' ') { +- PJ_THROW(SYNTAX_ERROR); ++ on_scanner_error(scanner); + } + + /* transport */ +@@ -1183,7 +1187,7 @@ static void parse_media(pj_scanner *scan + + /* format list */ + med->desc.fmt_count = 0; +- while (*scanner->curptr == ' ') { ++ while (scanner->curptr < scanner->end && *scanner->curptr == ' ') { + pj_str_t fmt; + + pj_scan_get_char(scanner); +@@ -1223,7 +1227,7 @@ static pjmedia_sdp_attr *parse_attr( pj_ + attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr); + + /* check equal sign */ +- if (*(scanner->curptr+1) != '=') { ++ if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return NULL; + } +@@ -1242,7 +1246,7 @@ static pjmedia_sdp_attr *parse_attr( pj_ + pj_scan_get_char(scanner); + + /* get value */ +- if (*scanner->curptr != '\r' && *scanner->curptr != '\n') { ++ if (!pj_scan_is_eof(scanner) && *scanner->curptr != '\r' && *scanner->curptr != '\n') { + pj_scan_get_until_chr(scanner, "\r\n", &attr->value); + } else { + attr->value.ptr = NULL; diff --git a/libs/pjproject/patches/0201-potential-stack-buffer-overflow-when-parsing-message-as-a-STUN-client.patch b/libs/pjproject/patches/0201-potential-stack-buffer-overflow-when-parsing-message-as-a-STUN-client.patch new file mode 100644 index 0000000..d66b773 --- /dev/null +++ b/libs/pjproject/patches/0201-potential-stack-buffer-overflow-when-parsing-message-as-a-STUN-client.patch @@ -0,0 +1,39 @@ +From 450baca94f475345542c6953832650c390889202 Mon Sep 17 00:00:00 2001 +From: sauwming +Date: Tue, 7 Jun 2022 12:00:13 +0800 +Subject: [PATCH] Merge pull request from GHSA-26j7-ww69-c4qj + +--- + pjlib-util/src/pjlib-util/stun_simple.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/pjlib-util/src/pjlib-util/stun_simple.c ++++ b/pjlib-util/src/pjlib-util/stun_simple.c +@@ -54,6 +54,7 @@ PJ_DEF(pj_status_t) pjstun_parse_msg( vo + { + pj_uint16_t msg_type, msg_len; + char *p_attr; ++ int attr_max_cnt = PJ_ARRAY_SIZE(msg->attr); + + PJ_CHECK_STACK(); + +@@ -83,7 +84,7 @@ PJ_DEF(pj_status_t) pjstun_parse_msg( vo + msg->attr_count = 0; + p_attr = (char*)buf + sizeof(pjstun_msg_hdr); + +- while (msg_len > 0) { ++ while (msg_len > 0 && msg->attr_count < attr_max_cnt) { + pjstun_attr_hdr **attr = &msg->attr[msg->attr_count]; + pj_uint32_t len; + pj_uint16_t attr_type; +@@ -111,6 +112,10 @@ PJ_DEF(pj_status_t) pjstun_parse_msg( vo + p_attr += len; + ++msg->attr_count; + } ++ if (msg->attr_count == attr_max_cnt) { ++ PJ_LOG(4, (THIS_FILE, "Warning: max number attribute %d reached.", ++ attr_max_cnt)); ++ } + + return PJ_SUCCESS; + } -- 2.30.2