pjproject: Update bundled to 2.15.1.

This resolves a security issue where RTP ports weren't being released
causing possible resource exhaustion issues.

Resolves: #GHSA-557q-795j-wfx2
This commit is contained in:
George Joseph
2025-08-25 07:59:04 -06:00
committed by github-actions[bot]
parent 6158cc7b8e
commit 0278f5bde1
40 changed files with 6089 additions and 7764 deletions

8343
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -607,6 +607,7 @@ AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_ENDPOINT_COMPACT_FORM], [PJSIP Compact Form Su
AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_TRANSPORT_DISABLE_CONNECTION_REUSE], [PJSIP Transport Connection Reuse Disabling], [PJPROJECT], [pjsip])
AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_OAUTH_AUTHENTICATION], [PJSIP OAuth Authentication Support], [PJPROJECT], [pjsip])
AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_TLS_TRANSPORT_RESTART], [PJSIP TLS Transport Restart Support], [PJPROJECT], [pjsip])
AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_EVSUB_PENDING_NOTIFY], [PJSIP NOTIFY Required on SUBSCRIBE], [PJPROJECT], [pjsip])
fi
AST_EXT_LIB_SETUP([POPT], [popt], [popt])
@@ -2557,6 +2558,18 @@ if test "$USE_PJPROJECT" != "no" ; then
AST_EXT_LIB_CHECK([PJSIP_AUTH_CLT_DEINIT], [pjsip], [pjsip_auth_clt_deinit], [pjsip.h], [$PJPROJECT_LIB], [$PJPROJECT_CFLAGS])
AST_EXT_LIB_CHECK([PJSIP_TSX_LAYER_FIND_TSX2], [pjsip], [pjsip_tsx_layer_find_tsx2], [pjsip.h], [$PJPROJECT_LIB], [$PJPROJECT_CFLAGS])
AST_EXT_LIB_CHECK([PJSIP_TLS_TRANSPORT_RESTART], [pjsip], [pjsip_tls_transport_restart], [pjsip.h], [$PJPROJECT_LIB], [$PJPROJECT_CFLAGS])
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pending_notify in evsub.c" >&5
$as_echo_n "checking for pending_notify in evsub... " >&6; }
pending_notify=$(${SED} -n -r -e '/^struct\s+pjsip_evsub/,/^\s+void\s+*mod_data/!d ; /pending_notify/p' $(find $PJSIP_EVSUB_PENDING_NOTIFY_DIR -name evsub.c))
if test -n "$pending_notify" ; then
AC_DEFINE(HAVE_PJSIP_EVSUB_PENDING_NOTIFY, 1, [Define to 1 if evsub requires a NOTIFY on SUBSCRIBE.])
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
fi

View File

@@ -19,7 +19,7 @@
of a mutex to its initializer. */
#undef CAN_COMPARE_MUTEX_TO_INIT_VALUE
/* Define to 1 if the `closedir' function returns void instead of int. */
/* Define to 1 if the 'closedir' function returns void instead of int. */
#undef CLOSEDIR_VOID
/* Some configure tests will unexpectedly fail if configure is run by a
@@ -32,10 +32,10 @@
/* Define to 1 if anonymous semaphores work. */
#undef HAS_WORKING_SEMAPHORE
/* Define to 1 if you have the `acos' function. */
/* Define to 1 if you have the 'acos' function. */
#undef HAVE_ACOS
/* Define to 1 if you have the `acosl' function. */
/* Define to 1 if you have the 'acosl' function. */
#undef HAVE_ACOSL
/* Define to 1 if you have 'alloca', as a function or macro. */
@@ -53,31 +53,31 @@
/* Define to 1 if you have the <arpa/nameser.h> header file. */
#undef HAVE_ARPA_NAMESER_H
/* Define to 1 if you have the `asin' function. */
/* Define to 1 if you have the 'asin' function. */
#undef HAVE_ASIN
/* Define to 1 if you have the `asinl' function. */
/* Define to 1 if you have the 'asinl' function. */
#undef HAVE_ASINL
/* Define to 1 if you have the `asprintf' function. */
/* Define to 1 if you have the 'asprintf' function. */
#undef HAVE_ASPRINTF
/* Define to 1 if you have the <assert.h> header file. */
#undef HAVE_ASSERT_H
/* Define to 1 if you have the `atan' function. */
/* Define to 1 if you have the 'atan' function. */
#undef HAVE_ATAN
/* Define to 1 if you have the `atan2' function. */
/* Define to 1 if you have the 'atan2' function. */
#undef HAVE_ATAN2
/* Define to 1 if you have the `atan2l' function. */
/* Define to 1 if you have the 'atan2l' function. */
#undef HAVE_ATAN2L
/* Define to 1 if you have the `atanl' function. */
/* Define to 1 if you have the 'atanl' function. */
#undef HAVE_ATANL
/* Define to 1 if you have the `atexit' function. */
/* Define to 1 if you have the 'atexit' function. */
#undef HAVE_ATEXIT
/* Define to 1 if your GCC C compiler supports the 'always_inline' attribute.
@@ -130,7 +130,7 @@
/* Define to 1 if you have the Bluetooth library. */
#undef HAVE_BLUETOOTH
/* Define to 1 if you have the file `bridges/bridge_softmix/include/hrirs.h'.
/* Define to 1 if you have the file 'bridges/bridge_softmix/include/hrirs.h'.
*/
#undef HAVE_BRIDGES_BRIDGE_SOFTMIX_INCLUDE_HRIRS_H
@@ -140,16 +140,16 @@
/* Define to 1 if you have the POSIX 1.e capabilities library. */
#undef HAVE_CAP
/* Define to 1 if you have the `ceil' function. */
/* Define to 1 if you have the 'ceil' function. */
#undef HAVE_CEIL
/* Define to 1 if you have the `ceill' function. */
/* Define to 1 if you have the 'ceill' function. */
#undef HAVE_CEILL
/* Define to 1 if your system has a working `chown' function. */
/* Define to 1 if your system has a working 'chown' function. */
#undef HAVE_CHOWN
/* Define to 1 if you have the `closefrom' function. */
/* Define to 1 if you have the 'closefrom' function. */
#undef HAVE_CLOSEFROM
/* Define to 1 if you have the Codec 2 Audio Decoder/Encoder library. */
@@ -161,10 +161,10 @@
/* Define to 1 if COROSYNC has the A callback only in corosync 1.x feature. */
#undef HAVE_COROSYNC_CFG_STATE_TRACK
/* Define to 1 if you have the `cos' function. */
/* Define to 1 if you have the 'cos' function. */
#undef HAVE_COS
/* Define to 1 if you have the `cosl' function. */
/* Define to 1 if you have the 'cosl' function. */
#undef HAVE_COSL
/* Define to 1 if you have the 'crypt' function. */
@@ -200,11 +200,11 @@
/* Define DAHDI headers version */
#undef HAVE_DAHDI_VERSION
/* Define to 1 if you have the declaration of `gethostbyname_r', and to 0 if
/* Define to 1 if you have the declaration of 'gethostbyname_r', and to 0 if
you don't. */
#undef HAVE_DECL_GETHOSTBYNAME_R
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
/* Define to 1 if you have the <dirent.h> header file, and it defines 'DIR'.
*/
#undef HAVE_DIRENT_H
@@ -214,44 +214,44 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
/* Define to 1 if you don't have 'vprintf' but do have '_doprnt.' */
#undef HAVE_DOPRNT
/* Define to 1 if you have the `dup2' function. */
/* Define to 1 if you have the 'dup2' function. */
#undef HAVE_DUP2
/* Define to 1 if you have the `eaccess' function. */
/* Define to 1 if you have the 'eaccess' function. */
#undef HAVE_EACCESS
/* Define to 1 if you have the `endpwent' function. */
/* Define to 1 if you have the 'endpwent' function. */
#undef HAVE_ENDPWENT
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the `euidaccess' function. */
/* Define to 1 if you have the 'euidaccess' function. */
#undef HAVE_EUIDACCESS
/* Define to 1 if your system supports eventfd and the EFD_NONBLOCK and
EFD_SEMAPHORE flags. */
#undef HAVE_EVENTFD
/* Define to 1 if you have the `exp' function. */
/* Define to 1 if you have the 'exp' function. */
#undef HAVE_EXP
/* Define to 1 if you have the `exp10' function. */
/* Define to 1 if you have the 'exp10' function. */
#undef HAVE_EXP10
/* Define to 1 if you have the `exp10l' function. */
/* Define to 1 if you have the 'exp10l' function. */
#undef HAVE_EXP10L
/* Define to 1 if you have the `exp2' function. */
/* Define to 1 if you have the 'exp2' function. */
#undef HAVE_EXP2
/* Define to 1 if you have the `exp2l' function. */
/* Define to 1 if you have the 'exp2l' function. */
#undef HAVE_EXP2L
/* Define to 1 if you have the `expl' function. */
/* Define to 1 if you have the 'expl' function. */
#undef HAVE_EXPL
/* Define to 1 if you have the <fcntl.h> header file. */
@@ -260,7 +260,7 @@
/* Define to 1 if you have the Ffmpeg and avcodec library. */
#undef HAVE_FFMPEG
/* Define to 1 if you have the `ffsll' function. */
/* Define to 1 if you have the 'ffsll' function. */
#undef HAVE_FFSLL
/* Define to 1 if you have the LIBFFTW3 library. */
@@ -269,37 +269,37 @@
/* Define to 1 if you have the <float.h> header file. */
#undef HAVE_FLOAT_H
/* Define to 1 if you have the `floor' function. */
/* Define to 1 if you have the 'floor' function. */
#undef HAVE_FLOOR
/* Define to 1 if you have the `floorl' function. */
/* Define to 1 if you have the 'floorl' function. */
#undef HAVE_FLOORL
/* Define to 1 if you have the `fmod' function. */
/* Define to 1 if you have the 'fmod' function. */
#undef HAVE_FMOD
/* Define to 1 if you have the `fmodl' function. */
/* Define to 1 if you have the 'fmodl' function. */
#undef HAVE_FMODL
/* Define to 1 if you have the `fork' function. */
/* Define to 1 if you have the 'fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the FreeTDS library. */
#undef HAVE_FREETDS
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
/* Define to 1 if fseeko (and ftello) are declared in stdio.h. */
#undef HAVE_FSEEKO
/* Define to 1 if you have the `ftruncate' function. */
/* Define to 1 if you have the 'ftruncate' function. */
#undef HAVE_FTRUNCATE
/* Define to 1 if your GCC C compiler provides __sync atomic operations. */
#undef HAVE_GCC_ATOMICS
/* Define to 1 if you have the `getcwd' function. */
/* Define to 1 if you have the 'getcwd' function. */
#undef HAVE_GETCWD
/* Define to 1 if you have the `gethostbyname' function. */
/* Define to 1 if you have the 'gethostbyname' function. */
#undef HAVE_GETHOSTBYNAME
/* Define to 1 if your system has gethostbyname_r with 5 arguments. */
@@ -308,25 +308,25 @@
/* Define to 1 if your system has gethostbyname_r with 6 arguments. */
#undef HAVE_GETHOSTBYNAME_R_6
/* Define to 1 if you have the `gethostname' function. */
/* Define to 1 if you have the 'gethostname' function. */
#undef HAVE_GETHOSTNAME
/* Define if your system has the GETIFADDRS headers. */
#undef HAVE_GETIFADDRS
/* Define to 1 if you have the `getloadavg' function. */
/* Define to 1 if you have the 'getloadavg' function. */
#undef HAVE_GETLOADAVG
/* Define to 1 if you have the `getpagesize' function. */
/* Define to 1 if you have the 'getpagesize' function. */
#undef HAVE_GETPAGESIZE
/* Define to 1 if you have the `getpeereid' function. */
/* Define to 1 if you have the 'getpeereid' function. */
#undef HAVE_GETPEEREID
/* Define to 1 if you have the `gettimeofday' function. */
/* Define to 1 if you have the 'gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the `glob' function. */
/* Define to 1 if you have the 'glob' function. */
#undef HAVE_GLOB
/* Define if your system has the GLOB_BRACE headers. */
@@ -378,10 +378,10 @@
or greater. */
#undef HAVE_IMAP_TK2006
/* Define to 1 if you have the `inet_aton' function. */
/* Define to 1 if you have the 'inet_aton' function. */
#undef HAVE_INET_ATON
/* Define to 1 if you have the `inet_ntoa' function. */
/* Define to 1 if you have the 'inet_ntoa' function. */
#undef HAVE_INET_NTOA
/* Define to 1 if you have the inotify support library. */
@@ -393,13 +393,13 @@
/* Define to 1 if you have the iODBC library. */
#undef HAVE_IODBC
/* Define to 1 if you have the `ioperm' function. */
/* Define to 1 if you have the 'ioperm' function. */
#undef HAVE_IOPERM
/* Define if your system has the IP_MTU_DISCOVER headers. */
#undef HAVE_IP_MTU_DISCOVER
/* Define to 1 if you have the `isascii' function. */
/* Define to 1 if you have the 'isascii' function. */
#undef HAVE_ISASCII
/* Define to 1 if you have the ISDN4Linux library. */
@@ -414,7 +414,7 @@
/* Define if your system has JANSSON_BUNDLED */
#undef HAVE_JANSSON_BUNDLED
/* Define to 1 if you have the `kevent64' function. */
/* Define to 1 if you have the 'kevent64' function. */
#undef HAVE_KEVENT64
/* Define to 1 if you have the kqueue support library. */
@@ -438,7 +438,7 @@
/* Define if your system has LIBJWT_BUNDLED */
#undef HAVE_LIBJWT_BUNDLED
/* Define to 1 if you have the `m' library (-lm). */
/* Define to 1 if you have the 'm' library (-lm). */
#undef HAVE_LIBM
/* Define if your system has the LIBXML2 libraries. */
@@ -468,26 +468,26 @@
/* Define to 1 if your system defines the locale_t type in xlocale.h */
#undef HAVE_LOCALE_T_IN_XLOCALE_H
/* Define to 1 if you have the `log' function. */
/* Define to 1 if you have the 'log' function. */
#undef HAVE_LOG
/* Define to 1 if you have the `log10' function. */
/* Define to 1 if you have the 'log10' function. */
#undef HAVE_LOG10
/* Define to 1 if you have the `log10l' function. */
/* Define to 1 if you have the 'log10l' function. */
#undef HAVE_LOG10L
/* Define to 1 if you have the `log2' function. */
/* Define to 1 if you have the 'log2' function. */
#undef HAVE_LOG2
/* Define to 1 if you have the `log2l' function. */
/* Define to 1 if you have the 'log2l' function. */
#undef HAVE_LOG2L
/* Define to 1 if you have the `logl' function. */
/* Define to 1 if you have the 'logl' function. */
#undef HAVE_LOGL
/* Define to 1 if the type `long double' works and has more range or precision
than `double'. */
/* Define to 1 if the type 'long double' works and has more range or precision
than 'double'. */
#undef HAVE_LONG_DOUBLE_WIDER
/* Define to 1 if you have the Lua library. */
@@ -496,19 +496,19 @@
/* Define to 1 if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define to 1 if you have the `malloc_trim' function. */
/* Define to 1 if you have the 'malloc_trim' function. */
#undef HAVE_MALLOC_TRIM
/* Define to 1 if you have the <math.h> header file. */
#undef HAVE_MATH_H
/* Define to 1 if you have the `memchr' function. */
/* Define to 1 if you have the 'memchr' function. */
#undef HAVE_MEMCHR
/* Define to 1 if you have the `memmove' function. */
/* Define to 1 if you have the 'memmove' function. */
#undef HAVE_MEMMOVE
/* Define to 1 if you have the `memset' function. */
/* Define to 1 if you have the 'memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the <minix/config.h> header file. */
@@ -523,19 +523,19 @@
/* Define if your system has the MISDN_FAC_RESULT headers. */
#undef HAVE_MISDN_FAC_RESULT
/* Define to 1 if you have the `mkdir' function. */
/* Define to 1 if you have the 'mkdir' function. */
#undef HAVE_MKDIR
/* Define to 1 if you have the `mkdtemp' function. */
/* Define to 1 if you have the 'mkdtemp' function. */
#undef HAVE_MKDTEMP
/* Define to 1 if you have a working `mmap' system call. */
/* Define to 1 if you have a working 'mmap' system call. */
#undef HAVE_MMAP
/* Define if your system has the MSG_NOSIGNAL headers. */
#undef HAVE_MSG_NOSIGNAL
/* Define to 1 if you have the `munmap' function. */
/* Define to 1 if you have the 'munmap' function. */
#undef HAVE_MUNMAP
/* Define if your system has the MYSQLCLIENT libraries. */
@@ -550,7 +550,7 @@
/* Define to 1 if you have the Network Broadcast Sound library. */
#undef HAVE_NBS
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* Define to 1 if you have the <ndir.h> header file, and it defines 'DIR'. */
#undef HAVE_NDIR_H
/* Define if your system has the NEON libraries. */
@@ -568,7 +568,7 @@
/* Define if your system has the NETSNMP libraries. */
#undef HAVE_NETSNMP
/* Define to 1 if you have the `newlocale' function. */
/* Define to 1 if you have the 'newlocale' function. */
#undef HAVE_NEWLOCALE
/* Define to 1 if you have the newt library. */
@@ -622,7 +622,7 @@
/* Define to indicate presence of the pg_encoding_to_char API. */
#undef HAVE_PGSQL_pg_encoding_to_char
/* Define to 1 if you have the `pipe2' function. */
/* Define to 1 if you have the 'pipe2' function. */
#undef HAVE_PIPE2
/* Define if your system has the PJPROJECT libraries. */
@@ -631,9 +631,6 @@
/* Define if your system has PJPROJECT_BUNDLED */
#undef HAVE_PJPROJECT_BUNDLED
/* Define if doing a bundled pjproject out-of-tree build. */
#undef HAVE_PJPROJECT_BUNDLED_OOT
/* Define to 1 if on_valid_pair callback is present. */
#undef HAVE_PJPROJECT_ON_VALID_ICE_PAIR_CALLBACK
@@ -650,6 +647,9 @@
/* Define to 1 if PJPROJECT has the PJSIP EVSUB Group Lock support feature. */
#undef HAVE_PJSIP_EVSUB_GRP_LOCK
/* Define to 1 if evsub requires a NOTIFY on SUBSCRIBE. */
#undef HAVE_PJSIP_EVSUB_PENDING_NOTIFY
/* Define to 1 if PJPROJECT has the PJSIP External Resolver Support feature.
*/
#undef HAVE_PJSIP_EXTERNAL_RESOLVER
@@ -712,13 +712,13 @@
/* Define if your system has the PORTAUDIO libraries. */
#undef HAVE_PORTAUDIO
/* Define to 1 if you have the `pow' function. */
/* Define to 1 if you have the 'pow' function. */
#undef HAVE_POW
/* Define to 1 if you have the `powl' function. */
/* Define to 1 if you have the 'powl' function. */
#undef HAVE_POWL
/* Define to 1 if you have the `ppoll' function. */
/* Define to 1 if you have the 'ppoll' function. */
#undef HAVE_PPOLL
/* Define to 1 if you have the ISDN PRI library. */
@@ -823,10 +823,10 @@
/* Define to 1 if your system has pthread_spinlock_t in pthread.h */
#undef HAVE_PTHREAD_SPINLOCK
/* Define to 1 if the system has the type `ptrdiff_t'. */
/* Define to 1 if the system has the type 'ptrdiff_t'. */
#undef HAVE_PTRDIFF_T
/* Define to 1 if you have the `putenv' function. */
/* Define to 1 if you have the 'putenv' function. */
#undef HAVE_PUTENV
/* Define to 1 if you have the <pwd.h> header file. */
@@ -838,16 +838,16 @@
/* Define to 1 if you have the Radius Client library. */
#undef HAVE_RADIUS
/* Define to 1 if you have the `regcomp' function. */
/* Define to 1 if you have the 'regcomp' function. */
#undef HAVE_REGCOMP
/* Define to 1 if you have the <regex.h> header file. */
#undef HAVE_REGEX_H
/* Define to 1 if you have the `remainder' function. */
/* Define to 1 if you have the 'remainder' function. */
#undef HAVE_REMAINDER
/* Define to 1 if you have the `remainderl' function. */
/* Define to 1 if you have the 'remainderl' function. */
#undef HAVE_REMAINDERL
/* Define to 1 if you have the LIBRESAMPLE library. */
@@ -865,22 +865,22 @@
/* Define to 1 if your system has the re-entrant resolver functions. */
#undef HAVE_RES_NINIT
/* Define to 1 if you have the `re_comp' function. */
/* Define to 1 if you have the 're_comp' function. */
#undef HAVE_RE_COMP
/* Define to 1 if you have the `rint' function. */
/* Define to 1 if you have the 'rint' function. */
#undef HAVE_RINT
/* Define to 1 if you have the `rintl' function. */
/* Define to 1 if you have the 'rintl' function. */
#undef HAVE_RINTL
/* Define to 1 if you have the `round' function. */
/* Define to 1 if you have the 'round' function. */
#undef HAVE_ROUND
/* Define to 1 if you have the `roundf' function. */
/* Define to 1 if you have the 'roundf' function. */
#undef HAVE_ROUNDF
/* Define to 1 if you have the `roundl' function. */
/* Define to 1 if you have the 'roundl' function. */
#undef HAVE_ROUNDL
/* Define to 1 if rt has the Realtime functions feature. */
@@ -901,22 +901,22 @@
/* Define to 1 if you have the Sdl Image library. */
#undef HAVE_SDL_IMAGE
/* Define to 1 if you have the `select' function. */
/* Define to 1 if you have the 'select' function. */
#undef HAVE_SELECT
/* Define to 1 if you have the `setenv' function. */
/* Define to 1 if you have the 'setenv' function. */
#undef HAVE_SETENV
/* Define to 1 if you have the `sin' function. */
/* Define to 1 if you have the 'sin' function. */
#undef HAVE_SIN
/* Define to 1 if you have the `sinl' function. */
/* Define to 1 if you have the 'sinl' function. */
#undef HAVE_SINL
/* Define to 1 if you have the libsndfile library. */
#undef HAVE_SNDFILE
/* Define to 1 if you have the `socket' function. */
/* Define to 1 if you have the 'socket' function. */
#undef HAVE_SOCKET
/* Define to 1 if your socket() implementation can accept SOCK_NONBLOCK. */
@@ -946,7 +946,7 @@
/* Define to 1 if you have the SQLite library. */
#undef HAVE_SQLITE3
/* Define to 1 if you have the `sqrtl' function. */
/* Define to 1 if you have the 'sqrtl' function. */
#undef HAVE_SQRTL
/* Define to 1 if you have the Secure RTP library. */
@@ -974,7 +974,7 @@
/* Define to 1 if you have the ISDN SS7 library. */
#undef HAVE_SS7
/* Define to 1 if `stat' has the bug that it succeeds when given the
/* Define to 1 if 'stat' has the bug that it succeeds when given the
zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
@@ -996,29 +996,29 @@
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strcasecmp' function. */
/* Define to 1 if you have the 'strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define to 1 if you have the `strcasestr' function. */
/* Define to 1 if you have the 'strcasestr' function. */
#undef HAVE_STRCASESTR
/* Define to 1 if you have the `strchr' function. */
/* Define to 1 if you have the 'strchr' function. */
#undef HAVE_STRCHR
/* Define to 1 if you have the `strcoll' function and it is properly defined.
/* Define to 1 if you have the 'strcoll' function and it is properly defined.
*/
#undef HAVE_STRCOLL
/* Define to 1 if you have the `strcspn' function. */
/* Define to 1 if you have the 'strcspn' function. */
#undef HAVE_STRCSPN
/* Define to 1 if you have the `strdup' function. */
/* Define to 1 if you have the 'strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
/* Define to 1 if you have the 'strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the `strftime' function. */
/* Define to 1 if you have the 'strftime' function. */
#undef HAVE_STRFTIME
/* Define to 1 if you have the <strings.h> header file. */
@@ -1027,79 +1027,79 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcat' function. */
/* Define to 1 if you have the 'strlcat' function. */
#undef HAVE_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
/* Define to 1 if you have the 'strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the `strncasecmp' function. */
/* Define to 1 if you have the 'strncasecmp' function. */
#undef HAVE_STRNCASECMP
/* Define to 1 if you have the `strndup' function. */
/* Define to 1 if you have the 'strndup' function. */
#undef HAVE_STRNDUP
/* Define to 1 if you have the `strnlen' function. */
/* Define to 1 if you have the 'strnlen' function. */
#undef HAVE_STRNLEN
/* Define to 1 if you have the `strrchr' function. */
/* Define to 1 if you have the 'strrchr' function. */
#undef HAVE_STRRCHR
/* Define to 1 if you have the `strsep' function. */
/* Define to 1 if you have the 'strsep' function. */
#undef HAVE_STRSEP
/* Define to 1 if you have the `strspn' function. */
/* Define to 1 if you have the 'strspn' function. */
#undef HAVE_STRSPN
/* Define to 1 if you have the `strstr' function. */
/* Define to 1 if you have the 'strstr' function. */
#undef HAVE_STRSTR
/* Define to 1 if you have the `strtod' function. */
/* Define to 1 if you have the 'strtod' function. */
#undef HAVE_STRTOD
/* Define to 1 if you have the `strtol' function. */
/* Define to 1 if you have the 'strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if you have the `strtold' function. */
/* Define to 1 if you have the 'strtold' function. */
#undef HAVE_STRTOLD
/* Define to 1 if you have the `strtoq' function. */
/* Define to 1 if you have the 'strtoq' function. */
#undef HAVE_STRTOQ
/* Define to 1 if `ifr_ifru.ifru_hwaddr' is a member of `struct ifreq'. */
/* Define to 1 if 'ifr_ifru.ifru_hwaddr' is a member of 'struct ifreq'. */
#undef HAVE_STRUCT_IFREQ_IFR_IFRU_IFRU_HWADDR
/* Define to 1 if `uid' is a member of `struct sockpeercred'. */
/* Define to 1 if 'uid' is a member of 'struct sockpeercred'. */
#undef HAVE_STRUCT_SOCKPEERCRED_UID
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
/* Define to 1 if 'st_blksize' is a member of 'struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLKSIZE
/* Define to 1 if `st_mtim' is a member of `struct stat'. */
/* Define to 1 if 'st_mtim' is a member of 'struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIM
/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
/* Define to 1 if 'st_mtimensec' is a member of 'struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
/* Define to 1 if `st_mtimespec' is a member of `struct stat'. */
/* Define to 1 if 'st_mtimespec' is a member of 'struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIMESPEC
/* Define to 1 if `cr_uid' is a member of `struct ucred'. */
/* Define to 1 if 'cr_uid' is a member of 'struct ucred'. */
#undef HAVE_STRUCT_UCRED_CR_UID
/* Define to 1 if `uid' is a member of `struct ucred'. */
/* Define to 1 if 'uid' is a member of 'struct ucred'. */
#undef HAVE_STRUCT_UCRED_UID
/* Define to 1 if `_u._ext.nsaddrs' is a member of `struct __res_state'. */
/* Define to 1 if '_u._ext.nsaddrs' is a member of 'struct __res_state'. */
#undef HAVE_STRUCT___RES_STATE__U__EXT_NSADDRS
/* Define to 1 if you have the mISDN Supplemental Services library. */
#undef HAVE_SUPPSERV
/* Define to 1 if you have the `swapctl' function. */
/* Define to 1 if you have the 'swapctl' function. */
#undef HAVE_SWAPCTL
/* Define to 1 if you have the `sysctl' function. */
/* Define to 1 if you have the 'sysctl' function. */
#undef HAVE_SYSCTL
/* Define to 1 if your system has sysinfo support */
@@ -1144,7 +1144,7 @@
/* Define if your system has the SYSTEMD libraries. */
#undef HAVE_SYSTEMD
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
/* Define to 1 if you have the <sys/dir.h> header file, and it defines 'DIR'.
*/
#undef HAVE_SYS_DIR_H
@@ -1164,7 +1164,7 @@
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines 'DIR'.
*/
#undef HAVE_SYS_NDIR_H
@@ -1198,10 +1198,10 @@
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the `tan' function. */
/* Define to 1 if you have the 'tan' function. */
#undef HAVE_TAN
/* Define to 1 if you have the `tanl' function. */
/* Define to 1 if you have the 'tanl' function. */
#undef HAVE_TANL
/* Define to 1 if you have the <termios.h> header file. */
@@ -1219,10 +1219,10 @@
/* Define to 1 if you have the tonezone library. */
#undef HAVE_TONEZONE
/* Define to 1 if you have the `trunc' function. */
/* Define to 1 if you have the 'trunc' function. */
#undef HAVE_TRUNC
/* Define to 1 if you have the `truncl' function. */
/* Define to 1 if you have the 'truncl' function. */
#undef HAVE_TRUNCL
/* Define to 1 if you have the unbound library. */
@@ -1234,35 +1234,35 @@
/* Define to 1 if you have the unixODBC library. */
#undef HAVE_UNIXODBC
/* Define to 1 if you have the `unsetenv' function. */
/* Define to 1 if you have the 'unsetenv' function. */
#undef HAVE_UNSETENV
/* Define to 1 if you have the uriparser library library. */
#undef HAVE_URIPARSER
/* Define to 1 if you have the `uselocale' function. */
/* Define to 1 if you have the 'uselocale' function. */
#undef HAVE_USELOCALE
/* Define to 1 if you have the `utime' function. */
/* Define to 1 if you have the 'utime' function. */
#undef HAVE_UTIME
/* Define to 1 if you have the <utime.h> header file. */
#undef HAVE_UTIME_H
/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */
/* Define to 1 if 'utime(file, NULL)' sets file's timestamp to the present. */
#undef HAVE_UTIME_NULL
/* Define to 1 if you have the `uuid_generate_random' function. */
/* Define to 1 if you have the 'uuid_generate_random' function. */
#undef HAVE_UUID_GENERATE_RANDOM
/* Define to 1 if your system can support larger than default select bitmasks.
*/
#undef HAVE_VARIABLE_FDSET
/* Define to 1 if you have the `vasprintf' function. */
/* Define to 1 if you have the 'vasprintf' function. */
#undef HAVE_VASPRINTF
/* Define to 1 if you have the `vfork' function. */
/* Define to 1 if you have the 'vfork' function. */
#undef HAVE_VFORK
/* Define to 1 if you have the <vfork.h> header file. */
@@ -1280,7 +1280,7 @@
/* Define if your system has the VoiceTronix API libraries. */
#undef HAVE_VPB
/* Define to 1 if you have the `vprintf' function. */
/* Define to 1 if you have the 'vprintf' function. */
#undef HAVE_VPRINTF
/* Define to 1 if you have the <wchar.h> header file. */
@@ -1310,7 +1310,7 @@
/* Define to 1 if you have the zlib compression library. */
#undef HAVE_ZLIB
/* Define to 1 if the system has the type `_Bool'. */
/* Define to 1 if the system has the type '_Bool'. */
#undef HAVE__BOOL
/* Defined if libcurl supports AsynchDNS */
@@ -1376,7 +1376,7 @@
/* Defined if libcurl supports TFTP */
#undef LIBCURL_PROTOCOL_TFTP
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
/* Define to 1 if 'lstat' dereferences a symlink specified with a trailing
slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
@@ -1411,28 +1411,28 @@
/* Name of RADIUS library include header */
#undef RADIUS_HEADER_STR
/* Define to the type of arg 1 for `select'. */
/* Define to the type of arg 1 for 'select'. */
#undef SELECT_TYPE_ARG1
/* Define to the type of args 2, 3 and 4 for `select'. */
/* Define to the type of args 2, 3 and 4 for 'select'. */
#undef SELECT_TYPE_ARG234
/* Define to the type of arg 5 for `select'. */
/* Define to the type of arg 5 for 'select'. */
#undef SELECT_TYPE_ARG5
/* The size of `char *', as computed by sizeof. */
/* The size of 'char *', as computed by sizeof. */
#undef SIZEOF_CHAR_P
/* The size of `fd_set.fds_bits', as computed by sizeof. */
/* The size of 'fd_set.fds_bits', as computed by sizeof. */
#undef SIZEOF_FD_SET_FDS_BITS
/* The size of `int', as computed by sizeof. */
/* The size of 'int', as computed by sizeof. */
#undef SIZEOF_INT
/* The size of `long', as computed by sizeof. */
/* The size of 'long', as computed by sizeof. */
#undef SIZEOF_LONG
/* The size of `long long', as computed by sizeof. */
/* The size of 'long long', as computed by sizeof. */
#undef SIZEOF_LONG_LONG
/* If using the C implementation of alloca, define if you know the
@@ -1443,18 +1443,18 @@
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if all of the C90 standard headers exist (not just the ones
/* Define to 1 if all of the C89 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* Define to 1 if your <sys/time.h> declares 'struct tm'. */
#undef TM_IN_SYS_TIME
/* Define to a type of the same size as fd_set.fds_bits[[0]] */
#undef TYPEOF_FD_SET_FDS_BITS
/* Enable extensions on AIX 3, Interix. */
/* Enable extensions on AIX, Interix, z/OS. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
@@ -1515,11 +1515,15 @@
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
# undef __STDC_WANT_IEC_60559_DFP_EXT__
#endif
/* Enable extensions specified by C23 Annex F. */
#ifndef __STDC_WANT_IEC_60559_EXT__
# undef __STDC_WANT_IEC_60559_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
#endif
@@ -1556,47 +1560,53 @@
*/
#undef _HAVE_STRING_ARCH_strsep
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
/* Define to 1 if necessary to make fseeko visible. */
#undef _LARGEFILE_SOURCE
/* Define for large files, on AIX-style hosts. */
/* Define to 1 on platforms where this makes off_t a 64-bit type. */
#undef _LARGE_FILES
/* Define to empty if `const' does not conform to ANSI C. */
/* Number of bits in time_t, on hosts where this is settable. */
#undef _TIME_BITS
/* Define to 1 on platforms where this makes time_t a 64-bit type. */
#undef __MINGW_USE_VC2005_COMPAT
/* Define to empty if 'const' does not conform to ANSI C. */
#undef const
/* Define curl_free() as free() if our version of curl lacks curl_free. */
#undef curl_free
/* Define to `int' if <sys/types.h> doesn't define. */
/* Define as 'int' if <sys/types.h> doesn't define. */
#undef gid_t
/* Define to `__inline__' or `__inline' if that's what the C compiler
/* Define to '__inline__' or '__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `int' if <sys/types.h> does not define. */
/* Define to 'int' if <sys/types.h> does not define. */
#undef mode_t
/* Define to `long int' if <sys/types.h> does not define. */
/* Define to 'long int' if <sys/types.h> does not define. */
#undef off_t
/* Define as a signed integer type capable of holding a process identifier. */
#undef pid_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* Define as 'unsigned int' if <stddef.h> doesn't define. */
#undef size_t
/* Define to `int' if <sys/types.h> doesn't define. */
/* Define as 'int' if <sys/types.h> doesn't define. */
#undef uid_t
/* Define as `fork' if `vfork' does not work. */
#undef vfork
/* Define to empty if the keyword `volatile' does not work. Warning: valid
code using `volatile' can become incorrect without. Disable with care. */
/* Define to empty if the keyword 'volatile' does not work. Warning: valid
code using 'volatile' can become incorrect without. Disable with care. */
#undef volatile
#endif /* ASTERISK_AUTOCONFIG_H */

View File

@@ -4,28 +4,22 @@
#define MENUSELECT_AUTOCONFIG_H
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
#undef CRAY_STACKSEG_END
/* Define to 1 if using `alloca.c'. */
/* Define to 1 if using 'alloca.c'. */
#undef C_ALLOCA
/* Define to 1 if you have `alloca', as a function or macro. */
/* Define to 1 if you have 'alloca', as a function or macro. */
#undef HAVE_ALLOCA
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
/* Define to 1 if <alloca.h> works. */
#undef HAVE_ALLOCA_H
/* Define to 1 if you have the `asprintf' function. */
/* Define to 1 if you have the 'asprintf' function. */
#undef HAVE_ASPRINTF
/* Define to 1 if you have the curses library. */
#undef HAVE_CURSES
/* Define to 1 if you have the `getloadavg' function. */
/* Define to 1 if you have the 'getloadavg' function. */
#undef HAVE_GETLOADAVG
/* Define if your system has the GTK2 libraries. */
@@ -37,25 +31,25 @@
/* Define if your system has the LIBXML2 libraries. */
#undef HAVE_LIBXML2
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the ncurses library. */
#undef HAVE_NCURSES
/* Define to 1 if you have the newt library. */
#undef HAVE_NEWT
/* Define to 1 if you have the `setenv' function. */
/* Define to 1 if you have the 'setenv' function. */
#undef HAVE_SETENV
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strcasestr' function. */
/* Define to 1 if you have the 'strcasestr' function. */
#undef HAVE_STRCASESTR
/* Define to 1 if you have the <strings.h> header file. */
@@ -64,13 +58,13 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strndup' function. */
/* Define to 1 if you have the 'strndup' function. */
#undef HAVE_STRNDUP
/* Define to 1 if you have the `strnlen' function. */
/* Define to 1 if you have the 'strnlen' function. */
#undef HAVE_STRNLEN
/* Define to 1 if you have the `strsep' function. */
/* Define to 1 if you have the 'strsep' function. */
#undef HAVE_STRSEP
/* Define to 1 if you have the <sys/stat.h> header file. */
@@ -85,10 +79,10 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `unsetenv' function. */
/* Define to 1 if you have the 'unsetenv' function. */
#undef HAVE_UNSETENV
/* Define to 1 if you have the `vasprintf' function. */
/* Define to 1 if you have the 'vasprintf' function. */
#undef HAVE_VASPRINTF
/* Define to the address where bug reports for this package should be sent. */
@@ -117,10 +111,12 @@
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if you have the ANSI C header files. */
/* Define to 1 if all of the C89 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* Define as 'unsigned int' if <stddef.h> doesn't define. */
#undef size_t
#endif

1058
menuselect/configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -3796,35 +3796,20 @@ static void set_state_terminated(struct ast_sip_subscription *sub)
*
*/
/*!
* \brief PJSIP callback when underlying SIP subscription changes state
*
* Although this function is called for every state change, we only care
* about the TERMINATED state, and only when we're actually processing the final
* notify (SIP_SUB_TREE_TERMINATE_IN_PROGRESS) OR when a transmission failure
* occurs (PJSIP_EVENT_TSX_STATE). In this case, we do all the subscription tree
* cleanup tasks and decrement the evsub reference.
/* The code in this function was previously in pubsub_on_evsub_state. As of
* pjsip 2.13 pubsub_on_evsub_state is called before pubsub_on_rx_refresh, so
* if we clean the sub tree in pubsub_on_evsub_state it won't be available in
* pubsub_on_rx_refresh. This means we won't be able to build or send the
* corresponding NOTIFY (which also causes pjsip to assert.)
* If HAVE_PJSIP_EVSUB_PENDING_NOTIFY is set based on configuration, this will
* be called from pubsub_on_rx_refresh. If not set, the result is the legacy
* behavior of calling this from pubsub_on_evsub_state.
*/
static void pubsub_on_evsub_state(pjsip_evsub *evsub, pjsip_event *event)
{
struct sip_subscription_tree *sub_tree =
pjsip_evsub_get_mod_data(evsub, pubsub_module.id);
static void clean_sub_tree(pjsip_evsub *evsub){
ast_debug(3, "evsub %p state %s event %s sub_tree %p sub_tree state %s\n", evsub,
pjsip_evsub_get_state_name(evsub), pjsip_event_str(event->type), sub_tree,
(sub_tree ? sub_tree_state_description[sub_tree->state] : "UNKNOWN"));
if (!sub_tree || pjsip_evsub_get_state(evsub) != PJSIP_EVSUB_STATE_TERMINATED) {
return;
}
/* It's easier to write this as what we WANT to process, then negate it. */
if (!(sub_tree->state == SIP_SUB_TREE_TERMINATE_IN_PROGRESS
|| (event->type == PJSIP_EVENT_TSX_STATE && sub_tree->state == SIP_SUB_TREE_NORMAL)
)) {
ast_debug(3, "Do nothing.\n");
return;
}
struct sip_subscription_tree *sub_tree;
sub_tree = pjsip_evsub_get_mod_data(evsub, pubsub_module.id);
if (sub_tree->expiration_task) {
char task_name[256];
@@ -3857,6 +3842,45 @@ static void pubsub_on_evsub_state(pjsip_evsub *evsub, pjsip_event *event)
ao2_ref(sub_tree, -1);
}
/*!
* \brief PJSIP callback when underlying SIP subscription changes state
*
* Although this function is called for every state change, we only care
* about the TERMINATED state, and only when we're actually processing the final
* notify (SIP_SUB_TREE_TERMINATE_IN_PROGRESS) OR when a transmission failure
* occurs (PJSIP_EVENT_TSX_STATE). In this case, we do all the subscription tree
* cleanup tasks and decrement the evsub reference.
*/
static void pubsub_on_evsub_state(pjsip_evsub *evsub, pjsip_event *event)
{
struct sip_subscription_tree *sub_tree =
pjsip_evsub_get_mod_data(evsub, pubsub_module.id);
ast_debug(3, "evsub %p state %s event %s sub_tree %p sub_tree state %s\n", evsub,
pjsip_evsub_get_state_name(evsub), pjsip_event_str(event->type), sub_tree,
(sub_tree ? sub_tree_state_description[sub_tree->state] : "UNKNOWN"));
if (!sub_tree || pjsip_evsub_get_state(evsub) != PJSIP_EVSUB_STATE_TERMINATED) {
return;
}
/* It's easier to write this as what we WANT to process, then negate it. */
if (!(sub_tree->state == SIP_SUB_TREE_TERMINATE_IN_PROGRESS
|| (event->type == PJSIP_EVENT_TSX_STATE && sub_tree->state == SIP_SUB_TREE_NORMAL)
)) {
ast_debug(3, "Do nothing.\n");
return;
}
#ifndef HAVE_PJSIP_EVSUB_PENDING_NOTIFY
/* for pjproject <2.13, this cleanup occurs here. For >=2.13, pubsub_on_evsub_state
is called before pubsub_on_rx_refresh and so must be cleaned there.*/
clean_sub_tree(evsub);
#endif
}
static int pubsub_on_refresh_timeout(void *userdata)
{
struct sip_subscription_tree *sub_tree = userdata;
@@ -3942,16 +3966,37 @@ static void pubsub_on_rx_refresh(pjsip_evsub *evsub, pjsip_rx_data *rdata,
subscription_persistence_update(sub_tree, rdata, SUBSCRIPTION_PERSISTENCE_REFRESHED);
#ifdef HAVE_PJSIP_EVSUB_PENDING_NOTIFY
/* As of pjsip 2.13, the NOTIFY has to be sent within this function as pjproject now
requires it. Previously this would have caused an early NOTIFY to go out before the
SUBSCRIBE's 200 OK. The previous solution was to push the NOTIFY, but now pjproject
looks for the NOTIFY on send and delays it until after it auto-replies.
If the NOTIFY is not there when it looks to send, pjproject will assert. */
serialized_pubsub_on_refresh_timeout(sub_tree);
#else
if (ast_sip_push_task(sub_tree->serializer, serialized_pubsub_on_refresh_timeout, ao2_bump(sub_tree))) {
/* If we can't push the NOTIFY refreshing task...we'll just go with it. */
ast_log(LOG_ERROR, "Failed to push task to send NOTIFY.\n");
sub_tree->state = SIP_SUB_TREE_NORMAL;
ao2_ref(sub_tree, -1);
}
#endif
if (sub_tree->is_list) {
pj_list_insert_before(res_hdr, create_require_eventlist(rdata->tp_info.pool));
}
#ifdef HAVE_PJSIP_EVSUB_PENDING_NOTIFY
/* for pjproject <2.13, this cleanup occurs in pubsub_on_evsub_state. For >=2.13,
pubsub_on_rx_refresh is called after pubsub_on_evsub_state and so the tree must be
cleaned here. */
if( pjsip_evsub_get_state(evsub) == PJSIP_EVSUB_STATE_TERMINATED &&
sub_tree->state == SIP_SUB_TREE_TERMINATE_PENDING ) {
clean_sub_tree(evsub);
}
#endif
}
static void pubsub_on_rx_notify(pjsip_evsub *evsub, pjsip_rx_data *rdata, int *p_st_code,

View File

@@ -111,6 +111,8 @@ AC_DEFUN([_PJPROJECT_CONFIGURE],
AC_DEFINE([HAVE_PJSIP_TRANSPORT_DISABLE_CONNECTION_REUSE], 1, [Define if your system has HAVE_PJSIP_TRANSPORT_DISABLE_CONNECTION_REUSE declared])
AC_DEFINE([HAVE_PJSIP_OAUTH_AUTHENTICATION], 1, [Define if your system has HAVE_PJSIP_OAUTH_AUTHENTICATION declared])
AC_DEFINE([HAVE_PJPROJECT_ON_VALID_ICE_PAIR_CALLBACK], 1, [Define if your system has the on_valid_pair pjnath callback.])
AC_DEFINE([HAVE_PJSIP_TLS_TRANSPORT_RESTART], 1, [Define if your system has pjsip_tls_transport_restart support.])
AC_DEFINE([HAVE_PJSIP_EVSUB_PENDING_NOTIFY], 1, [Define to 1 if evsub requires a NOTIFY on SUBSCRIBE.])
AC_SUBST([PJPROJECT_BUNDLED])
AC_SUBST([PJPROJECT_DIR])

View File

@@ -1,47 +1,34 @@
From e8000cc80e5f8ba02cc52852edc02cdb0e949525 Mon Sep 17 00:00:00 2001
From: Richard Mudgett <rmudgett@digium.com>
Date: Mon, 6 Aug 2018 11:24:25 -0500
Subject: [PATCH 1/5] 0000-configure-ssl-library-path.patch
---
aconfigure | 6 +++++-
aconfigure.ac | 6 +++++-
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/aconfigure b/aconfigure
index 1c449b8..c4c6060 100755
index d6f0e8809..9dcd46398 100755
--- a/aconfigure
+++ b/aconfigure
@@ -7954,7 +7954,11 @@ else
if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then
CFLAGS="$CFLAGS -I$with_ssl/include"
CPPFLAGS="$CPPFLAGS -I$with_ssl/include"
- LDFLAGS="$LDFLAGS -L$with_ssl/lib"
+ if test -d $with_ssl/lib; then
+ LDFLAGS="$LDFLAGS -L$with_ssl/lib"
+ else
+ LDFLAGS="$LDFLAGS -L$with_ssl"
+ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Using SSL prefix... $with_ssl" >&5
$as_echo "Using SSL prefix... $with_ssl" >&6; }
fi
@@ -9768,7 +9768,11 @@
if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then
CFLAGS="$CFLAGS -I$with_ssl/include"
CPPFLAGS="$CPPFLAGS -I$with_ssl/include"
- LDFLAGS="$LDFLAGS -L$with_ssl/lib"
+ if test -d $with_ssl/lib; then
+ LDFLAGS="$LDFLAGS -L$with_ssl/lib"
+ else
+ LDFLAGS="$LDFLAGS -L$with_ssl"
+ fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using SSL prefix... $with_ssl" >&5
printf "%s\n" "Using SSL prefix... $with_ssl" >&6; }
fi
diff --git a/aconfigure.ac b/aconfigure.ac
index 2c272cd..a5d6d97 100644
index 16b311045..849da81ab 100644
--- a/aconfigure.ac
+++ b/aconfigure.ac
@@ -1580,7 +1580,11 @@ AC_ARG_ENABLE(ssl,
if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then
CFLAGS="$CFLAGS -I$with_ssl/include"
CPPFLAGS="$CPPFLAGS -I$with_ssl/include"
- LDFLAGS="$LDFLAGS -L$with_ssl/lib"
+ if test -d $with_ssl/lib; then
+ LDFLAGS="$LDFLAGS -L$with_ssl/lib"
+ else
+ LDFLAGS="$LDFLAGS -L$with_ssl"
+ fi
AC_MSG_RESULT([Using SSL prefix... $with_ssl])
fi
--
2.7.4
@@ -2172,7 +2172,11 @@
if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then
CFLAGS="$CFLAGS -I$with_ssl/include"
CPPFLAGS="$CPPFLAGS -I$with_ssl/include"
- LDFLAGS="$LDFLAGS -L$with_ssl/lib"
+ if test -d $with_ssl/lib; then
+ LDFLAGS="$LDFLAGS -L$with_ssl/lib"
+ else
+ LDFLAGS="$LDFLAGS -L$with_ssl"
+ fi
AC_MSG_RESULT([Using SSL prefix... $with_ssl])
fi

View File

@@ -1,14 +1,5 @@
From 665a2fbc3a09a71cd77988ae2deb3f5d3e205f63 Mon Sep 17 00:00:00 2001
From: Richard Mudgett <rmudgett@digium.com>
Date: Thu, 23 Feb 2017 17:10:07 -0600
Subject: [PATCH 2/5] 0000-remove-third-party.patch
---
build.mak.in | 97 ------------------------------------------------------------
1 file changed, 97 deletions(-)
diff --git a/build.mak.in b/build.mak.in
index 80ccad1..41ec64e 100644
index 4bc464f8c..80681d961 100644
--- a/build.mak.in
+++ b/build.mak.in
@@ -1,4 +1,3 @@
@@ -16,10 +7,11 @@ index 80ccad1..41ec64e 100644
include $(PJDIR)/version.mak
export PJ_DIR := $(PJDIR)
@@ -37,19 +36,6 @@ export APP_THIRD_PARTY_EXT :=
@@ -42,21 +41,6 @@ export APP_THIRD_PARTY_EXT :=
export APP_THIRD_PARTY_LIBS :=
export APP_THIRD_PARTY_LIB_FILES :=
-ifneq (@ac_no_srtp@,1)
-ifneq (@ac_external_srtp@,0)
-# External SRTP library
-APP_THIRD_PARTY_EXT += -l@ac_external_srtp_lib@
@@ -32,11 +24,12 @@ index 80ccad1..41ec64e 100644
-APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libsrtp.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libsrtp.$(SHLIB_SUFFIX)
-endif
-endif
-endif
-
ifeq (@ac_pjmedia_resample@,libresample)
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
@@ -66,89 +52,6 @@ APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFI
@@ -73,102 +57,6 @@ APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFI
endif
endif
@@ -122,10 +115,20 @@ index 80ccad1..41ec64e 100644
-endif
-endif
-
-ifneq (@ac_no_webrtc_aec3@,1)
-ifeq (@ac_external_webrtc_aec3@,1)
-APP_THIRD_PARTY_EXT += -lwebrtc-aec3
-else
-APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc-aec3-$(LIB_SUFFIX)
-ifeq ($(PJ_SHARED_LIBRARIES),)
-APP_THIRD_PARTY_LIBS += -lwebrtc-aec3-$(TARGET_NAME)
-else
-APP_THIRD_PARTY_LIBS += -lwebrtc-aec3
-APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc-aec3.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libwebrtc.$(SHLIB_SUFFIX)
-endif
-endif
-endif
-
# Additional flags
@ac_build_mak_vars@
--
2.7.4

View File

@@ -1,53 +0,0 @@
From c40ad6ba454fdf6456d8ffa92faa4cd49f2c807d Mon Sep 17 00:00:00 2001
From: Richard Mudgett <rmudgett@digium.com>
Date: Thu, 23 Feb 2017 17:11:00 -0600
Subject: [PATCH 3/5] 0000-set_apps_initial_log_level.patch
---
pjsip-apps/src/pjsua/main.c | 2 ++
pjsip-apps/src/pjsystest/main_console.c | 2 ++
pjsip-apps/src/python/_pjsua.c | 3 ++-
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/pjsip-apps/src/pjsua/main.c b/pjsip-apps/src/pjsua/main.c
index 2baaf82..11831f2 100644
--- a/pjsip-apps/src/pjsua/main.c
+++ b/pjsip-apps/src/pjsua/main.c
@@ -126,5 +126,7 @@ int main_func(int argc, char *argv[])
int main(int argc, char *argv[])
{
+ pj_log_set_level(1);
+
return pj_run_app(&main_func, argc, argv, 0);
}
diff --git a/pjsip-apps/src/pjsystest/main_console.c b/pjsip-apps/src/pjsystest/main_console.c
index 122cdc7..dc79eab 100644
--- a/pjsip-apps/src/pjsystest/main_console.c
+++ b/pjsip-apps/src/pjsystest/main_console.c
@@ -133,6 +133,8 @@ void gui_sleep(unsigned sec)
int main()
{
+ pj_log_set_level(1);
+
if (systest_init() != PJ_SUCCESS)
return 1;
diff --git a/pjsip-apps/src/python/_pjsua.c b/pjsip-apps/src/python/_pjsua.c
index 31b835e..3e15030 100644
--- a/pjsip-apps/src/python/_pjsua.c
+++ b/pjsip-apps/src/python/_pjsua.c
@@ -4434,7 +4434,8 @@ init_pjsua(void)
PyObject* m = NULL;
#define ADD_CONSTANT(mod,name) PyModule_AddIntConstant(mod,#name,name)
-
+ pj_log_set_level(1);
+
PyEval_InitThreads();
if (PyType_Ready(&PyTyp_pjsua_callback) < 0)
--
2.7.4

View File

@@ -1,135 +0,0 @@
From 1ac599a0f29500a15faf0dbbdc2565cc7dce2420 Mon Sep 17 00:00:00 2001
From: Shaun Ruffell <sruffell@digium.com>
Date: Fri, 7 Sep 2012 14:31:19 -0500
Subject: [PATCH 4/5] pjproject: Fix for Solaris builds. Do not undef s_addr.
pjproject, in order to solve build problems on Windows [1], undefines s_addr in
one of it's headers that is included in res_rtp_asterisk.c. On Solaris s_addr is
not a structure member, but defined to map to the real strucuture member,
therefore when building on Solaris it's possible to get build errors like:
[CC] res_rtp_asterisk.c -> res_rtp_asterisk.o
In file included from /export/home/admin/asterisk-11-svn/include/asterisk/stun.h:29,
from res_rtp_asterisk.c:51:
/export/home/admin/asterisk-11-svn/include/asterisk/network.h: In function `inaddrcmp':
/export/home/admin/asterisk-11-svn/include/asterisk/network.h:92: error: structure has no member named `s_addr'
/export/home/admin/asterisk-11-svn/include/asterisk/network.h:92: error: structure has no member named `s_addr'
res_rtp_asterisk.c: In function `ast_rtp_on_ice_tx_pkt':
res_rtp_asterisk.c:706: warning: dereferencing type-punned pointer will break strict-aliasing rules
res_rtp_asterisk.c:710: warning: dereferencing type-punned pointer will break strict-aliasing rules
res_rtp_asterisk.c: In function `rtp_add_candidates_to_ice':
res_rtp_asterisk.c:1085: error: structure has no member named `s_addr'
make[2]: *** [res_rtp_asterisk.o] Error 1
make[1]: *** [res] Error 2
make[1]: Leaving directory `/export/home/admin/asterisk-11-svn'
gmake: *** [_cleantest_all] Error 2
Unfortunately, in order to make this work, I also had to make sure pjproject
only used the typdef pj_in_addr and not the struct pj_in_addr so that when
building Asterisk I could "typedef struct in_addr pj_in_addr". It's possible
then that the library and users of those interfaces in Asterisk have a different
idea about the type of the argument. While on the surface it looks like they are
all 32 bit big endian values.
[1] http://trac.pjsip.org/repos/changeset/484
Reported-by: Ben Klang
(issues ASTERISK-20366)
Updated by ASTERISK-27997
---
pjlib/include/pj/sock.h | 8 +++++++-
pjlib/src/pj/sock_bsd.c | 2 +-
pjlib/src/pj/sock_symbian.cpp | 2 +-
pjlib/src/pj/sock_uwp.cpp | 2 +-
pjsip/src/test/transport_test.c | 2 +-
5 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/pjlib/include/pj/sock.h b/pjlib/include/pj/sock.h
index 4daf298..c35833c 100644
--- a/pjlib/include/pj/sock.h
+++ b/pjlib/include/pj/sock.h
@@ -484,6 +484,7 @@ typedef enum pj_socket_sd_type
*/
#define PJ_INVALID_SOCKET (-1)
+#ifndef _ASTERISK_H
/* Must undefine s_addr because of pj_in_addr below */
#undef s_addr
@@ -495,6 +496,11 @@ typedef struct pj_in_addr
pj_uint32_t s_addr; /**< The 32bit IP address. */
} pj_in_addr;
+#else
+#include <sys/types.h>
+#include <netinet/in.h>
+typedef struct in_addr pj_in_addr;
+#endif
/**
* Maximum length of text representation of an IPv4 address.
@@ -712,7 +718,7 @@ PJ_DECL(char*) pj_inet_ntoa(pj_in_addr inaddr);
*
* @return nonzero if the address is valid, zero if not.
*/
-PJ_DECL(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp);
+PJ_DECL(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp);
/**
* This function converts an address in its standard text presentation form
diff --git a/pjlib/src/pj/sock_bsd.c b/pjlib/src/pj/sock_bsd.c
index e416991..940fce1 100644
--- a/pjlib/src/pj/sock_bsd.c
+++ b/pjlib/src/pj/sock_bsd.c
@@ -244,7 +244,7 @@ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)
* numbers-and-dots notation into binary data and stores it in the structure
* that inp points to.
*/
-PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)
+PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp)
{
char tempaddr[PJ_INET_ADDRSTRLEN];
diff --git a/pjlib/src/pj/sock_symbian.cpp b/pjlib/src/pj/sock_symbian.cpp
index 09239b0..e72bbda 100644
--- a/pjlib/src/pj/sock_symbian.cpp
+++ b/pjlib/src/pj/sock_symbian.cpp
@@ -299,7 +299,7 @@ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)
* numbers-and-dots notation into binary data and stores it in the structure
* that inp points to.
*/
-PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)
+PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp)
{
enum { MAXIPLEN = PJ_INET_ADDRSTRLEN };
diff --git a/pjlib/src/pj/sock_uwp.cpp b/pjlib/src/pj/sock_uwp.cpp
index 876c328..40250bf 100644
--- a/pjlib/src/pj/sock_uwp.cpp
+++ b/pjlib/src/pj/sock_uwp.cpp
@@ -933,7 +933,7 @@ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)
* numbers-and-dots notation into binary data and stores it in the structure
* that inp points to.
*/
-PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)
+PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, pj_in_addr *inp)
{
char tempaddr[PJ_INET_ADDRSTRLEN];
diff --git a/pjsip/src/test/transport_test.c b/pjsip/src/test/transport_test.c
index e5083d1..c429cc7 100644
--- a/pjsip/src/test/transport_test.c
+++ b/pjsip/src/test/transport_test.c
@@ -35,7 +35,7 @@ int generic_transport_test(pjsip_transport *tp)
/* Check that local address name is valid. */
{
- struct pj_in_addr addr;
+ pj_in_addr addr;
if (pj_inet_pton(pj_AF_INET(), &tp->local_name.host,
&addr) == PJ_SUCCESS)
--
2.7.4

View File

@@ -0,0 +1,158 @@
From edde06f261ac807a89a6086b7f03460867675f95 Mon Sep 17 00:00:00 2001
From: Nanang Izzuddin <nanang@teluu.com>
Date: Tue, 1 Jul 2025 15:13:36 +0700
Subject: [PATCH] Avoid deadlock between transport and transaction (#4453)
---
pjsip/include/pjsip/sip_transaction.h | 1 +
pjsip/src/pjsip/sip_transaction.c | 101 ++++++++++++++++++++++----
2 files changed, 88 insertions(+), 14 deletions(-)
diff --git a/pjsip/include/pjsip/sip_transaction.h b/pjsip/include/pjsip/sip_transaction.h
index 72d4bc81c5..5f28b2d69c 100644
--- a/pjsip/include/pjsip/sip_transaction.h
+++ b/pjsip/include/pjsip/sip_transaction.h
@@ -141,6 +141,7 @@ struct pjsip_transaction
int retransmit_count;/**< Retransmission count. */
pj_timer_entry retransmit_timer;/**< Retransmit timer. */
pj_timer_entry timeout_timer; /**< Timeout timer. */
+ pj_timer_entry misc_timer; /**< Miscellaneous timer. */
/** Module specific data. */
void *mod_data[PJSIP_MAX_MODULE];
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index 4335f11ff5..31dbaaab6e 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -140,6 +140,7 @@ static int max_retrans_count = -1;
#define TRANSPORT_ERR_TIMER 3
#define TRANSPORT_DISC_TIMER 4
#define TERMINATE_TIMER 5
+#define TRANSPORT_CB_TIMER 6
/* Flags for tsx_set_state() */
enum
@@ -2265,23 +2266,21 @@ static void send_msg_callback( pjsip_send_state *send_state,
}
-/* Transport callback. */
-static void transport_callback(void *token, pjsip_tx_data *tdata,
- pj_ssize_t sent)
-{
- pjsip_transaction *tsx = (pjsip_transaction*) token;
+/* Transport callback parameter. */
+struct tp_cb_param {
+ pjsip_transaction* tsx;
+ pjsip_tx_data* tdata;
+ pj_ssize_t sent;
+};
- /* Check if the transaction layer has been shutdown. */
- if (mod_tsx_layer.mod.id < 0)
- return;
- /* In other circumstances, locking tsx->grp_lock AFTER transport mutex
- * will introduce deadlock if another thread is currently sending a
- * SIP message to the transport. But this should be safe as there should
- * be no way this callback could be called while another thread is
- * sending a message.
- */
+/* Transport callback actual implementation. */
+static void transport_callback_impl(pjsip_transaction *tsx,
+ pjsip_tx_data* tdata,
+ pj_ssize_t sent)
+{
pj_grp_lock_acquire(tsx->grp_lock);
+
tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);
if (sent > 0 || tsx->role == PJSIP_ROLE_UAS) {
@@ -2299,6 +2298,7 @@ static void transport_callback(void *token, pjsip_tx_data *tdata,
tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED,
PJSIP_EVENT_UNKNOWN, NULL, 0 );
pj_grp_lock_release(tsx->grp_lock);
+ pj_grp_lock_dec_ref(tsx->grp_lock);
return;
}
@@ -2354,6 +2354,79 @@ static void transport_callback(void *token, pjsip_tx_data *tdata,
}
+/* Timer callback for transport callback.
+ * This is currently only used to avoid deadlock due to inversed locking order
+ * between transport and transaction.
+ */
+static void tsx_misc_timer_callback(pj_timer_heap_t *theap,
+ pj_timer_entry *entry)
+{
+ PJ_UNUSED_ARG(theap);
+
+ if (entry->id == TRANSPORT_CB_TIMER) {
+ struct tp_cb_param* param = (struct tp_cb_param*)entry->user_data;
+
+ /* Check if the transaction layer has been shutdown. */
+ if (mod_tsx_layer.mod.id >= 0) {
+ /* Call transport callback implementation */
+ transport_callback_impl(param->tsx, param->tdata, param->sent);
+ }
+
+ /* Release tdata */
+ pjsip_tx_data_dec_ref(param->tdata);
+ }
+}
+
+
+/* Transport callback. */
+static void transport_callback(void *token, pjsip_tx_data *tdata,
+ pj_ssize_t sent)
+{
+ pjsip_transaction *tsx = (pjsip_transaction*) token;
+ pj_status_t status;
+
+ /* Check if the transaction layer has been shutdown. */
+ if (mod_tsx_layer.mod.id < 0)
+ return;
+
+ /* In other circumstances, locking tsx->grp_lock AFTER transport mutex
+ * will introduce deadlock if another thread is currently sending a
+ * SIP message to the transport. But this should be safe as there should
+ * be no way this callback could be called while another thread is
+ * sending a message.
+ */
+ // Deadlock does happen, see #4453.
+ // So now, to avoid deadlock, we'll try to acquire the group lock first,
+ // and if it fails, we'll schedule the processing via timer.
+ status = pj_grp_lock_tryacquire(tsx->grp_lock);
+ if (status != PJ_SUCCESS) {
+ pj_time_val delay = { 0, 0 };
+ struct tp_cb_param *param = NULL;
+
+ lock_timer(tsx);
+ tsx_cancel_timer(tsx, &tsx->misc_timer);
+
+ /* Increment tdata ref count to avoid premature destruction.
+ * Note that tsx ref count is already handled by tsx_schedule_timer().
+ */
+ pjsip_tx_data_add_ref(tdata);
+
+ param = PJ_POOL_ZALLOC_T(tsx->pool, struct tp_cb_param);
+ param->sent = sent;
+ param->tdata = tdata;
+ param->tsx = tsx;
+ pj_timer_entry_init(&tsx->misc_timer, TIMER_INACTIVE, param,
+ &tsx_misc_timer_callback);
+ tsx_schedule_timer(tsx, &tsx->misc_timer, &delay, TRANSPORT_CB_TIMER);
+ unlock_timer(tsx);
+ return;
+ }
+
+ transport_callback_impl(tsx, tdata, sent);
+ pj_grp_lock_release(tsx->grp_lock);
+}
+
+
/*
* Callback when transport state changes.
*/

View File

@@ -1,39 +0,0 @@
commit c3c1bf45cae2a35003aa16c267d59f97027f9c5e
Author: Kevin Harwell <kharwell@digium.com>
Date: Thu Jun 11 11:11:13 2020 -0500
sip_inv - fix invite session ref count crash
Ensure the session's ref count is only decremented under proper conditons.
For more details see the following issue report:
https://github.com/pjsip/pjproject/issues/2443
Patch supplied by sauwming
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index ca225015b..7c11b1c8e 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -323,9 +323,19 @@ static void inv_set_state(pjsip_inv_session *inv, pjsip_inv_state state,
(*mod_inv.cb.on_state_changed)(inv, e);
pjsip_inv_dec_ref(inv);
- /* Only decrement when previous state is not already DISCONNECTED */
+ /* The above callback may change the state, so we need to be careful here
+ * and only decrement inv under the following conditions:
+ * 1. If the state parameter is DISCONNECTED, and previous state is not
+ * already DISCONNECTED.
+ * This is to make sure that dec_ref() is not called more than once.
+ * 2. If current state is PJSIP_INV_STATE_DISCONNECTED.
+ * This is to make sure that dec_ref() is not called if user restarts
+ * inv within the callback. Note that this check must be last since
+ * inv may have already been destroyed.
+ */
if (state == PJSIP_INV_STATE_DISCONNECTED &&
- prev_state != PJSIP_INV_STATE_DISCONNECTED)
+ prev_state != PJSIP_INV_STATE_DISCONNECTED &&
+ inv->state == PJSIP_INV_STATE_DISCONNECTED)
{
pjsip_inv_dec_ref(inv);
}

View File

@@ -1,39 +0,0 @@
commit 40dd48d10911f4ff9b8dfbf16428fbc9acc434ba
Author: Riza Sulistyo <trengginas@users.noreply.github.com>
Date: Thu Jul 9 17:47:24 2020 +0700
Modify timer_id check on cancel() (#2463)
* modify timer_id check on cancel().
* modification based on comments.
diff --git a/pjlib/include/pj/timer.h b/pjlib/include/pj/timer.h
index b738a6e76..4b76ab65d 100644
--- a/pjlib/include/pj/timer.h
+++ b/pjlib/include/pj/timer.h
@@ -120,7 +120,10 @@ typedef struct pj_timer_entry
/**
* Internal unique timer ID, which is assigned by the timer heap.
- * Application should not touch this ID.
+ * Positive values indicate that the timer entry is running,
+ * while -1 means that it's not. Any other value may indicate that it
+ * hasn't been properly initialised or is in a bad state.
+ * Application should not touch this ID.
*/
pj_timer_id_t _timer_id;
diff --git a/pjlib/src/pj/timer.c b/pjlib/src/pj/timer.c
index 66516fce8..34966c481 100644
--- a/pjlib/src/pj/timer.c
+++ b/pjlib/src/pj/timer.c
@@ -535,7 +535,7 @@ static int cancel( pj_timer_heap_t *ht,
PJ_CHECK_STACK();
// Check to see if the timer_id is out of range
- if (entry->_timer_id < 0 || (pj_size_t)entry->_timer_id > ht->max_size) {
+ if (entry->_timer_id < 1 || (pj_size_t)entry->_timer_id >= ht->max_size) {
entry->_timer_id = -1;
return 0;
}

View File

@@ -1,72 +0,0 @@
From 78683646c8bc670ec730a42494e075f671a08e28 Mon Sep 17 00:00:00 2001
From: Guido Falsi <mad@madpilot.net>
Date: Mon, 11 May 2020 08:50:39 +0200
Subject: [PATCH] Fix race condition in parallel builds (#2426)
* Some targets residing in `OBJDIRS` are missing a dependency on that directory, which results in a race condition, causing build to fail sometimes due to the directory not existing when running parallel builds.
* The `PJSUA_LIB` variable is not defined anywhere, resulting in an empty value, and no correct dependency on the pjsua shared library for `pjsua2`. The correct variable seems to be `PJSUA_LIB_LIB`, defined at the start of this same `Makefile`.
---
build/rules.mak | 12 ++++++------
pjsip/build/Makefile | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/build/rules.mak b/build/rules.mak
index 8fa98655e..912199c41 100644
--- a/build/rules.mak
+++ b/build/rules.mak
@@ -129,7 +129,7 @@ endif
$(OBJDIR)/$(app).o: $(OBJDIRS) $(OBJS)
$(CROSS_COMPILE)ld -r -o $@ $(OBJS)
-$(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o
+$(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o | $(OBJDIRS)
@echo Creating kbuild Makefile...
@echo "# Our module name:" > $(OBJDIR)/Makefile
@echo 'obj-m += $(app).o' >> $(OBJDIR)/Makefile
@@ -154,27 +154,27 @@ $(OBJDIR)/$(app).ko: $(OBJDIR)/$(app).o
../lib/$(app).ko: $(LIB) $(OBJDIR)/$(app).ko
cp $(OBJDIR)/$(app).ko ../lib
-$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.m
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.m | $(OBJDIRS)
$(CC) $($(APP)_CFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
-$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.c | $(OBJDIRS)
$(CC) $($(APP)_CFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
-$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.S
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.S | $(OBJDIRS)
$(CC) $($(APP)_CFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
-$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp | $(OBJDIRS)
$(CXX) $($(APP)_CXXFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
-$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc | $(OBJDIRS)
$(CXX) $($(APP)_CXXFLAGS) \
$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
$(subst /,$(HOST_PSEP),$<)
diff --git a/pjsip/build/Makefile b/pjsip/build/Makefile
index b85c7817a..20777909f 100644
--- a/pjsip/build/Makefile
+++ b/pjsip/build/Makefile
@@ -262,7 +262,7 @@ $(PJSUA_LIB_LIB) $(PJSUA_LIB_SONAME): $(PJSIP_LIB) $(PJSIP_SONAME) $(PJSIP_SIMPL
pjsua2-lib: $(PJSUA2_LIB_LIB)
$(PJSUA2_LIB_SONAME): $(PJSUA2_LIB_LIB)
-$(PJSUA2_LIB_LIB) $(PJSUA2_LIB_SONAME): $(PJSUA_LIB) $(PSJUA_LIB_SONAME) $(PJSIP_LIB) $(PJSIP_SONAME) $(PJSIP_SIMPLE_LIB) $(PJSIP_SIMPLE_SONAME) $(PJSIP_UA_LIB) $(PJSIP_UA_SONAME)
+$(PJSUA2_LIB_LIB) $(PJSUA2_LIB_SONAME): $(PJSUA_LIB_LIB) $(PJSUA_LIB_SONAME) $(PJSIP_LIB) $(PJSIP_SONAME) $(PJSIP_SIMPLE_LIB) $(PJSIP_SIMPLE_SONAME) $(PJSIP_UA_LIB) $(PJSIP_UA_SONAME)
$(MAKE) -f $(RULES_MAK) APP=PJSUA2_LIB app=pjsua2-lib $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)
pjsip-test: $(TEST_EXE)

View File

@@ -1,28 +0,0 @@
diff -ur source.orig/pjmedia/src/pjmedia/sdp_neg.c source/pjmedia/src/pjmedia/sdp_neg.c
--- source.orig/pjmedia/src/pjmedia/sdp_neg.c 2020-07-02 10:35:42.022459904 +0200
+++ source/pjmedia/src/pjmedia/sdp_neg.c 2020-07-02 10:33:24.996316867 +0200
@@ -906,7 +906,7 @@
* after receiving remote answer.
*/
static pj_status_t process_answer(pj_pool_t *pool,
- pjmedia_sdp_session *offer,
+ pjmedia_sdp_session *local_offer,
pjmedia_sdp_session *answer,
pj_bool_t allow_asym,
pjmedia_sdp_session **p_active)
@@ -914,10 +914,14 @@
unsigned omi = 0; /* Offer media index */
unsigned ami = 0; /* Answer media index */
pj_bool_t has_active = PJ_FALSE;
+ pjmedia_sdp_session *offer;
pj_status_t status;
/* Check arguments. */
- PJ_ASSERT_RETURN(pool && offer && answer && p_active, PJ_EINVAL);
+ PJ_ASSERT_RETURN(pool && local_offer && answer && p_active, PJ_EINVAL);
+
+ /* Duplicate local offer SDP. */
+ offer = pjmedia_sdp_session_clone(pool, local_offer);
/* Check that media count match between offer and answer */
// Ticket #527, different media count is allowed for more interoperability,

View File

@@ -1,37 +0,0 @@
From ce18018cc17bef8f80c08686e3a7b28384ef3ba5 Mon Sep 17 00:00:00 2001
From: sauwming <ming@teluu.com>
Date: Mon, 12 Oct 2020 13:31:25 +0800
Subject: [PATCH] Fix incorrect copying of destination info when creating
CANCEL (#2546)
---
pjsip/src/pjsip/sip_util.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c
index d10a6fa30..a1bf878ea 100644
--- a/pjsip/src/pjsip/sip_util.c
+++ b/pjsip/src/pjsip/sip_util.c
@@ -779,14 +779,14 @@ PJ_DEF(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,
pjsip_hdr_clone(cancel_tdata->pool, req_tdata->saved_strict_route);
}
- /* Copy the destination host name from the original request */
- pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,
- &req_tdata->dest_info.name);
-
- /* Finally copy the destination info from the original request */
+ /* Copy the destination info from the original request */
pj_memcpy(&cancel_tdata->dest_info, &req_tdata->dest_info,
sizeof(req_tdata->dest_info));
+ /* Finally, copy the destination host name from the original request */
+ pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,
+ &req_tdata->dest_info.name);
+
/* Done.
* Return the transmit buffer containing the CANCEL request.
*/
--
2.25.1

View File

@@ -1,33 +0,0 @@
diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c
index 3b85b4273..a14009662 100644
--- a/pjmedia/src/pjmedia/sdp_neg.c
+++ b/pjmedia/src/pjmedia/sdp_neg.c
@@ -304,7 +304,6 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(
{
pjmedia_sdp_session *new_offer;
pjmedia_sdp_session *old_offer;
- char media_used[PJMEDIA_MAX_SDP_MEDIA];
unsigned oi; /* old offer media index */
pj_status_t status;
@@ -323,8 +322,19 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(
/* Change state to STATE_LOCAL_OFFER */
neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER;
+ /* When there is no active local SDP in state PJMEDIA_SDP_NEG_STATE_DONE,
+ * it means that the previous initial SDP nego must have been failed,
+ * so we'll just set the local SDP offer here.
+ */
+ if (!neg->active_local_sdp) {
+ neg->initial_sdp_tmp = NULL;
+ neg->initial_sdp = pjmedia_sdp_session_clone(pool, local);
+ neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, local);
+
+ return PJ_SUCCESS;
+ }
+
/* Init vars */
- pj_bzero(media_used, sizeof(media_used));
old_offer = neg->active_local_sdp;
new_offer = pjmedia_sdp_session_clone(pool, local);

View File

@@ -1,212 +0,0 @@
From bdbeb7c4b2b11efc2e59f5dee7aa4360a2bc9fff Mon Sep 17 00:00:00 2001
From: sauwming <ming@teluu.com>
Date: Thu, 22 Apr 2021 14:03:28 +0800
Subject: [PATCH 90/90] Skip unsupported digest algorithm (#2408)
Co-authored-by: Nanang Izzuddin <nanang@teluu.com>
---
pjsip/src/pjsip/sip_auth_client.c | 32 +++++--
tests/pjsua/scripts-sipp/uas-auth-two-algo.py | 7 ++
.../pjsua/scripts-sipp/uas-auth-two-algo.xml | 83 +++++++++++++++++++
3 files changed, 117 insertions(+), 5 deletions(-)
create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.py
create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.xml
diff --git a/pjsip/src/pjsip/sip_auth_client.c b/pjsip/src/pjsip/sip_auth_client.c
index 828b04db9..7eb2f5cd1 100644
--- a/pjsip/src/pjsip/sip_auth_client.c
+++ b/pjsip/src/pjsip/sip_auth_client.c
@@ -1042,7 +1042,7 @@ static pj_status_t process_auth( pj_pool_t *req_pool,
pjsip_hdr *hdr;
pj_status_t status;
- /* See if we have sent authorization header for this realm */
+ /* See if we have sent authorization header for this realm (and scheme) */
hdr = tdata->msg->hdr.next;
while (hdr != &tdata->msg->hdr) {
if ((hchal->type == PJSIP_H_WWW_AUTHENTICATE &&
@@ -1052,7 +1052,8 @@ static pj_status_t process_auth( pj_pool_t *req_pool,
{
sent_auth = (pjsip_authorization_hdr*) hdr;
if (pj_stricmp(&hchal->challenge.common.realm,
- &sent_auth->credential.common.realm )==0)
+ &sent_auth->credential.common.realm)==0 &&
+ pj_stricmp(&hchal->scheme, &sent_auth->scheme)==0)
{
/* If this authorization has empty response, remove it. */
if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&
@@ -1062,6 +1063,14 @@ static pj_status_t process_auth( pj_pool_t *req_pool,
hdr = hdr->next;
pj_list_erase(sent_auth);
continue;
+ } else
+ if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 &&
+ pj_stricmp(&sent_auth->credential.digest.algorithm,
+ &hchal->challenge.digest.algorithm)!=0)
+ {
+ /* Same 'digest' scheme but different algo */
+ hdr = hdr->next;
+ continue;
} else {
/* Found previous authorization attempt */
break;
@@ -1155,9 +1164,10 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
{
pjsip_tx_data *tdata;
const pjsip_hdr *hdr;
- unsigned chal_cnt;
+ unsigned chal_cnt, auth_cnt;
pjsip_via_hdr *via;
pj_status_t status;
+ pj_status_t last_auth_err;
PJ_ASSERT_RETURN(sess && rdata && old_request && new_request,
PJ_EINVAL);
@@ -1178,6 +1188,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
*/
hdr = rdata->msg_info.msg->hdr.next;
chal_cnt = 0;
+ auth_cnt = 0;
+ last_auth_err = PJSIP_EAUTHNOAUTH;
while (hdr != &rdata->msg_info.msg->hdr) {
pjsip_cached_auth *cached_auth;
const pjsip_www_authenticate_hdr *hchal;
@@ -1222,8 +1234,13 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
*/
status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri,
tdata, sess, cached_auth, &hauth);
- if (status != PJ_SUCCESS)
- return status;
+ if (status != PJ_SUCCESS) {
+ last_auth_err = status;
+
+ /* Process next header. */
+ hdr = hdr->next;
+ continue;
+ }
if (pj_pool_get_used_size(cached_auth->pool) >
PJSIP_AUTH_CACHED_POOL_MAX_SIZE)
@@ -1236,12 +1253,17 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
/* Process next header. */
hdr = hdr->next;
+ auth_cnt++;
}
/* Check if challenge is present */
if (chal_cnt == 0)
return PJSIP_EAUTHNOCHAL;
+ /* Check if any authorization header has been created */
+ if (auth_cnt == 0)
+ return last_auth_err;
+
/* Remove branch param in Via header. */
via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
via->branch_param.slen = 0;
diff --git a/tests/pjsua/scripts-sipp/uas-auth-two-algo.py b/tests/pjsua/scripts-sipp/uas-auth-two-algo.py
new file mode 100644
index 000000000..c79c9f6d3
--- /dev/null
+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.py
@@ -0,0 +1,7 @@
+# $Id$
+#
+import inc_const as const
+
+PJSUA = ["--null-audio --max-calls=1 --id=sip:a@localhost --username=a --realm=* --registrar=$SIPP_URI"]
+
+PJSUA_EXPECTS = [[0, "registration success", ""]]
diff --git a/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml
new file mode 100644
index 000000000..bd4871940
--- /dev/null
+++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="Basic UAS responder">
+ <recv request="REGISTER" crlf="true">
+ </recv>
+
+ <send>
+ <![CDATA[
+ SIP/2.0 100 Trying
+ [last_Via:];received=1.1.1.1;rport=1111
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Content-Length: 0
+ ]]>
+ </send>
+
+ <send>
+ <![CDATA[
+ SIP/2.0 401 Unauthorized
+ [last_Via:];received=1.1.1.1;rport=1111
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=SHA-256, qop="auth"
+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=MD5, qop="auth"
+ WWW-Authenticate: Digest realm="sip.linphone.org", nonce="PARV4gAAAADgw3asAADW8zsi5BEAAAAA", opaque="+GNywA==", algorithm=MD2, qop="auth"
+ Content-Length: 0
+ ]]>
+ </send>
+
+ <recv request="REGISTER" crlf="true">
+ <action>
+ <ereg regexp=".*"
+ search_in="hdr"
+ header="Authorization:"
+ assign_to="have_auth" />
+ </action>
+ </recv>
+
+ <nop next="resp_okay" test="have_auth" />
+
+ <send next="end">
+ <![CDATA[
+ SIP/2.0 403 no auth
+ [last_Via:];received=1.1.1.1;rport=1111
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ [last_Contact:]
+ Content-Length: 0
+ ]]>
+ </send>
+
+ <label id="resp_okay" />
+
+ <send>
+ <![CDATA[
+ SIP/2.0 200 OK
+ [last_Via:];received=1.1.1.1;rport=1111
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ [last_Contact:]
+ Content-Length: 0
+ ]]>
+ </send>
+
+ <label id="end" />
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
--
2.31.1

View File

@@ -1,82 +0,0 @@
commit f0ff5817d0647bdecd1ec99488db9378e304cf83
Author: sauwming <ming@teluu.com>
Date: Mon May 17 09:56:27 2021 +0800
Fix double free of stun session (#2709)
diff --git a/pjnath/include/pjnath/stun_session.h b/pjnath/include/pjnath/stun_session.h
index bee630ab4..afca06911 100644
--- a/pjnath/include/pjnath/stun_session.h
+++ b/pjnath/include/pjnath/stun_session.h
@@ -341,6 +341,7 @@ struct pj_stun_tx_data
pj_pool_t *pool; /**< Pool. */
pj_stun_session *sess; /**< The STUN session. */
pj_stun_msg *msg; /**< The STUN message. */
+ pj_bool_t is_destroying; /**< Is destroying? */
void *token; /**< The token. */
diff --git a/pjnath/src/pjnath/stun_session.c b/pjnath/src/pjnath/stun_session.c
index f2b4f7058..d436b94bf 100644
--- a/pjnath/src/pjnath/stun_session.c
+++ b/pjnath/src/pjnath/stun_session.c
@@ -167,16 +167,27 @@ static void tdata_on_destroy(void *arg)
{
pj_stun_tx_data *tdata = (pj_stun_tx_data*)arg;
+ if (tdata->grp_lock) {
+ pj_grp_lock_dec_ref(tdata->sess->grp_lock);
+ }
+
pj_pool_safe_release(&tdata->pool);
}
static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)
{
- TRACE_((THIS_FILE, "tdata %p destroy request, force=%d, tsx=%p", tdata,
- force, tdata->client_tsx));
+ TRACE_((THIS_FILE,
+ "tdata %p destroy request, force=%d, tsx=%p, destroying=%d",
+ tdata, force, tdata->client_tsx, tdata->is_destroying));
+
+ /* Just return if destroy has been requested before */
+ if (tdata->is_destroying)
+ return;
/* STUN session may have been destroyed, except when tdata is cached. */
+ tdata->is_destroying = PJ_TRUE;
+
if (tdata->res_timer.id != PJ_FALSE) {
pj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap,
&tdata->res_timer, PJ_FALSE);
@@ -189,7 +200,6 @@ static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)
pj_stun_client_tsx_set_data(tdata->client_tsx, NULL);
}
if (tdata->grp_lock) {
- pj_grp_lock_dec_ref(tdata->sess->grp_lock);
pj_grp_lock_dec_ref(tdata->grp_lock);
} else {
tdata_on_destroy(tdata);
@@ -200,11 +210,11 @@ static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force)
/* "Probably" this is to absorb retransmission */
pj_time_val delay = {0, 300};
pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay);
+ tdata->is_destroying = PJ_FALSE;
} else {
pj_list_erase(tdata);
if (tdata->grp_lock) {
- pj_grp_lock_dec_ref(tdata->sess->grp_lock);
pj_grp_lock_dec_ref(tdata->grp_lock);
} else {
tdata_on_destroy(tdata);
@@ -238,7 +248,7 @@ static void on_cache_timeout(pj_timer_heap_t *timer_heap,
sess = tdata->sess;
pj_grp_lock_acquire(sess->grp_lock);
- if (sess->is_destroying) {
+ if (sess->is_destroying || tdata->is_destroying) {
pj_grp_lock_release(sess->grp_lock);
return;
}

View File

@@ -1,166 +0,0 @@
From bb92c97ea512aa0ef316c9b2335c7d57b84dfc9a Mon Sep 17 00:00:00 2001
From: Nanang Izzuddin <nanang@teluu.com>
Date: Wed, 16 Jun 2021 12:12:35 +0700
Subject: [PATCH 1/2] - Avoid SSL socket parent/listener getting destroyed
during handshake by increasing parent's reference count. - Add missing SSL
socket close when the newly accepted SSL socket is discarded in SIP TLS
transport.
---
pjlib/src/pj/ssl_sock_imp_common.c | 44 +++++++++++++++++++++--------
pjsip/src/pjsip/sip_transport_tls.c | 23 ++++++++++++++-
2 files changed, 55 insertions(+), 12 deletions(-)
diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c
index bc468bcb3..abec31805 100644
--- a/pjlib/src/pj/ssl_sock_imp_common.c
+++ b/pjlib/src/pj/ssl_sock_imp_common.c
@@ -224,6 +224,8 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
/* Accepting */
if (ssock->is_server) {
+ pj_bool_t ret = PJ_TRUE;
+
if (status != PJ_SUCCESS) {
/* Handshake failed in accepting, destroy our self silently. */
@@ -241,6 +243,12 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
status);
}
+ /* Decrement ref count of parent */
+ if (ssock->parent->param.grp_lock) {
+ pj_grp_lock_dec_ref(ssock->parent->param.grp_lock);
+ ssock->parent = NULL;
+ }
+
/* Originally, this is a workaround for ticket #985. However,
* a race condition may occur in multiple worker threads
* environment when we are destroying SSL objects while other
@@ -284,23 +292,29 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
return PJ_FALSE;
}
+
/* Notify application the newly accepted SSL socket */
if (ssock->param.cb.on_accept_complete2) {
- pj_bool_t ret;
ret = (*ssock->param.cb.on_accept_complete2)
(ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr,
pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr),
status);
- if (ret == PJ_FALSE)
- return PJ_FALSE;
} else if (ssock->param.cb.on_accept_complete) {
- pj_bool_t ret;
ret = (*ssock->param.cb.on_accept_complete)
(ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr,
pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr));
- if (ret == PJ_FALSE)
- return PJ_FALSE;
}
+
+ /* Decrement ref count of parent and reset parent (we don't need it
+ * anymore, right?).
+ */
+ if (ssock->parent->param.grp_lock) {
+ pj_grp_lock_dec_ref(ssock->parent->param.grp_lock);
+ ssock->parent = NULL;
+ }
+
+ if (ret == PJ_FALSE)
+ return PJ_FALSE;
}
/* Connecting */
@@ -864,9 +878,13 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
if (status != PJ_SUCCESS)
goto on_return;
+ /* Set parent and add ref count (avoid parent destroy during handshake) */
+ ssock->parent = ssock_parent;
+ if (ssock->parent->param.grp_lock)
+ pj_grp_lock_add_ref(ssock->parent->param.grp_lock);
+
/* Update new SSL socket attributes */
ssock->sock = newsock;
- ssock->parent = ssock_parent;
ssock->is_server = PJ_TRUE;
if (ssock_parent->cert) {
status = pj_ssl_sock_set_certificate(ssock, ssock->pool,
@@ -913,16 +931,20 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool,
ssock->param.async_cnt,
sizeof(void*));
- if (!ssock->asock_rbuf)
- return PJ_ENOMEM;
+ if (!ssock->asock_rbuf) {
+ status = PJ_ENOMEM;
+ goto on_return;
+ }
for (i = 0; i<ssock->param.async_cnt; ++i) {
- ssock->asock_rbuf[i] = (void*) pj_pool_alloc(
+ ssock->asock_rbuf[i] = (void*) pj_pool_alloc(
ssock->pool,
ssock->param.read_buffer_size +
sizeof(read_data_t*));
- if (!ssock->asock_rbuf[i])
- return PJ_ENOMEM;
+ if (!ssock->asock_rbuf[i]) {
+ status = PJ_ENOMEM;
+ goto on_return;
+ }
}
/* Create active socket */
diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c
index 17b7ae3de..ce524d53f 100644
--- a/pjsip/src/pjsip/sip_transport_tls.c
+++ b/pjsip/src/pjsip/sip_transport_tls.c
@@ -1325,9 +1325,26 @@ static pj_bool_t on_accept_complete2(pj_ssl_sock_t *ssock,
PJ_UNUSED_ARG(src_addr_len);
listener = (struct tls_listener*) pj_ssl_sock_get_user_data(ssock);
+ if (!listener) {
+ /* Listener already destroyed, e.g: after TCP accept but before SSL
+ * handshake is completed.
+ */
+ if (new_ssock && accept_status == PJ_SUCCESS) {
+ /* Close the SSL socket if the accept op is successful */
+ PJ_LOG(4,(THIS_FILE,
+ "Incoming TLS connection from %s (sock=%d) is discarded "
+ "because listener is already destroyed",
+ pj_sockaddr_print(src_addr, addr, sizeof(addr), 3),
+ new_ssock));
+
+ pj_ssl_sock_close(new_ssock);
+ }
+
+ return PJ_FALSE;
+ }
if (accept_status != PJ_SUCCESS) {
- if (listener && listener->tls_setting.on_accept_fail_cb) {
+ if (listener->tls_setting.on_accept_fail_cb) {
pjsip_tls_on_accept_fail_param param;
pj_ssl_sock_info ssi;
@@ -1350,6 +1367,8 @@ static pj_bool_t on_accept_complete2(pj_ssl_sock_t *ssock,
PJ_ASSERT_RETURN(new_ssock, PJ_TRUE);
if (!listener->is_registered) {
+ pj_ssl_sock_close(new_ssock);
+
if (listener->tls_setting.on_accept_fail_cb) {
pjsip_tls_on_accept_fail_param param;
pj_bzero(&param, sizeof(param));
@@ -1401,6 +1420,8 @@ static pj_bool_t on_accept_complete2(pj_ssl_sock_t *ssock,
ssl_info.grp_lock, &tls);
if (status != PJ_SUCCESS) {
+ pj_ssl_sock_close(new_ssock);
+
if (listener->tls_setting.on_accept_fail_cb) {
pjsip_tls_on_accept_fail_param param;
pj_bzero(&param, sizeof(param));

View File

@@ -1,136 +0,0 @@
From 68c69f516f95df1faa42e5647e9ce7cfdc41ac38 Mon Sep 17 00:00:00 2001
From: Nanang Izzuddin <nanang@teluu.com>
Date: Wed, 16 Jun 2021 12:15:29 +0700
Subject: [PATCH 2/2] - Fix silly mistake: accepted active socket created
without group lock in SSL socket. - Replace assertion with normal validation
check of SSL socket instance in OpenSSL verification callback (verify_cb())
to avoid crash, e.g: if somehow race condition with SSL socket destroy
happens or OpenSSL application data index somehow gets corrupted.
---
pjlib/src/pj/ssl_sock_imp_common.c | 3 +-
pjlib/src/pj/ssl_sock_ossl.c | 45 +++++++++++++++++++++++++-----
2 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c
index bc468bcb3..c2b8a846b 100644
--- a/pjlib/src/pj/ssl_sock_imp_common.c
+++ b/pjlib/src/pj/ssl_sock_imp_common.c
@@ -927,6 +927,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
/* Create active socket */
pj_activesock_cfg_default(&asock_cfg);
+ asock_cfg.grp_lock = ssock->param.grp_lock;
asock_cfg.async_cnt = ssock->param.async_cnt;
asock_cfg.concurrency = ssock->param.concurrency;
asock_cfg.whole_data = PJ_TRUE;
@@ -942,7 +943,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
goto on_return;
pj_grp_lock_add_ref(glock);
- asock_cfg.grp_lock = ssock->param.grp_lock = glock;
+ ssock->param.grp_lock = glock;
pj_grp_lock_add_handler(ssock->param.grp_lock, ssock->pool, ssock,
ssl_on_destroy);
}
diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
index a95b339a5..56841f80a 100644
--- a/pjlib/src/pj/ssl_sock_ossl.c
+++ b/pjlib/src/pj/ssl_sock_ossl.c
@@ -327,7 +327,8 @@ static pj_status_t STATUS_FROM_SSL_ERR(char *action, pj_ssl_sock_t *ssock,
ERROR_LOG("STATUS_FROM_SSL_ERR", err, ssock);
}
- ssock->last_err = err;
+ if (ssock)
+ ssock->last_err = err;
return GET_STATUS_FROM_SSL_ERR(err);
}
@@ -344,7 +345,8 @@ static pj_status_t STATUS_FROM_SSL_ERR2(char *action, pj_ssl_sock_t *ssock,
/* Dig for more from OpenSSL error queue */
SSLLogErrors(action, ret, err, len, ssock);
- ssock->last_err = ssl_err;
+ if (ssock)
+ ssock->last_err = ssl_err;
return GET_STATUS_FROM_SSL_ERR(ssl_err);
}
@@ -587,6 +589,13 @@ static pj_status_t init_openssl(void)
/* Create OpenSSL application data index for SSL socket */
sslsock_idx = SSL_get_ex_new_index(0, "SSL socket", NULL, NULL, NULL);
+ if (sslsock_idx == -1) {
+ status = STATUS_FROM_SSL_ERR2("Init", NULL, -1, ERR_get_error(), 0);
+ PJ_LOG(1,(THIS_FILE,
+ "Fatal error: failed to get application data index for "
+ "SSL socket"));
+ return status;
+ }
return status;
}
@@ -614,21 +623,36 @@ static int password_cb(char *buf, int num, int rwflag, void *user_data)
}
-/* SSL password callback. */
+/* SSL certificate verification result callback.
+ * Note that this callback seems to be always called from library worker
+ * thread, e.g: active socket on_read_complete callback, which should have
+ * already been equipped with race condition avoidance mechanism (should not
+ * be destroyed while callback is being invoked).
+ */
static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
- pj_ssl_sock_t *ssock;
- SSL *ossl_ssl;
+ pj_ssl_sock_t *ssock = NULL;
+ SSL *ossl_ssl = NULL;
int err;
/* Get SSL instance */
ossl_ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
SSL_get_ex_data_X509_STORE_CTX_idx());
- pj_assert(ossl_ssl);
+ if (!ossl_ssl) {
+ PJ_LOG(1,(THIS_FILE,
+ "SSL verification callback failed to get SSL instance"));
+ goto on_return;
+ }
/* Get SSL socket instance */
ssock = SSL_get_ex_data(ossl_ssl, sslsock_idx);
- pj_assert(ssock);
+ if (!ssock) {
+ /* SSL socket may have been destroyed */
+ PJ_LOG(1,(THIS_FILE,
+ "SSL verification callback failed to get SSL socket "
+ "instance (sslsock_idx=%d).", sslsock_idx));
+ goto on_return;
+ }
/* Store verification status */
err = X509_STORE_CTX_get_error(x509_ctx);
@@ -706,6 +730,7 @@ static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
if (PJ_FALSE == ssock->param.verify_peer)
preverify_ok = 1;
+on_return:
return preverify_ok;
}
@@ -1213,6 +1238,12 @@ static void ssl_destroy(pj_ssl_sock_t *ssock)
static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
{
ossl_sock_t *ossock = (ossl_sock_t *)ssock;
+
+ /* Detach from SSL instance */
+ if (ossock->ossl_ssl) {
+ SSL_set_ex_data(ossock->ossl_ssl, sslsock_idx, NULL);
+ }
+
/**
* Avoid calling SSL_shutdown() if handshake wasn't completed.
* OpenSSL 1.0.2f complains if SSL_shutdown() is called during an

View File

@@ -1,32 +0,0 @@
From 2ae784030b0d9cf217c3d562af20e4967f19a3dc Mon Sep 17 00:00:00 2001
From: George Joseph <gjoseph@sangoma.com>
Date: Tue, 14 Sep 2021 10:47:29 -0600
Subject: [PATCH] pjmedia_sdp_attr_get_rtpmap: Strip param trailing whitespace
Use pj_scan_get() to parse the param part of rtpmap so
trailing whitespace is automatically stripped.
Fixes #2827
---
pjmedia/src/pjmedia/sdp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pjmedia/src/pjmedia/sdp.c b/pjmedia/src/pjmedia/sdp.c
index 5d05a0d9c..3448749c9 100644
--- a/pjmedia/src/pjmedia/sdp.c
+++ b/pjmedia/src/pjmedia/sdp.c
@@ -313,9 +313,9 @@ PJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtpmap( const pjmedia_sdp_attr *attr,
/* Expecting either '/' or EOF */
if (*scanner.curptr == '/') {
+ /* Skip the '/' */
pj_scan_get_char(&scanner);
- rtpmap->param.ptr = scanner.curptr;
- rtpmap->param.slen = scanner.end - scanner.curptr;
+ pj_scan_get(&scanner, &cs_token, &rtpmap->param);
} else {
rtpmap->param.slen = 0;
}
--
2.31.1

View File

@@ -1,661 +0,0 @@
From 0ed41eb5fd0e4192e1b7dc374f819d17aef3e805 Mon Sep 17 00:00:00 2001
From: George Joseph <gtjoseph@users.noreply.github.com>
Date: Tue, 21 Dec 2021 19:32:22 -0700
Subject: [PATCH] sip_inv: Additional multipart support (#2919) (#2920)
---
pjsip/include/pjsip-ua/sip_inv.h | 108 ++++++++++-
pjsip/src/pjsip-ua/sip_inv.c | 240 ++++++++++++++++++++-----
pjsip/src/test/inv_offer_answer_test.c | 103 ++++++++++-
3 files changed, 394 insertions(+), 57 deletions(-)
diff --git a/pjsip/include/pjsip-ua/sip_inv.h b/pjsip/include/pjsip-ua/sip_inv.h
index 14f2d23fa..c33551786 100644
--- a/pjsip/include/pjsip-ua/sip_inv.h
+++ b/pjsip/include/pjsip-ua/sip_inv.h
@@ -451,11 +451,11 @@ struct pjsip_inv_session
/**
- * This structure represents SDP information in a pjsip_rx_data. Application
- * retrieve this information by calling #pjsip_rdata_get_sdp_info(). This
+ * This structure represents SDP information in a pjsip_(rx|tx)_data. Application
+ * retrieve this information by calling #pjsip_get_sdp_info(). This
* mechanism supports multipart message body.
*/
-typedef struct pjsip_rdata_sdp_info
+typedef struct pjsip_sdp_info
{
/**
* Pointer and length of the text body in the incoming message. If
@@ -475,7 +475,15 @@ typedef struct pjsip_rdata_sdp_info
*/
pjmedia_sdp_session *sdp;
-} pjsip_rdata_sdp_info;
+} pjsip_sdp_info;
+
+/**
+ * For backwards compatibility and completeness,
+ * pjsip_rdata_sdp_info and pjsip_tdata_sdp_info
+ * are typedef'd to pjsip_sdp_info.
+ */
+typedef pjsip_sdp_info pjsip_rdata_sdp_info;
+typedef pjsip_sdp_info pjsip_tdata_sdp_info;
/**
@@ -1045,6 +1053,44 @@ PJ_DECL(pj_status_t) pjsip_create_sdp_body(pj_pool_t *pool,
pjmedia_sdp_session *sdp,
pjsip_msg_body **p_body);
+/**
+ * This is a utility function to create a multipart body with the
+ * SIP body as the first part.
+ *
+ * @param pool Pool to allocate memory.
+ * @param sdp SDP session to be put in the SIP message body.
+ * @param p_body Pointer to receive SIP message body containing
+ * the SDP session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_create_multipart_sdp_body( pj_pool_t *pool,
+ pjmedia_sdp_session *sdp,
+ pjsip_msg_body **p_body);
+
+/**
+ * Retrieve SDP information from a message body. Application should
+ * prefer to use this function rather than parsing the SDP manually since
+ * this function supports multipart message body.
+ *
+ * This function will only parse the SDP once, the first time it is called
+ * on the same message. Subsequent call on the same message will just pick
+ * up the already parsed SDP from the message.
+ *
+ * @param pool Pool to allocate memory.
+ * @param body The message body.
+ * @param msg_media_type From the rdata or tdata Content-Type header, if available.
+ * If NULL, the content_type from the body will be used.
+ * @param search_media_type The media type to search for.
+ * If NULL, "application/sdp" will be used.
+ *
+ * @return The SDP info.
+ */
+PJ_DECL(pjsip_sdp_info*) pjsip_get_sdp_info(pj_pool_t *pool,
+ pjsip_msg_body *body,
+ pjsip_media_type *msg_media_type,
+ const pjsip_media_type *search_media_type);
+
/**
* Retrieve SDP information from an incoming message. Application should
* prefer to use this function rather than parsing the SDP manually since
@@ -1061,6 +1107,60 @@ PJ_DECL(pj_status_t) pjsip_create_sdp_body(pj_pool_t *pool,
PJ_DECL(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata);
+/**
+ * Retrieve SDP information from an incoming message. Application should
+ * prefer to use this function rather than parsing the SDP manually since
+ * this function supports multipart message body.
+ *
+ * This function will only parse the SDP once, the first time it is called
+ * on the same message. Subsequent call on the same message will just pick
+ * up the already parsed SDP from the message.
+ *
+ * @param rdata The incoming message.
+ * @param search_media_type The SDP media type to search for.
+ * If NULL, "application/sdp" will be used.
+ *
+ * @return The SDP info.
+ */
+PJ_DECL(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info2(
+ pjsip_rx_data *rdata,
+ const pjsip_media_type *search_media_type);
+
+/**
+ * Retrieve SDP information from an outgoing message. Application should
+ * prefer to use this function rather than parsing the SDP manually since
+ * this function supports multipart message body.
+ *
+ * This function will only parse the SDP once, the first time it is called
+ * on the same message. Subsequent call on the same message will just pick
+ * up the already parsed SDP from the message.
+ *
+ * @param tdata The outgoing message.
+ *
+ * @return The SDP info.
+ */
+PJ_DECL(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info(pjsip_tx_data *tdata);
+
+/**
+ * Retrieve SDP information from an outgoing message. Application should
+ * prefer to use this function rather than parsing the SDP manually since
+ * this function supports multipart message body.
+ *
+ * This function will only parse the SDP once, the first time it is called
+ * on the same message. Subsequent call on the same message will just pick
+ * up the already parsed SDP from the message.
+ *
+ * @param tdata The outgoing message.
+ * @param search_media_type The SDP media type to search for.
+ * If NULL, "application/sdp" will be used.
+ *
+ * @return The SDP info.
+ */
+PJ_DECL(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info2(
+ pjsip_tx_data *tdata,
+ const pjsip_media_type *search_media_type);
+
+
PJ_END_DECL
/**
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index ca225015b..b68ae0f16 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -118,6 +118,8 @@ static pj_status_t handle_timer_response(pjsip_inv_session *inv,
static pj_bool_t inv_check_secure_dlg(pjsip_inv_session *inv,
pjsip_event *e);
+static int print_sdp(pjsip_msg_body *body, char *buf, pj_size_t len);
+
static void (*inv_state_handler[])( pjsip_inv_session *inv, pjsip_event *e) =
{
&inv_on_state_null,
@@ -946,66 +948,170 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uac( pjsip_dialog *dlg,
return PJ_SUCCESS;
}
-PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata)
+PJ_DEF(pjsip_sdp_info*) pjsip_get_sdp_info(pj_pool_t *pool,
+ pjsip_msg_body *body,
+ pjsip_media_type *msg_media_type,
+ const pjsip_media_type *search_media_type)
{
- pjsip_rdata_sdp_info *sdp_info;
- pjsip_msg_body *body = rdata->msg_info.msg->body;
- pjsip_ctype_hdr *ctype_hdr = rdata->msg_info.ctype;
- pjsip_media_type app_sdp;
+ pjsip_sdp_info *sdp_info;
+ pjsip_media_type search_type;
+ pjsip_media_type multipart_mixed;
+ pjsip_media_type multipart_alternative;
+ pjsip_media_type *msg_type;
+ pj_status_t status;
- sdp_info = (pjsip_rdata_sdp_info*)
- rdata->endpt_info.mod_data[mod_inv.mod.id];
- if (sdp_info)
- return sdp_info;
+ sdp_info = PJ_POOL_ZALLOC_T(pool,
+ pjsip_sdp_info);
- sdp_info = PJ_POOL_ZALLOC_T(rdata->tp_info.pool,
- pjsip_rdata_sdp_info);
PJ_ASSERT_RETURN(mod_inv.mod.id >= 0, sdp_info);
- rdata->endpt_info.mod_data[mod_inv.mod.id] = sdp_info;
- pjsip_media_type_init2(&app_sdp, "application", "sdp");
+ if (!body) {
+ return sdp_info;
+ }
- if (body && ctype_hdr &&
- pj_stricmp(&ctype_hdr->media.type, &app_sdp.type)==0 &&
- pj_stricmp(&ctype_hdr->media.subtype, &app_sdp.subtype)==0)
+ if (msg_media_type) {
+ msg_type = msg_media_type;
+ } else {
+ if (body->content_type.type.slen == 0) {
+ return sdp_info;
+ }
+ msg_type = &body->content_type;
+ }
+
+ if (!search_media_type) {
+ pjsip_media_type_init2(&search_type, "application", "sdp");
+ } else {
+ pj_memcpy(&search_type, search_media_type, sizeof(search_type));
+ }
+
+ pjsip_media_type_init2(&multipart_mixed, "multipart", "mixed");
+ pjsip_media_type_init2(&multipart_alternative, "multipart", "alternative");
+
+ if (pjsip_media_type_cmp(msg_type, &search_type, PJ_FALSE) == 0)
{
- sdp_info->body.ptr = (char*)body->data;
- sdp_info->body.slen = body->len;
- } else if (body && ctype_hdr &&
- pj_stricmp2(&ctype_hdr->media.type, "multipart")==0 &&
- (pj_stricmp2(&ctype_hdr->media.subtype, "mixed")==0 ||
- pj_stricmp2(&ctype_hdr->media.subtype, "alternative")==0))
+ /*
+ * If the print_body function is print_sdp, we know that
+ * body->data is a pjmedia_sdp_session object and came from
+ * a tx_data. If not, it's the text representation of the
+ * sdp from an rx_data.
+ */
+ if (body->print_body == print_sdp) {
+ sdp_info->sdp = body->data;
+ } else {
+ sdp_info->body.ptr = (char*)body->data;
+ sdp_info->body.slen = body->len;
+ }
+ } else if (pjsip_media_type_cmp(&multipart_mixed, msg_type, PJ_FALSE) == 0 ||
+ pjsip_media_type_cmp(&multipart_alternative, msg_type, PJ_FALSE) == 0)
{
- pjsip_multipart_part *part;
+ pjsip_multipart_part *part;
+ part = pjsip_multipart_find_part(body, &search_type, NULL);
+ if (part) {
+ if (part->body->print_body == print_sdp) {
+ sdp_info->sdp = part->body->data;
+ } else {
+ sdp_info->body.ptr = (char*)part->body->data;
+ sdp_info->body.slen = part->body->len;
+ }
+ }
+ }
- part = pjsip_multipart_find_part(body, &app_sdp, NULL);
- if (part) {
- sdp_info->body.ptr = (char*)part->body->data;
- sdp_info->body.slen = part->body->len;
- }
+ /*
+ * If the body was already a pjmedia_sdp_session, we can just
+ * return it. If not and there wasn't a text representation
+ * of the sdp either, we can also just return.
+ */
+ if (sdp_info->sdp || !sdp_info->body.ptr) {
+ return sdp_info;
}
- if (sdp_info->body.ptr) {
- pj_status_t status;
- status = pjmedia_sdp_parse(rdata->tp_info.pool,
- sdp_info->body.ptr,
- sdp_info->body.slen,
- &sdp_info->sdp);
- if (status == PJ_SUCCESS)
- status = pjmedia_sdp_validate2(sdp_info->sdp, PJ_FALSE);
+ /*
+ * If the body was the text representation of teh SDP, we need
+ * to parse it to create a pjmedia_sdp_session object.
+ */
+ status = pjmedia_sdp_parse(pool,
+ sdp_info->body.ptr,
+ sdp_info->body.slen,
+ &sdp_info->sdp);
+ if (status == PJ_SUCCESS)
+ status = pjmedia_sdp_validate2(sdp_info->sdp, PJ_FALSE);
- if (status != PJ_SUCCESS) {
- sdp_info->sdp = NULL;
- PJ_PERROR(1,(THIS_FILE, status,
- "Error parsing/validating SDP body"));
- }
+ if (status != PJ_SUCCESS) {
+ sdp_info->sdp = NULL;
+ PJ_PERROR(1, (THIS_FILE, status,
+ "Error parsing/validating SDP body"));
+ }
+
+ sdp_info->sdp_err = status;
+
+ return sdp_info;
+}
- sdp_info->sdp_err = status;
+PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info2(
+ pjsip_rx_data *rdata,
+ const pjsip_media_type *search_media_type)
+{
+ pjsip_media_type *msg_media_type = NULL;
+ pjsip_rdata_sdp_info *sdp_info;
+
+ if (rdata->endpt_info.mod_data[mod_inv.mod.id]) {
+ return (pjsip_rdata_sdp_info *)rdata->endpt_info.mod_data[mod_inv.mod.id];
+ }
+
+ /*
+ * rdata should have a Content-Type header at this point but we'll
+ * make sure.
+ */
+ if (rdata->msg_info.ctype) {
+ msg_media_type = &rdata->msg_info.ctype->media;
+ }
+ sdp_info = pjsip_get_sdp_info(rdata->tp_info.pool,
+ rdata->msg_info.msg->body,
+ msg_media_type,
+ search_media_type);
+ rdata->endpt_info.mod_data[mod_inv.mod.id] = sdp_info;
+
+ return sdp_info;
+}
+
+PJ_DEF(pjsip_rdata_sdp_info*) pjsip_rdata_get_sdp_info(pjsip_rx_data *rdata)
+{
+ return pjsip_rdata_get_sdp_info2(rdata, NULL);
+}
+
+PJ_DEF(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info2(
+ pjsip_tx_data *tdata,
+ const pjsip_media_type *search_media_type)
+{
+ pjsip_ctype_hdr *ctype_hdr = NULL;
+ pjsip_media_type *msg_media_type = NULL;
+ pjsip_tdata_sdp_info *sdp_info;
+
+ if (tdata->mod_data[mod_inv.mod.id]) {
+ return (pjsip_tdata_sdp_info *)tdata->mod_data[mod_inv.mod.id];
+ }
+ /*
+ * tdata won't usually have a Content-Type header at this point
+ * but we'll check just the same,
+ */
+ ctype_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTENT_TYPE, NULL);
+ if (ctype_hdr) {
+ msg_media_type = &ctype_hdr->media;
}
+ sdp_info = pjsip_get_sdp_info(tdata->pool,
+ tdata->msg->body,
+ msg_media_type,
+ search_media_type);
+ tdata->mod_data[mod_inv.mod.id] = sdp_info;
+
return sdp_info;
}
+PJ_DEF(pjsip_tdata_sdp_info*) pjsip_tdata_get_sdp_info(pjsip_tx_data *tdata)
+{
+ return pjsip_tdata_get_sdp_info2(tdata, NULL);
+}
/*
* Verify incoming INVITE request.
@@ -1730,13 +1836,55 @@ PJ_DEF(pj_status_t) pjsip_create_sdp_body( pj_pool_t *pool,
return PJ_SUCCESS;
}
+static pjsip_multipart_part* create_sdp_part(pj_pool_t *pool, pjmedia_sdp_session *sdp)
+{
+ pjsip_multipart_part *sdp_part;
+ pjsip_media_type media_type;
+
+ pjsip_media_type_init2(&media_type, "application", "sdp");
+
+ sdp_part = pjsip_multipart_create_part(pool);
+ PJ_ASSERT_RETURN(sdp_part != NULL, NULL);
+
+ sdp_part->body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);
+ PJ_ASSERT_RETURN(sdp_part->body != NULL, NULL);
+
+ pjsip_media_type_cp(pool, &sdp_part->body->content_type, &media_type);
+
+ sdp_part->body->data = sdp;
+ sdp_part->body->clone_data = clone_sdp;
+ sdp_part->body->print_body = print_sdp;
+
+ return sdp_part;
+}
+
+PJ_DEF(pj_status_t) pjsip_create_multipart_sdp_body(pj_pool_t *pool,
+ pjmedia_sdp_session *sdp,
+ pjsip_msg_body **p_body)
+{
+ pjsip_media_type media_type;
+ pjsip_msg_body *multipart;
+ pjsip_multipart_part *sdp_part;
+
+ pjsip_media_type_init2(&media_type, "multipart", "mixed");
+ multipart = pjsip_multipart_create(pool, &media_type, NULL);
+ PJ_ASSERT_RETURN(multipart != NULL, PJ_ENOMEM);
+
+ sdp_part = create_sdp_part(pool, sdp);
+ PJ_ASSERT_RETURN(sdp_part != NULL, PJ_ENOMEM);
+ pjsip_multipart_add_part(pool, multipart, sdp_part);
+ *p_body = multipart;
+
+ return PJ_SUCCESS;
+}
+
static pjsip_msg_body *create_sdp_body(pj_pool_t *pool,
const pjmedia_sdp_session *c_sdp)
{
pjsip_msg_body *body;
pj_status_t status;
- status = pjsip_create_sdp_body(pool,
+ status = pjsip_create_sdp_body(pool,
pjmedia_sdp_session_clone(pool, c_sdp),
&body);
@@ -2059,6 +2207,7 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
)
)
{
+ pjsip_sdp_info *tdata_sdp_info;
const pjmedia_sdp_session *reoffer_sdp = NULL;
PJ_LOG(4,(inv->obj_name, "Received %s response "
@@ -2067,14 +2216,15 @@ static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv,
(st_code/10==18? "early" : "final" )));
/* Retrieve original SDP offer from INVITE request */
- reoffer_sdp = (const pjmedia_sdp_session*)
- tsx->last_tx->msg->body->data;
+ tdata_sdp_info = pjsip_tdata_get_sdp_info(tsx->last_tx);
+ reoffer_sdp = tdata_sdp_info->sdp;
/* Feed the original offer to negotiator */
status = pjmedia_sdp_neg_modify_local_offer2(inv->pool_prov,
inv->neg,
inv->sdp_neg_flags,
reoffer_sdp);
+
if (status != PJ_SUCCESS) {
PJ_LOG(1,(inv->obj_name, "Error updating local offer for "
"forked 2xx/18x response (err=%d)", status));
diff --git a/pjsip/src/test/inv_offer_answer_test.c b/pjsip/src/test/inv_offer_answer_test.c
index ad5fcd409..9cdd2654b 100644
--- a/pjsip/src/test/inv_offer_answer_test.c
+++ b/pjsip/src/test/inv_offer_answer_test.c
@@ -137,6 +137,7 @@ typedef struct inv_test_param_t
pj_bool_t need_established;
unsigned count;
oa_t oa[4];
+ pj_bool_t multipart_body;
} inv_test_param_t;
typedef struct inv_test_t
@@ -257,6 +258,17 @@ static void on_media_update(pjsip_inv_session *inv_ses,
}
}
+ /* Special handling for standard offer/answer */
+ if (inv_test.param.count == 1 &&
+ inv_test.param.oa[0] == OFFERER_UAC &&
+ inv_test.param.need_established)
+ {
+ jobs[job_cnt].type = ESTABLISH_CALL;
+ jobs[job_cnt].who = PJSIP_ROLE_UAS;
+ job_cnt++;
+ TRACE_((THIS_FILE, " C+++"));
+ }
+
pj_assert(job_cnt <= PJ_ARRAY_SIZE(jobs));
}
}
@@ -333,6 +345,15 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata)
NULL, &tdata);
pj_assert(status == PJ_SUCCESS);
+ /* Use multipart body, if configured */
+ if (sdp && inv_test.param.multipart_body) {
+ status = pjsip_create_multipart_sdp_body(
+ tdata->pool,
+ pjmedia_sdp_session_clone(tdata->pool, sdp),
+ &tdata->msg->body);
+ }
+ pj_assert(status == PJ_SUCCESS);
+
status = pjsip_inv_send_msg(inv_test.uas, tdata);
pj_assert(status == PJ_SUCCESS);
@@ -426,6 +447,7 @@ static int perform_test(inv_test_param_t *param)
sdp = NULL;
status = pjsip_inv_create_uac(dlg, sdp, inv_test.param.inv_option, &inv_test.uac);
+ //inv_test.uac->create_multipart = param->multipart_body;
PJ_ASSERT_RETURN(status==PJ_SUCCESS, -20);
TRACE_((THIS_FILE, " Sending INVITE %s offer", (sdp ? "with" : "without")));
@@ -436,8 +458,17 @@ static int perform_test(inv_test_param_t *param)
status = pjsip_inv_invite(inv_test.uac, &tdata);
PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30);
+ /* Use multipart body, if configured */
+ if (sdp && param->multipart_body) {
+ status = pjsip_create_multipart_sdp_body(
+ tdata->pool,
+ pjmedia_sdp_session_clone(tdata->pool, sdp),
+ &tdata->msg->body);
+ }
+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, -40);
+
status = pjsip_inv_send_msg(inv_test.uac, tdata);
- PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30);
+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, -50);
/*
* Wait until test completes
@@ -525,13 +556,14 @@ static inv_test_param_t test_params[] =
200/INVITE (answer) <--
ACK -->
*/
-#if 0
+#if 1
{
"Standard INVITE with offer",
0,
PJ_TRUE,
1,
- { OFFERER_UAC }
+ { OFFERER_UAC },
+ PJ_FALSE
},
{
@@ -539,7 +571,25 @@ static inv_test_param_t test_params[] =
PJSIP_INV_REQUIRE_100REL,
PJ_TRUE,
1,
- { OFFERER_UAC }
+ { OFFERER_UAC },
+ PJ_FALSE
+ },
+ {
+ "Standard INVITE with offer, with Multipart",
+ 0,
+ PJ_TRUE,
+ 1,
+ { OFFERER_UAC },
+ PJ_TRUE
+ },
+
+ {
+ "Standard INVITE with offer, with 100rel, with Multipart",
+ PJSIP_INV_REQUIRE_100REL,
+ PJ_TRUE,
+ 1,
+ { OFFERER_UAC },
+ PJ_TRUE
},
#endif
@@ -555,7 +605,8 @@ static inv_test_param_t test_params[] =
0,
PJ_TRUE,
1,
- { OFFERER_UAS }
+ { OFFERER_UAS },
+ PJ_FALSE
},
{
@@ -563,7 +614,25 @@ static inv_test_param_t test_params[] =
PJSIP_INV_REQUIRE_100REL,
PJ_TRUE,
1,
- { OFFERER_UAS }
+ { OFFERER_UAS },
+ PJ_FALSE
+ },
+ {
+ "INVITE with no offer, with Multipart",
+ 0,
+ PJ_TRUE,
+ 1,
+ { OFFERER_UAS },
+ PJ_TRUE
+ },
+
+ {
+ "INVITE with no offer, with 100rel, with Multipart",
+ PJSIP_INV_REQUIRE_100REL,
+ PJ_TRUE,
+ 1,
+ { OFFERER_UAS },
+ PJ_TRUE
},
#endif
@@ -584,14 +653,24 @@ static inv_test_param_t test_params[] =
0,
PJ_TRUE,
2,
- { OFFERER_UAC, OFFERER_UAC }
+ { OFFERER_UAC, OFFERER_UAC },
+ PJ_FALSE
+ },
+ {
+ "INVITE and UPDATE by UAC, with Multipart",
+ 0,
+ PJ_TRUE,
+ 2,
+ { OFFERER_UAC, OFFERER_UAC },
+ PJ_TRUE
},
{
"INVITE and UPDATE by UAC, with 100rel",
PJSIP_INV_REQUIRE_100REL,
PJ_TRUE,
2,
- { OFFERER_UAC, OFFERER_UAC }
+ { OFFERER_UAC, OFFERER_UAC },
+ PJ_FALSE
},
#endif
@@ -617,6 +696,14 @@ static inv_test_param_t test_params[] =
4,
{ OFFERER_UAC, OFFERER_UAS, OFFERER_UAC, OFFERER_UAS }
},
+ {
+ "INVITE and many UPDATE by UAC and UAS, with Multipart",
+ 0,
+ PJ_TRUE,
+ 4,
+ { OFFERER_UAC, OFFERER_UAS, OFFERER_UAC, OFFERER_UAS },
+ PJ_TRUE
+ },
};
--
2.33.1

View File

@@ -1,176 +0,0 @@
From 7e3dfd8a15fd0f98dbf0e04d2d7a5bded90ee401 Mon Sep 17 00:00:00 2001
From: George Joseph <gjoseph@sangoma.com>
Date: Tue, 11 Jan 2022 09:27:23 -0700
Subject: [PATCH] Create generic pjsip_hdr_find functions
pjsip_msg_find_hdr(), pjsip_msg_find_hdr_by_name(), and
pjsip_msg_find_hdr_by_names() require a pjsip_msg to be passed in
so if you need to search a header list that's not in a pjsip_msg,
you have to do it yourself. This commit adds generic versions of
those 3 functions that take in the actual header list head instead
of a pjsip_msg so if you need to search a list of headers in
something like a pjsip_multipart_part, you can do so easily.
---
pjsip/include/pjsip/sip_msg.h | 53 +++++++++++++++++++++++++++++++++++
pjsip/src/pjsip/sip_msg.c | 51 +++++++++++++++++++++++----------
2 files changed, 89 insertions(+), 15 deletions(-)
diff --git a/pjsip/include/pjsip/sip_msg.h b/pjsip/include/pjsip/sip_msg.h
index 4c9100d39..e3502e94e 100644
--- a/pjsip/include/pjsip/sip_msg.h
+++ b/pjsip/include/pjsip/sip_msg.h
@@ -362,6 +362,59 @@ PJ_DECL(void*) pjsip_hdr_shallow_clone( pj_pool_t *pool, const void *hdr );
*/
PJ_DECL(int) pjsip_hdr_print_on( void *hdr, char *buf, pj_size_t len);
+/**
+ * Find a header in a header list by the header type.
+ *
+ * @param hdr_list The "head" of the header list.
+ * @param type The header type to find.
+ * @param start The first header field where the search should begin.
+ * If NULL is specified, then the search will begin from the
+ * first header, otherwise the search will begin at the
+ * specified header.
+ *
+ * @return The header field, or NULL if no header with the specified
+ * type is found.
+ */
+PJ_DECL(void*) pjsip_hdr_find( const void *hdr_list,
+ pjsip_hdr_e type,
+ const void *start);
+
+/**
+ * Find a header in a header list by its name.
+ *
+ * @param hdr_list The "head" of the header list.
+ * @param name The header name to find.
+ * @param start The first header field where the search should begin.
+ * If NULL is specified, then the search will begin from the
+ * first header, otherwise the search will begin at the
+ * specified header.
+ *
+ * @return The header field, or NULL if no header with the specified
+ * type is found.
+ */
+PJ_DECL(void*) pjsip_hdr_find_by_name( const void *hdr_list,
+ const pj_str_t *name,
+ const void *start);
+
+/**
+ * Find a header in a header list by its name and short name version.
+ *
+ * @param hdr_list The "head" of the header list.
+ * @param name The header name to find.
+ * @param sname The short name version of the header name.
+ * @param start The first header field where the search should begin.
+ * If NULL is specified, then the search will begin from the
+ * first header, otherwise the search will begin at the
+ * specified header.
+ *
+ * @return The header field, or NULL if no header with the specified
+ * type is found.
+ */
+PJ_DECL(void*) pjsip_hdr_find_by_names( const void *hdr_list,
+ const pj_str_t *name,
+ const pj_str_t *sname,
+ const void *start);
+
/**
* @}
*/
diff --git a/pjsip/src/pjsip/sip_msg.c b/pjsip/src/pjsip/sip_msg.c
index 6ba3054da..2a6a96af0 100644
--- a/pjsip/src/pjsip/sip_msg.c
+++ b/pjsip/src/pjsip/sip_msg.c
@@ -356,13 +356,13 @@ PJ_DEF(pjsip_msg*) pjsip_msg_clone( pj_pool_t *pool, const pjsip_msg *src)
return dst;
}
-PJ_DEF(void*) pjsip_msg_find_hdr( const pjsip_msg *msg,
- pjsip_hdr_e hdr_type, const void *start)
+PJ_DEF(void*) pjsip_hdr_find( const void *hdr_list,
+ pjsip_hdr_e hdr_type, const void *start)
{
- const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=&msg->hdr;
+ const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=hdr_list;
if (hdr == NULL) {
- hdr = msg->hdr.next;
+ hdr = end->next;
}
for (; hdr!=end; hdr = hdr->next) {
if (hdr->type == hdr_type)
@@ -371,14 +371,14 @@ PJ_DEF(void*) pjsip_msg_find_hdr( const pjsip_msg *msg,
return NULL;
}
-PJ_DEF(void*) pjsip_msg_find_hdr_by_name( const pjsip_msg *msg,
- const pj_str_t *name,
- const void *start)
+PJ_DEF(void*) pjsip_hdr_find_by_name( const void *hdr_list,
+ const pj_str_t *name,
+ const void *start)
{
- const pjsip_hdr *hdr=(const pjsip_hdr*)start, *end=&msg->hdr;
+ const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=hdr_list;
if (hdr == NULL) {
- hdr = msg->hdr.next;
+ hdr = end->next;
}
for (; hdr!=end; hdr = hdr->next) {
if (pj_stricmp(&hdr->name, name) == 0)
@@ -387,15 +387,15 @@ PJ_DEF(void*) pjsip_msg_find_hdr_by_name( const pjsip_msg *msg,
return NULL;
}
-PJ_DEF(void*) pjsip_msg_find_hdr_by_names( const pjsip_msg *msg,
- const pj_str_t *name,
- const pj_str_t *sname,
- const void *start)
+PJ_DEF(void*) pjsip_hdr_find_by_names( const void *hdr_list,
+ const pj_str_t *name,
+ const pj_str_t *sname,
+ const void *start)
{
- const pjsip_hdr *hdr=(const pjsip_hdr*)start, *end=&msg->hdr;
+ const pjsip_hdr *hdr=(const pjsip_hdr*) start, *end=hdr_list;
if (hdr == NULL) {
- hdr = msg->hdr.next;
+ hdr = end->next;
}
for (; hdr!=end; hdr = hdr->next) {
if (pj_stricmp(&hdr->name, name) == 0)
@@ -406,6 +406,27 @@ PJ_DEF(void*) pjsip_msg_find_hdr_by_names( const pjsip_msg *msg,
return NULL;
}
+PJ_DEF(void*) pjsip_msg_find_hdr( const pjsip_msg *msg,
+ pjsip_hdr_e hdr_type, const void *start)
+{
+ return pjsip_hdr_find(&msg->hdr, hdr_type, start);
+}
+
+PJ_DEF(void*) pjsip_msg_find_hdr_by_name( const pjsip_msg *msg,
+ const pj_str_t *name,
+ const void *start)
+{
+ return pjsip_hdr_find_by_name(&msg->hdr, name, start);
+}
+
+PJ_DEF(void*) pjsip_msg_find_hdr_by_names( const pjsip_msg *msg,
+ const pj_str_t *name,
+ const pj_str_t *sname,
+ const void *start)
+{
+ return pjsip_hdr_find_by_names(&msg->hdr, name, sname, start);
+}
+
PJ_DEF(void*) pjsip_msg_find_remove_hdr( pjsip_msg *msg,
pjsip_hdr_e hdr_type, void *start)
{
--
2.34.1

View File

@@ -1,644 +0,0 @@
From b7ecff22e77887626fd8e8608c4dd73bc7b7366f Mon Sep 17 00:00:00 2001
From: George Joseph <gjoseph@sangoma.com>
Date: Tue, 18 Jan 2022 06:14:31 -0700
Subject: [PATCH] Additional multipart improvements
Added the following APIs:
pjsip_multipart_find_part_by_header()
pjsip_multipart_find_part_by_header_str()
pjsip_multipart_find_part_by_cid_str()
pjsip_multipart_find_part_by_cid_uri()
---
pjsip/include/pjsip/sip_multipart.h | 83 ++++++++++
pjsip/src/pjsip/sip_multipart.c | 223 +++++++++++++++++++++++++++
pjsip/src/test/multipart_test.c | 225 +++++++++++++++++++++++++++-
3 files changed, 530 insertions(+), 1 deletion(-)
diff --git a/pjsip/include/pjsip/sip_multipart.h b/pjsip/include/pjsip/sip_multipart.h
index 1c05767c5..c6b82b0b4 100644
--- a/pjsip/include/pjsip/sip_multipart.h
+++ b/pjsip/include/pjsip/sip_multipart.h
@@ -153,6 +153,89 @@ pjsip_multipart_find_part( const pjsip_msg_body *mp,
const pjsip_media_type *content_type,
const pjsip_multipart_part *start);
+/**
+ * Find a body inside multipart bodies which has a header matching the
+ * supplied one. Most useful for finding a part with a specific Content-ID.
+ *
+ * @param pool Memory pool to use for temp space.
+ * @param mp The multipart body.
+ * @param search_hdr Header to search for.
+ * @param start If specified, the search will begin at
+ * start->next part. Otherwise it will begin at
+ * the first part in the multipart bodies.
+ *
+ * @return The first part which has a header matching the
+ * specified one, or NULL if not found.
+ */
+PJ_DECL(pjsip_multipart_part*)
+pjsip_multipart_find_part_by_header(pj_pool_t *pool,
+ const pjsip_msg_body *mp,
+ void *search_hdr,
+ const pjsip_multipart_part *start);
+
+/**
+ * Find a body inside multipart bodies which has a header matching the
+ * supplied name and value. Most useful for finding a part with a specific
+ * Content-ID.
+ *
+ * @param pool Memory pool to use for temp space.
+ * @param mp The multipart body.
+ * @param hdr_name Header name to search for.
+ * @param hdr_value Header value search for.
+ * @param start If specified, the search will begin at
+ * start->next part. Otherwise it will begin at
+ * the first part in the multipart bodies.
+ *
+ * @return The first part which has a header matching the
+ * specified one, or NULL if not found.
+ */
+PJ_DECL(pjsip_multipart_part*)
+pjsip_multipart_find_part_by_header_str(pj_pool_t *pool,
+ const pjsip_msg_body *mp,
+ const pj_str_t *hdr_name,
+ const pj_str_t *hdr_value,
+ const pjsip_multipart_part *start);
+
+
+
+/**
+ * Find a body inside multipart bodies which has a Content-ID value matching the
+ * supplied "cid" URI in pj_str form. The "cid:" scheme will be assumed if the
+ * URL doesn't start with it. Enclosing angle brackets will also be handled
+ * correctly if they exist.
+ *
+ * @see RFC2392 Content-ID and Message-ID Uniform Resource Locators
+ *
+ * @param pool Memory pool to use for temp space.
+ * @param mp The multipart body.
+ * @param cid The "cid" URI to search for in pj_str form.
+ *
+ * @return The first part which has a Content-ID header matching the
+ * specified "cid" URI. or NULL if not found.
+ */
+PJ_DECL(pjsip_multipart_part*)
+pjsip_multipart_find_part_by_cid_str(pj_pool_t *pool,
+ const pjsip_msg_body *mp,
+ pj_str_t *cid);
+
+/**
+ * Find a body inside multipart bodies which has a Content-ID value matching the
+ * supplied "cid" URI.
+ *
+ * @see RFC2392 Content-ID and Message-ID Uniform Resource Locators
+ *
+ * @param pool Memory pool to use for temp space.
+ * @param mp The multipart body.
+ * @param cid The "cid" URI to search for.
+ *
+ * @return The first part which had a Content-ID header matching the
+ * specified "cid" URI. or NULL if not found.
+ */
+PJ_DECL(pjsip_multipart_part*)
+pjsip_multipart_find_part_by_cid_uri(pj_pool_t *pool,
+ const pjsip_msg_body *mp,
+ pjsip_other_uri *cid_uri);
+
/**
* Parse multipart message.
*
diff --git a/pjsip/src/pjsip/sip_multipart.c b/pjsip/src/pjsip/sip_multipart.c
index e7d722d2e..9d8be55b0 100644
--- a/pjsip/src/pjsip/sip_multipart.c
+++ b/pjsip/src/pjsip/sip_multipart.c
@@ -19,6 +19,7 @@
#include <pjsip/sip_multipart.h>
#include <pjsip/sip_parser.h>
#include <pjlib-util/scanner.h>
+#include <pjlib-util/string.h>
#include <pj/assert.h>
#include <pj/ctype.h>
#include <pj/errno.h>
@@ -416,6 +417,220 @@ pjsip_multipart_find_part( const pjsip_msg_body *mp,
return NULL;
}
+/*
+ * Find a body inside multipart bodies which has the header and value.
+ */
+PJ_DEF(pjsip_multipart_part*)
+pjsip_multipart_find_part_by_header_str(pj_pool_t *pool,
+ const pjsip_msg_body *mp,
+ const pj_str_t *hdr_name,
+ const pj_str_t *hdr_value,
+ const pjsip_multipart_part *start)
+{
+ struct multipart_data *m_data;
+ pjsip_multipart_part *part;
+ pjsip_hdr *found_hdr;
+ pj_str_t found_hdr_str;
+ pj_str_t found_hdr_value;
+ pj_size_t expected_hdr_slen;
+ pj_size_t buf_size;
+ int hdr_name_len;
+#define REASONABLE_PADDING 32
+#define SEPARATOR_LEN 2
+ /* Must specify mandatory params */
+ PJ_ASSERT_RETURN(mp && hdr_name && hdr_value, NULL);
+
+ /* mp must really point to an actual multipart msg body */
+ PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);
+
+ /*
+ * We'll need to "print" each header we find to test it but
+ * allocating a buffer of PJSIP_MAX_URL_SIZE is overkill.
+ * Instead, we'll allocate one large enough to hold the search
+ * header name, the ": " separator, the search hdr value, and
+ * the NULL terminator. If we can't print the found header
+ * into that buffer then it can't be a match.
+ *
+ * Some header print functions such as generic_int require enough
+ * space to print the maximum possible header length so we'll
+ * add a reasonable amount to the print buffer size.
+ */
+ expected_hdr_slen = hdr_name->slen + SEPARATOR_LEN + hdr_value->slen;
+ buf_size = expected_hdr_slen + REASONABLE_PADDING;
+ found_hdr_str.ptr = pj_pool_alloc(pool, buf_size);
+ found_hdr_str.slen = 0;
+ hdr_name_len = hdr_name->slen + SEPARATOR_LEN;
+
+ m_data = (struct multipart_data*)mp->data;
+
+ if (start)
+ part = start->next;
+ else
+ part = m_data->part_head.next;
+
+ while (part != &m_data->part_head) {
+ found_hdr = NULL;
+ while ((found_hdr = pjsip_hdr_find_by_name(&part->hdr, hdr_name,
+ (found_hdr ? found_hdr->next : NULL))) != NULL) {
+
+ found_hdr_str.slen = pjsip_hdr_print_on((void*) found_hdr, found_hdr_str.ptr, buf_size);
+ /*
+ * If the buffer was too small (slen = -1) or the result wasn't
+ * the same length as the search header, it can't be a match.
+ */
+ if (found_hdr_str.slen != expected_hdr_slen) {
+ continue;
+ }
+ /*
+ * Set the value overlay to start at the found header value...
+ */
+ found_hdr_value.ptr = found_hdr_str.ptr + hdr_name_len;
+ found_hdr_value.slen = found_hdr_str.slen - hdr_name_len;
+ /* ...and compare it to the supplied header value. */
+ if (pj_strcmp(hdr_value, &found_hdr_value) == 0) {
+ return part;
+ }
+ }
+ part = part->next;
+ }
+ return NULL;
+#undef SEPARATOR_LEN
+#undef REASONABLE_PADDING
+}
+
+PJ_DEF(pjsip_multipart_part*)
+pjsip_multipart_find_part_by_header(pj_pool_t *pool,
+ const pjsip_msg_body *mp,
+ void *search_for,
+ const pjsip_multipart_part *start)
+{
+ struct multipart_data *m_data;
+ pjsip_hdr *search_hdr = search_for;
+ pj_str_t search_buf;
+
+ /* Must specify mandatory params */
+ PJ_ASSERT_RETURN(mp && search_hdr, NULL);
+
+ /* mp must really point to an actual multipart msg body */
+ PJ_ASSERT_RETURN(mp->print_body==&multipart_print_body, NULL);
+
+ /*
+ * Unfortunately, there isn't enough information to determine
+ * the maximum printed size of search_hdr at this point so we
+ * have to allocate a reasonable max.
+ */
+ search_buf.ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
+ search_buf.slen = pjsip_hdr_print_on(search_hdr, search_buf.ptr, PJSIP_MAX_URL_SIZE - 1);
+ if (search_buf.slen <= 0) {
+ return NULL;
+ }
+ /*
+ * Set the header value to start after the header name plus the ":", then
+ * strip leading and trailing whitespace.
+ */
+ search_buf.ptr += (search_hdr->name.slen + 1);
+ search_buf.slen -= (search_hdr->name.slen + 1);
+ pj_strtrim(&search_buf);
+
+ return pjsip_multipart_find_part_by_header_str(pool, mp, &search_hdr->name, &search_buf, start);
+}
+
+/*
+ * Convert a Content-ID URI to it's corresponding header value.
+ * RFC2392 says...
+ * A "cid" URL is converted to the corresponding Content-ID message
+ * header by removing the "cid:" prefix, converting the % encoded
+ * character(s) to their equivalent US-ASCII characters, and enclosing
+ * the remaining parts with an angle bracket pair, "<" and ">".
+ *
+ * This implementation will accept URIs with or without the "cid:"
+ * scheme and optional angle brackets.
+ */
+static pj_str_t cid_uri_to_hdr_value(pj_pool_t *pool, pj_str_t *cid_uri)
+{
+ pj_size_t cid_len = pj_strlen(cid_uri);
+ pj_size_t alloc_len = cid_len + 2 /* for the leading and trailing angle brackets */;
+ pj_str_t uri_overlay;
+ pj_str_t cid_hdr;
+ pj_str_t hdr_overlay;
+
+ pj_strassign(&uri_overlay, cid_uri);
+ /* If the URI is already enclosed in angle brackets, remove them. */
+ if (uri_overlay.ptr[0] == '<') {
+ uri_overlay.ptr++;
+ uri_overlay.slen -= 2;
+ }
+ /* If the URI starts with the "cid:" scheme, skip over it. */
+ if (pj_strncmp2(&uri_overlay, "cid:", 4) == 0) {
+ uri_overlay.ptr += 4;
+ uri_overlay.slen -= 4;
+ }
+ /* Start building */
+ cid_hdr.ptr = pj_pool_alloc(pool, alloc_len);
+ cid_hdr.ptr[0] = '<';
+ cid_hdr.slen = 1;
+ hdr_overlay.ptr = cid_hdr.ptr + 1;
+ hdr_overlay.slen = 0;
+ pj_strcpy_unescape(&hdr_overlay, &uri_overlay);
+ cid_hdr.slen += hdr_overlay.slen;
+ cid_hdr.ptr[cid_hdr.slen] = '>';
+ cid_hdr.slen++;
+
+ return cid_hdr;
+}
+
+PJ_DEF(pjsip_multipart_part*)
+pjsip_multipart_find_part_by_cid_str(pj_pool_t *pool,
+ const pjsip_msg_body *mp,
+ pj_str_t *cid)
+{
+ struct multipart_data *m_data;
+ pjsip_multipart_part *part;
+ pjsip_generic_string_hdr *found_hdr;
+ pj_str_t found_hdr_value;
+ static pj_str_t hdr_name = { "Content-ID", 10};
+ pj_str_t hdr_value;
+
+ PJ_ASSERT_RETURN(pool && mp && cid && (pj_strlen(cid) > 0), NULL);
+
+ hdr_value = cid_uri_to_hdr_value(pool, cid);
+ if (pj_strlen(&hdr_value) == 0) {
+ return NULL;
+ }
+
+ m_data = (struct multipart_data*)mp->data;
+ part = m_data->part_head.next;
+
+ while (part != &m_data->part_head) {
+ found_hdr = NULL;
+ while ((found_hdr = pjsip_hdr_find_by_name(&part->hdr, &hdr_name,
+ (found_hdr ? found_hdr->next : NULL))) != NULL) {
+ if (pj_strcmp(&hdr_value, &found_hdr->hvalue) == 0) {
+ return part;
+ }
+ }
+ part = part->next;
+ }
+ return NULL;
+}
+
+PJ_DEF(pjsip_multipart_part*)
+pjsip_multipart_find_part_by_cid_uri(pj_pool_t *pool,
+ const pjsip_msg_body *mp,
+ pjsip_other_uri *cid_uri)
+{
+ PJ_ASSERT_RETURN(pool && mp && cid_uri, NULL);
+
+ if (pj_strcmp2(&cid_uri->scheme, "cid") != 0) {
+ return NULL;
+ }
+ /*
+ * We only need to pass the URI content so we
+ * can do that directly.
+ */
+ return pjsip_multipart_find_part_by_cid_str(pool, mp, &cid_uri->content);
+}
+
/* Parse a multipart part. "pct" is parent content-type */
static pjsip_multipart_part *parse_multipart_part(pj_pool_t *pool,
char *start,
@@ -584,6 +799,7 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,
(int)boundary.slen, boundary.ptr));
}
+
/* Build the delimiter:
* delimiter = "--" boundary
*/
@@ -630,6 +846,8 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,
if (*curptr=='\r') ++curptr;
if (*curptr!='\n') {
/* Expecting a newline here */
+ PJ_LOG(2, (THIS_FILE, "Failed to find newline"));
+
return NULL;
}
++curptr;
@@ -645,6 +863,7 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,
curptr = pj_strstr(&subbody, &delim);
if (!curptr) {
/* We're really expecting end delimiter to be found. */
+ PJ_LOG(2, (THIS_FILE, "Failed to find end-delimiter"));
return NULL;
}
}
@@ -670,9 +889,13 @@ PJ_DEF(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,
part = parse_multipart_part(pool, start_body, end_body - start_body,
ctype);
if (part) {
+ TRACE_((THIS_FILE, "Adding part"));
pjsip_multipart_add_part(pool, body, part);
+ } else {
+ PJ_LOG(2, (THIS_FILE, "Failed to add part"));
}
}
+ TRACE_((THIS_FILE, "pjsip_multipart_parse finished: %p", body));
return body;
}
diff --git a/pjsip/src/test/multipart_test.c b/pjsip/src/test/multipart_test.c
index 4f16e68bf..97267a290 100644
--- a/pjsip/src/test/multipart_test.c
+++ b/pjsip/src/test/multipart_test.c
@@ -28,6 +28,7 @@
typedef pj_status_t (*verify_ptr)(pj_pool_t*,pjsip_msg_body*);
static pj_status_t verify1(pj_pool_t *pool, pjsip_msg_body *body);
+static pj_status_t verify2(pj_pool_t *pool, pjsip_msg_body *body);
static struct test_t
{
@@ -68,7 +69,41 @@ static struct test_t
"This is epilogue, which should be ignored too",
&verify1
+ },
+ {
+ /* Content-type */
+ "multipart", "mixed", "12345",
+
+ /* Body: */
+ "This is the prolog, which should be ignored.\r\n"
+ "--12345\r\n"
+ "Content-Type: text/plain\r\n"
+ "Content-ID: <header1@example.org>\r\n"
+ "Content-ID: <\"header1\"@example.org>\r\n"
+ "Content-Length: 13\r\n"
+ "\r\n"
+ "has header1\r\n"
+ "--12345 \t\r\n"
+ "Content-Type: application/pidf+xml\r\n"
+ "Content-ID: <my header2@example.org>\r\n"
+ "Content-ID: <my\xffheader2@example.org>\r\n"
+ "Content-Length: 13\r\n"
+ "\r\n"
+ "has header2\r\n"
+ "--12345\r\n"
+ "Content-Type: text/plain\r\n"
+ "Content-ID: <my header3@example.org>\r\n"
+ "Content-ID: <header1@example.org>\r\n"
+ "Content-ID: <my header4@example.org>\r\n"
+ "Content-Length: 13\r\n"
+ "\r\n"
+ "has header4\r\n"
+ "--12345--\r\n"
+ "This is epilogue, which should be ignored too",
+
+ &verify2
}
+
};
static void init_media_type(pjsip_media_type *mt,
@@ -87,6 +122,192 @@ static void init_media_type(pjsip_media_type *mt,
}
}
+static int verify_hdr(pj_pool_t *pool, pjsip_msg_body *multipart_body,
+ void *hdr, char *part_body)
+{
+ pjsip_media_type mt;
+ pjsip_multipart_part *part;
+ pj_str_t the_body;
+
+
+ part = pjsip_multipart_find_part_by_header(pool, multipart_body, hdr, NULL);
+ if (!part) {
+ return -1;
+ }
+
+ the_body.ptr = (char*)part->body->data;
+ the_body.slen = part->body->len;
+
+ if (pj_strcmp2(&the_body, part_body) != 0) {
+ return -2;
+ }
+
+ return 0;
+}
+
+static int verify_cid_str(pj_pool_t *pool, pjsip_msg_body *multipart_body,
+ pj_str_t cid_url, char *part_body)
+{
+ pjsip_media_type mt;
+ pjsip_multipart_part *part;
+ pj_str_t the_body;
+
+ part = pjsip_multipart_find_part_by_cid_str(pool, multipart_body, &cid_url);
+ if (!part) {
+ return -3;
+ }
+
+ the_body.ptr = (char*)part->body->data;
+ the_body.slen = part->body->len;
+
+ if (pj_strcmp2(&the_body, part_body) != 0) {
+ return -4;
+ }
+
+ return 0;
+}
+
+static int verify_cid_uri(pj_pool_t *pool, pjsip_msg_body *multipart_body,
+ pjsip_other_uri *cid_uri, char *part_body)
+{
+ pjsip_media_type mt;
+ pjsip_multipart_part *part;
+ pj_str_t the_body;
+
+ part = pjsip_multipart_find_part_by_cid_uri(pool, multipart_body, cid_uri);
+ if (!part) {
+ return -5;
+ }
+
+ the_body.ptr = (char*)part->body->data;
+ the_body.slen = part->body->len;
+
+ if (pj_strcmp2(&the_body, part_body) != 0) {
+ return -6;
+ }
+
+ return 0;
+}
+
+static pj_status_t verify2(pj_pool_t *pool, pjsip_msg_body *body)
+{
+ int rc = 0;
+ int rcbase = 300;
+ pjsip_other_uri *cid_uri;
+ pjsip_ctype_hdr *ctype_hdr = pjsip_ctype_hdr_create(pool);
+
+ ctype_hdr->media.type = pj_str("application");
+ ctype_hdr->media.subtype = pj_str("pidf+xml");
+
+ rc = verify_hdr(pool, body, ctype_hdr, "has header2");
+ if (rc) {
+ return (rc - rcbase);
+ }
+
+ rcbase += 10;
+ rc = verify_cid_str(pool, body, pj_str("cid:header1@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, "<cid:%22header1%22@example.org>",
+ strlen("<cid:%22header1%22@example.org>"), 0));
+ rcbase += 10;
+ rc = verify_cid_uri(pool, body, cid_uri, "has header1");
+ if (rc) {
+ return (rc - rcbase);
+ }
+
+ rcbase += 10;
+ rc = verify_cid_str(pool, body, pj_str("<cid:my%20header2@example.org>"), "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, "<cid:my%ffheader2@example.org>",
+ strlen("<cid:my%ffheader2@example.org>"), 0));
+ rcbase += 10;
+ rc = verify_cid_uri(pool, body, cid_uri, "has header2");
+ if (rc) {
+ return (rc - rcbase);
+ }
+
+ rcbase += 10;
+ rc = verify_cid_str(pool, body, pj_str("cid:my%20header3@example.org"), "has header4");
+ if (rc) {
+ return (rc - rcbase);
+ }
+
+ rcbase += 10;
+ rc = verify_cid_str(pool, body, pj_str("<cid:my%20header4@example.org>"), "has header4");
+ if (rc) {
+ return (rc - rcbase);
+ }
+
+ cid_uri = pjsip_uri_get_uri(pjsip_parse_uri(pool, "<cid:my%20header4@example.org>",
+ strlen("<cid:my%20header4@example.org>"), 0));
+ rcbase += 10;
+ rc = verify_cid_uri(pool, body, cid_uri, "has header4");
+ if (rc) {
+ return (rc - rcbase);
+ }
+
+ rcbase += 10;
+ rc = verify_cid_str(pool, body, pj_str("<my%20header3@example.org>"), "has header4");
+ if (rc) {
+ return (rc - rcbase);
+ }
+
+ /* These should all fail for malformed or missing URI */
+ rcbase += 10;
+ rc = verify_cid_str(pool, body, pj_str("cid:"), "has header4");
+ if (!rc) {
+ return (rc - rcbase);
+ }
+
+ rcbase += 10;
+ rc = verify_cid_str(pool, body, pj_str(""), "has header4");
+ if (!rc) {
+ return (rc - rcbase);
+ }
+
+ rcbase += 10;
+ rc = verify_cid_str(pool, body, pj_str("<>"), "has header4");
+ if (!rc) {
+ return (rc - rcbase);
+ }
+
+ rcbase += 10;
+ rc = verify_cid_str(pool, body, pj_str("<cid>"), "has header4");
+ if (!rc) {
+ return (rc - rcbase);
+ }
+
+ /*
+ * This is going to pass but the ' ' in the uri is un-encoded which is invalid
+ * so we should never see it.
+ */
+ rcbase += 10;
+ rc = verify_cid_str(pool, body, pj_str("cid:my header3@example.org"), "has header4");
+ if (rc) {
+ return (rc - rcbase);
+ }
+
+ return 0;
+}
+
static int verify_part(pjsip_multipart_part *part,
char *h_content_type,
char *h_content_subtype,
@@ -236,8 +457,10 @@ static int parse_test(void)
pj_strdup2_with_null(pool, &str, p_tests[i].msg);
body = pjsip_multipart_parse(pool, str.ptr, str.slen, &ctype, 0);
- if (!body)
+ if (!body) {
+ pj_pool_release(pool);
return -100;
+ }
if (p_tests[i].verify) {
rc = p_tests[i].verify(pool, body);
--
2.34.1

View File

@@ -1,26 +0,0 @@
From 15663e3f37091069b8c98a7fce680dc04bc8e865 Mon Sep 17 00:00:00 2001
From: sauwming <ming@teluu.com>
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(+)
diff --git a/pjnath/src/pjnath/stun_msg.c b/pjnath/src/pjnath/stun_msg.c
index cd5870f82..bd83351e6 100644
--- 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(pj_pool_t *pool,
/* 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);
--
2.25.1

View File

@@ -1,114 +0,0 @@
From db3235953baa56d2fb0e276ca510fefca751643f Mon Sep 17 00:00:00 2001
From: Nanang Izzuddin <nanang@teluu.com>
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(-)
diff --git a/pjsip/src/pjsip/sip_ua_layer.c b/pjsip/src/pjsip/sip_ua_layer.c
index 59c2524ba..5d79882a1 100644
--- 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;
};
@@ -327,6 +330,7 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,
* 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);
@@ -334,8 +338,8 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,
/* 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);
}
@@ -345,14 +349,15 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,
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);
}
@@ -397,12 +402,43 @@ PJ_DEF(pj_status_t) pjsip_ua_unregister_dlg( pjsip_user_agent *ua,
/* 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. */
--
2.25.1

View File

@@ -1,42 +0,0 @@
From 077b465c33f0aec05a49cd2ca456f9a1b112e896 Mon Sep 17 00:00:00 2001
From: sauwming <ming@teluu.com>
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(-)
diff --git a/pjlib-util/src/pjlib-util/scanner.c b/pjlib-util/src/pjlib-util/scanner.c
index 27a0b8831..a54edf2d8 100644
--- 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 *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;
--
2.25.1

View File

@@ -1,307 +0,0 @@
From aefc5f83f7de651e3a37e7e1781bfaef46dab9c4 Mon Sep 17 00:00:00 2001
From: Ben Ford <bford@sangoma.com>
Date: Wed, 30 Nov 2022 11:28:16 -0600
Subject: [PATCH] Merge pull request from GHSA-fq45-m3f7-3mhj
* Initial patch
* Use 'pj_scan_is_eof(scanner)'
Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
* Use 'pj_scan_is_eof(scanner)'
Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
* Use 'pj_scan_is_eof(scanner)'
Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
* Use `!pj_scan_is_eof` instead of manually checking `scanner->curptr < scanner->end`
Co-authored-by: Maksim Mukosey <mmukosey@gmail.com>
* Update pjlib-util/src/pjlib-util/scanner.c
Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
* Update pjlib-util/src/pjlib-util/scanner.c
Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
* Update pjlib-util/src/pjlib-util/scanner.c
Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
* Revert '>=' back to '>' in pj_scan_stricmp_alnum()
* Fix error compiles.
Co-authered-by: sauwming <ming@teluu.com>
Co-authored-by: Nanang Izzuddin <nanang@teluu.com>
Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
Co-authored-by: Maksim Mukosey <mmukosey@gmail.com>
---
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(-)
diff --git a/pjlib-util/src/pjlib-util/scanner.c b/pjlib-util/src/pjlib-util/scanner.c
index c18b74c55..ea27bbec9 100644
--- 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_scanner *scanner )
PJ_DEF(void) pj_scan_skip_line( pj_scanner *scanner )
{
- char *s = pj_ansi_strchr(scanner->curptr, '\n');
+ 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 *scanner,
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_scanner *scanner,
/* 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,
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);
}
}
@@ -462,15 +468,16 @@ PJ_DEF(int) pj_scan_get_char( pj_scanner *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;
}
@@ -515,7 +522,9 @@ PJ_DEF(void) pj_scan_get_until( pj_scanner *scanner,
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);
}
}
@@ -539,7 +548,9 @@ PJ_DEF(void) pj_scan_get_until_ch( pj_scanner *scanner,
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);
}
}
@@ -565,7 +576,9 @@ PJ_DEF(void) pj_scan_get_until_chr( pj_scanner *scanner,
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);
}
}
@@ -580,7 +593,9 @@ PJ_DEF(void) pj_scan_advance_n( pj_scanner *scanner,
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);
}
}
@@ -631,5 +646,3 @@ PJ_DEF(void) pj_scan_restore_state( pj_scanner *scanner,
scanner->line = state->line;
scanner->start_line = state->start_line;
}
-
-
diff --git a/pjmedia/src/pjmedia/rtp.c b/pjmedia/src/pjmedia/rtp.c
index 6c571010c..c987cd0ad 100644
--- a/pjmedia/src/pjmedia/rtp.c
+++ b/pjmedia/src/pjmedia/rtp.c
@@ -183,6 +183,11 @@ PJ_DEF(pj_status_t) pjmedia_rtp_decode_rtp2(
/* 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) {
dec_hdr->ext_hdr = (pjmedia_rtp_ext_hdr*)(((pj_uint8_t*)pkt) + offset);
@@ -195,8 +200,8 @@ PJ_DEF(pj_status_t) pjmedia_rtp_decode_rtp2(
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. */
@@ -386,5 +391,3 @@ void pjmedia_rtp_seq_update( pjmedia_rtp_seq_session *sess,
seq_status->status.value = st.status.value;
}
}
-
-
diff --git a/pjmedia/src/pjmedia/sdp.c b/pjmedia/src/pjmedia/sdp.c
index c443d863f..f27a1a84f 100644
--- a/pjmedia/src/pjmedia/sdp.c
+++ b/pjmedia/src/pjmedia/sdp.c
@@ -967,13 +967,13 @@ static void parse_version(pj_scanner *scanner, parse_context *ctx)
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;
}
@@ -990,7 +990,7 @@ static void parse_origin(pj_scanner *scanner, pjmedia_sdp_session *ses,
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;
}
@@ -1036,7 +1036,7 @@ static void parse_time(pj_scanner *scanner, pjmedia_sdp_session *ses,
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;
}
@@ -1064,7 +1064,7 @@ static void parse_generic_line(pj_scanner *scanner, pj_str_t *str,
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;
}
@@ -1133,7 +1133,7 @@ static void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med,
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;
}
@@ -1148,6 +1148,10 @@ static void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med,
/* 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);
@@ -1159,7 +1163,7 @@ static void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med,
}
if (pj_scan_get_char(scanner) != ' ') {
- PJ_THROW(SYNTAX_ERROR);
+ on_scanner_error(scanner);
}
/* transport */
@@ -1167,7 +1171,7 @@ static void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med,
/* 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);
@@ -1207,7 +1211,7 @@ static pjmedia_sdp_attr *parse_attr( pj_pool_t *pool, pj_scanner *scanner,
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;
}
@@ -1226,7 +1230,7 @@ static pjmedia_sdp_attr *parse_attr( pj_pool_t *pool, pj_scanner *scanner,
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;
--
2.25.1

View File

@@ -1,44 +0,0 @@
From 450baca94f475345542c6953832650c390889202 Mon Sep 17 00:00:00 2001
From: sauwming <ming@teluu.com>
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(-)
diff --git a/pjlib-util/src/pjlib-util/stun_simple.c b/pjlib-util/src/pjlib-util/stun_simple.c
index 722519584..d0549176d 100644
--- 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( void *buf, pj_size_t buf_len,
{
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( void *buf, pj_size_t buf_len,
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( void *buf, pj_size_t buf_len,
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.25.1

View File

@@ -1,28 +0,0 @@
diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
index 4f483faa1..12439e3ee 100644
--- a/pjsip/src/pjsip/sip_transport.c
+++ b/pjsip/src/pjsip/sip_transport.c
@@ -2071,15 +2071,17 @@
* which were sent to keep NAT bindings.
*/
if (tmp.slen) {
- PJ_LOG(1, (THIS_FILE,
- "Error processing %d bytes packet from %s %s:%d %.*s:\n"
- "%.*s\n"
- "-- end of packet.",
+ PJ_LOG(2, (THIS_FILE,
+ "Dropping %d bytes packet from %s %s:%d %.*s\n",
msg_fragment_size,
rdata->tp_info.transport->type_name,
- rdata->pkt_info.src_name,
+ rdata->pkt_info.src_name,
rdata->pkt_info.src_port,
- (int)tmp.slen, tmp.ptr,
+ (int)tmp.slen, tmp.ptr));
+ PJ_LOG(4, (THIS_FILE,
+ "Dropped packet:"
+ "%.*s\n"
+ "-- end of packet.",
(int)msg_fragment_size,
rdata->msg_info.msg_buf));
}

View File

@@ -1,203 +0,0 @@
From 0731f6ac75f251302b6b135f9534c8a94fe75e62 Mon Sep 17 00:00:00 2001
From: Nanang Izzuddin <nanang@teluu.com>
Date: Tue, 20 Dec 2022 11:39:12 +0700
Subject: [PATCH 300/303] Merge pull request from GHSA-9pfh-r8x4-w26w
* Fix buffer overread in STUN message decoder
* Updates based on comments
---
pjnath/include/pjnath/stun_msg.h | 4 ++++
pjnath/src/pjnath/stun_msg.c | 32 ++++++++++++++++++++------------
2 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/pjnath/include/pjnath/stun_msg.h b/pjnath/include/pjnath/stun_msg.h
index f4fc5a1e4..c9dd7cf0d 100644
--- a/pjnath/include/pjnath/stun_msg.h
+++ b/pjnath/include/pjnath/stun_msg.h
@@ -432,20 +432,21 @@ typedef enum pj_stun_status
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Transaction ID
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\endverbatim
*/
+#pragma pack(1)
typedef struct pj_stun_msg_hdr
{
/**
* STUN message type, which the first two bits must be zeroes.
*/
pj_uint16_t type;
/**
* The message length is the size, in bytes, of the message not
* including the 20 byte STUN header.
@@ -463,53 +464,56 @@ typedef struct pj_stun_msg_hdr
* The transaction ID is a 96 bit identifier. STUN transactions are
* identified by their unique 96-bit transaction ID. For request/
* response transactions, the transaction ID is chosen by the STUN
* client and MUST be unique for each new STUN transaction generated by
* that STUN client. The transaction ID MUST be uniformly and randomly
* distributed between 0 and 2**96 - 1.
*/
pj_uint8_t tsx_id[12];
} pj_stun_msg_hdr;
+#pragma pack()
/**
* This structre describes STUN attribute header. Each attribute is
* TLV encoded, with a 16 bit type, 16 bit length, and variable value.
* Each STUN attribute ends on a 32 bit boundary:
*
* \verbatim
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\endverbatim
*/
+#pragma pack(1)
typedef struct pj_stun_attr_hdr
{
/**
* STUN attribute type.
*/
pj_uint16_t type;
/**
* The Length refers to the length of the actual useful content of the
* Value portion of the attribute, measured in bytes. The value
* in the Length field refers to the length of the Value part of the
* attribute prior to padding - i.e., the useful content.
*/
pj_uint16_t length;
} pj_stun_attr_hdr;
+#pragma pack()
/**
* This structure describes STUN generic IP address attribute, used for
* example to represent STUN MAPPED-ADDRESS attribute.
*
* The generic IP address attribute indicates the transport address.
* It consists of an eight bit address family, and a sixteen bit port,
* followed by a fixed length value representing the IP address. If the
* address family is IPv4, the address is 32 bits, in network byte
diff --git a/pjnath/src/pjnath/stun_msg.c b/pjnath/src/pjnath/stun_msg.c
index bd83351e6..fd15230bc 100644
--- a/pjnath/src/pjnath/stun_msg.c
+++ b/pjnath/src/pjnath/stun_msg.c
@@ -739,22 +739,22 @@ PJ_DEF(int) pj_stun_set_padding_char(int chr)
int old_pad = padding_char;
padding_char = chr;
return old_pad;
}
//////////////////////////////////////////////////////////////////////////////
#define INIT_ATTR(a,t,l) (a)->hdr.type=(pj_uint16_t)(t), \
- (a)->hdr.length=(pj_uint16_t)(l)
-#define ATTR_HDR_LEN 4
+ (a)->hdr.length=(pj_uint16_t)(l)
+#define ATTR_HDR_LEN sizeof(pj_stun_attr_hdr)
static pj_uint16_t GETVAL16H(const pj_uint8_t *buf, unsigned pos)
{
return (pj_uint16_t) ((buf[pos + 0] << 8) | \
(buf[pos + 1] << 0));
}
/*unused PJ_INLINE(pj_uint16_t) GETVAL16N(const pj_uint8_t *buf, unsigned pos)
{
return pj_htons(GETVAL16H(buf,pos));
@@ -2318,56 +2318,64 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
PJ_ASSERT_RETURN(pool && pdu && pdu_len && p_msg, PJ_EINVAL);
PJ_ASSERT_RETURN(sizeof(pj_stun_msg_hdr) == 20, PJ_EBUG);
if (p_parsed_len)
*p_parsed_len = 0;
if (p_response)
*p_response = NULL;
/* Check if this is a STUN message, if necessary */
if (options & PJ_STUN_CHECK_PACKET) {
- status = pj_stun_msg_check(pdu, pdu_len, options);
- if (status != PJ_SUCCESS)
- return status;
+ status = pj_stun_msg_check(pdu, pdu_len, options);
+ if (status != PJ_SUCCESS)
+ return status;
+ } else {
+ /* For safety, verify packet length at least */
+ pj_uint32_t msg_len = GETVAL16H(pdu, 2) + 20;
+ if (msg_len > pdu_len ||
+ ((options & PJ_STUN_IS_DATAGRAM) && msg_len != pdu_len))
+ {
+ return PJNATH_EINSTUNMSGLEN;
+ }
}
/* Create the message, copy the header, and convert to host byte order */
msg = PJ_POOL_ZALLOC_T(pool, pj_stun_msg);
pj_memcpy(&msg->hdr, pdu, sizeof(pj_stun_msg_hdr));
msg->hdr.type = pj_ntohs(msg->hdr.type);
msg->hdr.length = pj_ntohs(msg->hdr.length);
msg->hdr.magic = pj_ntohl(msg->hdr.magic);
pdu += sizeof(pj_stun_msg_hdr);
/* pdu_len -= sizeof(pj_stun_msg_hdr); */
pdu_len = msg->hdr.length;
/* No need to create response if this is not a request */
if (!PJ_STUN_IS_REQUEST(msg->hdr.type))
p_response = NULL;
/* Parse attributes */
- while (pdu_len >= 4) {
- unsigned attr_type, attr_val_len;
- const struct attr_desc *adesc;
+ while (pdu_len >= ATTR_HDR_LEN) {
+ unsigned attr_type, attr_val_len;
+ const struct attr_desc *adesc;
/* Get attribute type and length. If length is not aligned
* to 4 bytes boundary, add padding.
*/
attr_type = GETVAL16H(pdu, 0);
attr_val_len = GETVAL16H(pdu, 2);
attr_val_len = (attr_val_len + 3) & (~3);
- /* Check length */
- if (pdu_len < attr_val_len) {
- pj_str_t err_msg;
- char err_msg_buf[80];
+ /* Check length */
+ if (pdu_len < attr_val_len + ATTR_HDR_LEN) {
+ pj_str_t err_msg;
+ char err_msg_buf[80];
err_msg.ptr = err_msg_buf;
err_msg.slen = pj_ansi_snprintf(err_msg_buf, sizeof(err_msg_buf),
"Attribute %s has invalid length",
pj_stun_get_attr_name(attr_type));
PJ_LOG(4,(THIS_FILE, "Error decoding message: %.*s",
(int)err_msg.slen, err_msg.ptr));
if (p_response) {
--
2.41.0

View File

@@ -1,81 +0,0 @@
From 5c50a482986750c83db0dee2963599b8906e6951 Mon Sep 17 00:00:00 2001
From: sauwming <ming@teluu.com>
Date: Fri, 23 Dec 2022 15:05:28 +0800
Subject: [PATCH 301/303] Merge pull request from GHSA-cxwq-5g9x-x7fr
* Fixed heap buffer overflow when parsing STUN errcode attribute
* Also fixed uint parsing
---
pjnath/src/pjnath/stun_msg.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/pjnath/src/pjnath/stun_msg.c b/pjnath/src/pjnath/stun_msg.c
index fd15230bc..d3aaae5bf 100644
--- a/pjnath/src/pjnath/stun_msg.c
+++ b/pjnath/src/pjnath/stun_msg.c
@@ -1432,26 +1432,26 @@ static pj_status_t decode_uint_attr(pj_pool_t *pool,
void **p_attr)
{
pj_stun_uint_attr *attr;
PJ_UNUSED_ARG(msghdr);
/* Create the attribute */
attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint_attr);
GETATTRHDR(buf, &attr->hdr);
- attr->value = GETVAL32H(buf, 4);
-
/* Check that the attribute length is valid */
if (attr->hdr.length != 4)
return PJNATH_ESTUNINATTRLEN;
+ attr->value = GETVAL32H(buf, 4);
+
/* Done */
*p_attr = attr;
return PJ_SUCCESS;
}
static pj_status_t encode_uint_attr(const void *a, pj_uint8_t *buf,
unsigned len,
const pj_stun_msg_hdr *msghdr,
@@ -1751,28 +1751,29 @@ static pj_status_t decode_errcode_attr(pj_pool_t *pool,
{
pj_stun_errcode_attr *attr;
pj_str_t value;
PJ_UNUSED_ARG(msghdr);
/* Create the attribute */
attr = PJ_POOL_ZALLOC_T(pool, pj_stun_errcode_attr);
GETATTRHDR(buf, &attr->hdr);
+ /* Check that the attribute length is valid */
+ if (attr->hdr.length < 4)
+ return PJNATH_ESTUNINATTRLEN;
+
attr->err_code = buf[6] * 100 + buf[7];
/* 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);
/* Done */
*p_attr = attr;
return PJ_SUCCESS;
}
--
2.41.0

View File

@@ -1,166 +0,0 @@
From 67e62627240b3f925c765cbda63ccbec328fed29 Mon Sep 17 00:00:00 2001
From: Matthew Fredrickson <mfredrickson@fluentstream.com>
Date: Tue, 30 May 2023 04:33:05 -0500
Subject: [PATCH 302/303] Locking fix so that SSL_shutdown and SSL_write are
not called at same time (#3583)
---
pjlib/src/pj/ssl_sock_ossl.c | 82 ++++++++++++++++++++++--------------
1 file changed, 51 insertions(+), 31 deletions(-)
diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
index 56841f80a..5c68edb2b 100644
--- a/pjlib/src/pj/ssl_sock_ossl.c
+++ b/pjlib/src/pj/ssl_sock_ossl.c
@@ -1230,44 +1230,58 @@ static void ssl_destroy(pj_ssl_sock_t *ssock)
/* Potentially shutdown OpenSSL library if this is the last
* context exists.
*/
shutdown_openssl();
}
/* Reset SSL socket state */
static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
{
+ int post_unlock_flush_circ_buf = 0;
+
ossl_sock_t *ossock = (ossl_sock_t *)ssock;
+ /* Must lock around SSL calls, particularly SSL_shutdown
+ * as it can modify the write BIOs and destructively
+ * interfere with any ssl_write() calls in progress
+ * above in a multithreaded environment */
+ pj_lock_acquire(ssock->write_mutex);
+
/* 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
* SSL handshake, while previous versions always return 0.
*/
if (ossock->ossl_ssl && SSL_in_init(ossock->ossl_ssl) == 0) {
- int ret = SSL_shutdown(ossock->ossl_ssl);
- if (ret == 0) {
- /* Flush data to send close notify. */
- flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0);
- }
+ int ret = SSL_shutdown(ossock->ossl_ssl);
+ if (ret == 0) {
+ /* SSL_shutdown will potentially trigger a bunch of
+ * data to dump to the socket */
+ post_unlock_flush_circ_buf = 1;
+ }
}
- pj_lock_acquire(ssock->write_mutex);
ssock->ssl_state = SSL_STATE_NULL;
+
pj_lock_release(ssock->write_mutex);
+ if (post_unlock_flush_circ_buf) {
+ /* Flush data to send close notify. */
+ flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0);
+ }
+
ssl_close_sockets(ssock);
/* Upon error, OpenSSL may leave any error description in the thread
* error queue, which sometime may cause next call to SSL API returning
* false error alarm, e.g: in Linux, SSL_CTX_use_certificate_chain_file()
* returning false error after a handshake error (in different SSL_CTX!).
* For now, just clear thread error queue here.
*/
ERR_clear_error();
}
@@ -1855,52 +1869,58 @@ static pj_status_t ssl_read(pj_ssl_sock_t *ssock, void *data, int *size)
{
ossl_sock_t *ossock = (ossl_sock_t *)ssock;
int size_ = *size;
int len = size_;
/* SSL_read() may write some data to write buffer when re-negotiation
* is on progress, so let's protect it with write mutex.
*/
pj_lock_acquire(ssock->write_mutex);
*size = size_ = SSL_read(ossock->ossl_ssl, data, size_);
- pj_lock_release(ssock->write_mutex);
if (size_ <= 0) {
pj_status_t status;
int err = SSL_get_error(ossock->ossl_ssl, size_);
- /* SSL might just return SSL_ERROR_WANT_READ in
- * re-negotiation.
- */
- if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ) {
- if (err == SSL_ERROR_SYSCALL && size_ == -1 &&
- ERR_peek_error() == 0 && errno == 0)
- {
- status = STATUS_FROM_SSL_ERR2("Read", ssock, size_,
- err, len);
- PJ_LOG(4,("SSL", "SSL_read() = -1, with "
- "SSL_ERROR_SYSCALL, no SSL error, "
- "and errno = 0 - skip BIO error"));
- /* Ignore these errors */
- } else {
- /* Reset SSL socket state, then return PJ_FALSE */
- status = STATUS_FROM_SSL_ERR2("Read", ssock, size_,
- err, len);
- ssl_reset_sock_state(ssock);
- return status;
- }
- }
-
- /* Need renegotiation */
- return PJ_EEOF;
+ /* SSL might just return SSL_ERROR_WANT_READ in
+ * re-negotiation.
+ */
+ if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ) {
+ if (err == SSL_ERROR_SYSCALL && size_ == -1 &&
+ ERR_peek_error() == 0 && errno == 0)
+ {
+ status = STATUS_FROM_SSL_ERR2("Read", ssock, size_,
+ err, len);
+ PJ_LOG(4,("SSL", "SSL_read() = -1, with "
+ "SSL_ERROR_SYSCALL, no SSL error, "
+ "and errno = 0 - skip BIO error"));
+ /* Ignore these errors */
+ } else {
+ /* Reset SSL socket state, then return PJ_FALSE */
+ status = STATUS_FROM_SSL_ERR2("Read", ssock, size_,
+ err, len);
+ pj_lock_release(ssock->write_mutex);
+ /* Unfortunately we can't hold the lock here to reset all the state.
+ * We probably should though.
+ */
+ ssl_reset_sock_state(ssock);
+ return status;
+ }
+ }
+
+ pj_lock_release(ssock->write_mutex);
+ /* Need renegotiation */
+ return PJ_EEOF;
}
+ pj_lock_release(ssock->write_mutex);
+
return PJ_SUCCESS;
}
/* Write plain data to SSL and flush write BIO. */
static pj_status_t ssl_write(pj_ssl_sock_t *ssock, const void *data,
pj_ssize_t size, int *nwritten)
{
ossl_sock_t *ossock = (ossl_sock_t *)ssock;
pj_status_t status = PJ_SUCCESS;
--
2.41.0

View File

@@ -1,123 +0,0 @@
From a677cd8fb690ed103fed11ab0252b44bd62b0d3e Mon Sep 17 00:00:00 2001
From: Riza Sulistyo <trengginas@users.noreply.github.com>
Date: Wed, 5 Jul 2023 10:38:21 +0700
Subject: [PATCH 303/303] Don't call SSL_shutdown() when receiving
SSL_ERROR_SYSCALL or SSL_ERROR_SSL (#3577)
---
pjlib/src/pj/ssl_sock_imp_common.c | 1 +
pjlib/src/pj/ssl_sock_imp_common.h | 13 +++++++------
pjlib/src/pj/ssl_sock_ossl.c | 17 ++++++++++++-----
3 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c
index 8dbfe175a..2b00a7bcc 100644
--- a/pjlib/src/pj/ssl_sock_imp_common.c
+++ b/pjlib/src/pj/ssl_sock_imp_common.c
@@ -205,20 +205,21 @@ static void ssl_close_sockets(pj_ssl_sock_t *ssock)
}
/* When handshake completed:
* - notify application
* - if handshake failed, reset SSL state
* - return PJ_FALSE when SSL socket instance is destroyed by application.
*/
static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
pj_status_t status)
{
+ ssock->handshake_status = status;
/* Cancel handshake timer */
if (ssock->timer.id == TIMER_HANDSHAKE_TIMEOUT) {
pj_timer_heap_cancel(ssock->param.timer_heap, &ssock->timer);
ssock->timer.id = TIMER_NONE;
}
/* Update certificates info on successful handshake */
if (status == PJ_SUCCESS)
ssl_update_certs_info(ssock);
diff --git a/pjlib/src/pj/ssl_sock_imp_common.h b/pjlib/src/pj/ssl_sock_imp_common.h
index 5e2520341..da26f1e04 100644
--- a/pjlib/src/pj/ssl_sock_imp_common.h
+++ b/pjlib/src/pj/ssl_sock_imp_common.h
@@ -100,26 +100,27 @@ struct pj_ssl_sock_t
* information allocation. Don't use for
* other purposes. */
pj_ssl_sock_t *parent;
pj_ssl_sock_param param;
pj_ssl_sock_param newsock_param;
pj_ssl_cert_t *cert;
pj_ssl_cert_info local_cert_info;
pj_ssl_cert_info remote_cert_info;
- pj_bool_t is_server;
- enum ssl_state ssl_state;
- pj_ioqueue_op_key_t handshake_op_key;
- pj_ioqueue_op_key_t shutdown_op_key;
- pj_timer_entry timer;
- pj_status_t verify_status;
+ pj_bool_t is_server;
+ enum ssl_state ssl_state;
+ pj_ioqueue_op_key_t handshake_op_key;
+ pj_ioqueue_op_key_t shutdown_op_key;
+ pj_timer_entry timer;
+ pj_status_t verify_status;
+ pj_status_t handshake_status;
unsigned long last_err;
pj_sock_t sock;
pj_activesock_t *asock;
pj_sockaddr local_addr;
pj_sockaddr rem_addr;
int addr_len;
diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
index 5c68edb2b..9f66a7485 100644
--- a/pjlib/src/pj/ssl_sock_ossl.c
+++ b/pjlib/src/pj/ssl_sock_ossl.c
@@ -1249,27 +1249,34 @@ static void ssl_reset_sock_state(pj_ssl_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
* SSL handshake, while previous versions always return 0.
+ * Call SSL_shutdown() when there is a timeout handshake failure or
+ * the last error is not SSL_ERROR_SYSCALL and not SSL_ERROR_SSL.
*/
if (ossock->ossl_ssl && SSL_in_init(ossock->ossl_ssl) == 0) {
- int ret = SSL_shutdown(ossock->ossl_ssl);
- if (ret == 0) {
- /* SSL_shutdown will potentially trigger a bunch of
- * data to dump to the socket */
- post_unlock_flush_circ_buf = 1;
+ if (ssock->handshake_status == PJ_ETIMEDOUT ||
+ (ssock->last_err != SSL_ERROR_SYSCALL &&
+ ssock->last_err != SSL_ERROR_SSL))
+ {
+ int ret = SSL_shutdown(ossock->ossl_ssl);
+ if (ret == 0) {
+ /* SSL_shutdown will potentially trigger a bunch of
+ * data to dump to the socket */
+ post_unlock_flush_circ_buf = 1;
+ }
}
}
ssock->ssl_state = SSL_STATE_NULL;
pj_lock_release(ssock->write_mutex);
if (post_unlock_flush_circ_buf) {
/* Flush data to send close notify. */
flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0);
--
2.41.0

View File

@@ -75,9 +75,9 @@
#define PJ_ICE_MAX_CHECKS (PJ_ICE_MAX_CAND * PJ_ICE_MAX_CAND)
/* Increase limits to allow more formats */
#define PJMEDIA_MAX_SDP_FMT 64
#define PJMEDIA_MAX_SDP_FMT 72
#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*6 + 4)
#define PJMEDIA_MAX_SDP_MEDIA 16
/*
@@ -87,3 +87,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

View File

@@ -1,2 +0,0 @@
5d0202f79a7aeb14873c45b0e4c14a70 *pjproject-2.10.zip
4fffc49b461133f0a4143b05a22fb30e pjproject-2.10.tar.bz2

View File

@@ -0,0 +1 @@
6b4b34c14d39224d3342d368f5abbad4 pjproject-2.15.1.tar.bz2

View File

@@ -2,5 +2,5 @@
# configure script so it must follow 'shell'
# syntax as well as 'make' syntax.
JANSSON_VERSION=2.12
PJPROJECT_VERSION=2.10
PJPROJECT_VERSION=2.15.1
LIBJWT_VERSION=1.15.3