diff options
116 files changed, 582 insertions, 144 deletions
@@ -57,6 +57,36 @@ cdr_syslog built. ------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 15.2.0 to Asterisk 15.3.0 ------------ +------------------------------------------------------------------------------ + +app_followme +------------------ + * Added a new prompt, connecting-prompt, which will be played + (if configured) to the "winner" callee before connecting the call. + +res_pjsip +------------------ + * Users who are matching endpoints by SIP header need to reevaluate their + global "endpoint_identifier_order" option in light of the "ip" endpoint + identifier method split into the "ip" and "header" endpoint identifier + methods. + +res_pjsip_endpoint_identifier_ip +------------------ + * The endpoint identifier "ip" method previously recognized endpoints either + by IP address or a matching SIP header. The "ip" endpoint identifier method + is now split into the "ip" and "header" endpoint identifier methods. The + "ip" endpoint identifier method only matches by IP address and the "header" + endpoint identifier method only matches by SIP header. The split allows the + user to control the relative priority of the IP address and the SIP header + identification methods in the global "endpoint_identifier_order" option. + e.g., If you have two type=identify sections where one matches by IP address + for endpoint alice and the other matches by SIP header for endpoint bob then + you can now predict which endpoint is matched when a request comes in that + matches both. + +------------------------------------------------------------------------------ --- Functionality changes from Asterisk 15.1.0 to Asterisk 15.2.0 ------------ ------------------------------------------------------------------------------ diff --git a/Makefile.moddir_rules b/Makefile.moddir_rules index 917c8e08c..5d82088a9 100644 --- a/Makefile.moddir_rules +++ b/Makefile.moddir_rules @@ -115,7 +115,7 @@ ifneq ($(findstring :,$(XMLSTARLET)$(BASH)),:) @if [ -f .moduleinfo ] ; then \ declare -A DISABLED_MODS ;\ for x in $(MENUSELECT_$(MENUSELECT_CATEGORY)) ; do DISABLED_MODS[$${x}]=1 ; done ;\ - EXTERNAL_MODS=$$(xmlstarlet sel -t -m "/category/member[support_level = 'external']" -v "@name" -n .moduleinfo) ;\ + EXTERNAL_MODS=$$($(XMLSTARLET) sel -t -m "/category/member[support_level = 'external']" -v "@name" -n .moduleinfo) ;\ for x in $${EXTERNAL_MODS} ; do \ if [ -z "$${DISABLED_MODS[$${x}]}" ] ; then \ $(ASTTOPDIR)/build_tools/download_externals $${x} ;\ diff --git a/UPGRADE-15.txt b/UPGRADE-15.txt index 30dc5d04c..d47bbe38a 100644 --- a/UPGRADE-15.txt +++ b/UPGRADE-15.txt @@ -23,6 +23,29 @@ === UPGRADE-14.txt -- Upgrade info for 13 to 14 =========================================================== +From 15.2.0 to 15.3.0: + +res_pjsip +------------------ + * Users who are matching endpoints by SIP header need to reevaluate their + global "endpoint_identifier_order" option in light of the "ip" endpoint + identifier method split into the "ip" and "header" endpoint identifier + methods. + +res_pjsip_endpoint_identifier_ip +------------------ + * The endpoint identifier "ip" method previously recognized endpoints either + by IP address or a matching SIP header. The "ip" endpoint identifier method + is now split into the "ip" and "header" endpoint identifier methods. The + "ip" endpoint identifier method only matches by IP address and the "header" + endpoint identifier method only matches by SIP header. The split allows the + user to control the relative priority of the IP address and the SIP header + identification methods in the global "endpoint_identifier_order" option. + e.g., If you have two type=identify sections where one matches by IP address + for endpoint alice and the other matches by SIP header for endpoint bob then + you can now predict which endpoint is matched when a request comes in that + matches both. + New in 15.0.0: Build System: diff --git a/UPGRADE.txt b/UPGRADE.txt index b2c75fbb5..8f45742af 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -43,19 +43,3 @@ ARI: cdr_syslog: - The cdr_syslog module is now deprecated and by default it is no longer built. - -New in 15.0.0: - -Build System: - - '--with-pjproject-bundled' is now the default when running ./configure - It can be disabled with '--without-pjproject-bundled'. - -Core: - - Multi-stream support has been added so a channel can have multiple - streams of the same type such as audio and video. - - - The 'Data Retrieval API' has been removed. This API was not actively - maintained, was not added to new modules (such as res_pjsip), and there - exist better alternatives to acquire the same information, such as the - ARI. As a result, the 'DataGet' AMI action as well as the 'data get' - CLI command have been removed. diff --git a/apps/app_adsiprog.c b/apps/app_adsiprog.c index 2dd226fbd..688168e52 100644 --- a/apps/app_adsiprog.c +++ b/apps/app_adsiprog.c @@ -1613,5 +1613,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk ADSI Programmin .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, - .nonoptreq = "res_adsi", + .requires = "res_adsi", ); diff --git a/apps/app_followme.c b/apps/app_followme.c index 7b47f4dbb..dbb11ee26 100644 --- a/apps/app_followme.c +++ b/apps/app_followme.c @@ -176,6 +176,7 @@ struct call_followme { char plsholdprompt[PATH_MAX]; /*!< Sound prompt name and path */ char statusprompt[PATH_MAX]; /*!< Sound prompt name and path */ char sorryprompt[PATH_MAX]; /*!< Sound prompt name and path */ + char connprompt[PATH_MAX]; /*!< Sound prompt name and path */ AST_LIST_HEAD_NOLOCK(numbers, number) numbers; /*!< Head of the list of follow-me numbers */ AST_LIST_HEAD_NOLOCK(blnumbers, number) blnumbers; /*!< Head of the list of black-listed numbers */ @@ -212,6 +213,7 @@ struct fm_args { char plsholdprompt[PATH_MAX]; /*!< Sound prompt name and path */ char statusprompt[PATH_MAX]; /*!< Sound prompt name and path */ char sorryprompt[PATH_MAX]; /*!< Sound prompt name and path */ + char connprompt[PATH_MAX]; /*!< Sound prompt name and path */ struct ast_flags followmeflags; }; @@ -277,6 +279,7 @@ static char optionsprompt[PATH_MAX] = "followme/options"; static char plsholdprompt[PATH_MAX] = "followme/pls-hold-while-try"; static char statusprompt[PATH_MAX] = "followme/status"; static char sorryprompt[PATH_MAX] = "followme/sorry"; +static char connprompt[PATH_MAX] = ""; static AST_RWLIST_HEAD_STATIC(followmes, call_followme); @@ -333,6 +336,7 @@ static void init_profile(struct call_followme *f, int activate) ast_copy_string(f->plsholdprompt, plsholdprompt, sizeof(f->plsholdprompt)); ast_copy_string(f->statusprompt, statusprompt, sizeof(f->statusprompt)); ast_copy_string(f->sorryprompt, sorryprompt, sizeof(f->sorryprompt)); + ast_copy_string(f->connprompt, connprompt, sizeof(f->connprompt)); if (activate) { f->active = 1; } @@ -366,7 +370,9 @@ static void profile_set_param(struct call_followme *f, const char *param, const ast_copy_string(f->statusprompt, val, sizeof(f->statusprompt)); else if (!strcasecmp(param, "followme-sorry-prompt") || !strcasecmp(param, "sorry_prompt")) ast_copy_string(f->sorryprompt, val, sizeof(f->sorryprompt)); - else if (failunknown) { + else if (!strcasecmp(param, "followme-connecting-prompt") || !strcasecmp(param, "connecting_prompt")) { + ast_copy_string(f->connprompt, val, sizeof(f->connprompt)); + } else if (failunknown) { if (linenum >= 0) ast_log(LOG_WARNING, "Unknown keyword in profile '%s': %s at line %d of followme.conf\n", f->name, param, linenum); else @@ -489,6 +495,13 @@ static int reload_followme(int reload) ast_copy_string(sorryprompt, tmpstr, sizeof(sorryprompt)); } + if ((tmpstr = ast_variable_retrieve(cfg, "general", "connecting-prompt")) && !ast_strlen_zero(tmpstr)) { + ast_copy_string(connprompt, tmpstr, sizeof(connprompt)); + } else if ((tmpstr = ast_variable_retrieve(cfg, "general", "connecting_prompt")) && !ast_strlen_zero(tmpstr)) { + ast_copy_string(connprompt, tmpstr, sizeof(connprompt)); + } + + /* Chug through config file */ while ((cat = ast_category_browse(cfg, cat))) { int new = 0; @@ -1408,6 +1421,7 @@ static int app_exec(struct ast_channel *chan, const char *data) ast_copy_string(targs->plsholdprompt, f->plsholdprompt, sizeof(targs->plsholdprompt)); ast_copy_string(targs->statusprompt, f->statusprompt, sizeof(targs->statusprompt)); ast_copy_string(targs->sorryprompt, f->sorryprompt, sizeof(targs->sorryprompt)); + ast_copy_string(targs->connprompt, f->connprompt, sizeof(targs->connprompt)); /* Copy the numbers we're going to use into another list in case the master list should get modified (and locked) while we're trying to do a follow-me */ AST_LIST_HEAD_INIT_NOLOCK(&targs->cnumbers); @@ -1495,6 +1509,14 @@ static int app_exec(struct ast_channel *chan, const char *data) res = 0; } else { caller = chan; + + /* Play "connecting" message to the winner, if configured. */ + if (!ast_strlen_zero(targs->connprompt)) { + ast_autoservice_start(caller); + ast_stream_and_wait(outbound, targs->connprompt, ""); + ast_autoservice_stop(caller); + } + /* Bridge the two channels. */ memset(&config, 0, sizeof(config)); diff --git a/apps/app_getcpeid.c b/apps/app_getcpeid.c index e0b9f1239..868dc97c3 100644 --- a/apps/app_getcpeid.c +++ b/apps/app_getcpeid.c @@ -140,5 +140,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Get ADSI CPE ID", .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, - .nonoptreq = "res_adsi", + .requires = "res_adsi", ); diff --git a/apps/app_queue.c b/apps/app_queue.c index c62828cfd..e7779b732 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -11345,5 +11345,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "True Call Queueing", .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_CONSUMER, - .nonoptreq = "res_monitor", + .optional_modules = "res_monitor", ); diff --git a/apps/app_speech_utils.c b/apps/app_speech_utils.c index 339c3161f..2ba297e33 100644 --- a/apps/app_speech_utils.c +++ b/apps/app_speech_utils.c @@ -1003,5 +1003,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Dialplan Speech Applicat .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_speech", + .requires = "res_speech", ); diff --git a/apps/app_stack.c b/apps/app_stack.c index 459c06df2..1f98378c9 100644 --- a/apps/app_stack.c +++ b/apps/app_stack.c @@ -1320,5 +1320,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT | AST_MODFLAG_LOAD_ORDER, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, - .nonoptreq = "res_agi", + .optional_modules = "res_agi", ); diff --git a/apps/app_stasis.c b/apps/app_stasis.c index 81c58e8b0..8d09349b9 100644 --- a/apps/app_stasis.c +++ b/apps/app_stasis.c @@ -144,5 +144,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Stasis dialplan applicat .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_stasis", + .requires = "res_stasis", ); diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 0bcfa4f3a..4853a53f9 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -16488,5 +16488,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc, .load = load_module, .unload = unload_module, .reload = reload, - .nonoptreq = "res_adsi,res_smdi", + .optional_modules = "res_adsi,res_smdi", ); diff --git a/build_tools/download_externals b/build_tools/download_externals index efeb6c53c..f27271fd5 100755 --- a/build_tools/download_externals +++ b/build_tools/download_externals @@ -165,7 +165,7 @@ if [[ -f ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml ]] ; then fi fi - cs=$(md5sum ${f} | cut -b1-32) + cs=$(${MD5} ${f} | cut -b1-32) if [[ "${cs}" != "${sum}" ]] ; then echo Checksum mismatch: ${f} need_install=1 @@ -214,7 +214,7 @@ trap "rm -rf ${cache_dir}/${module_dir} ; rm -rf ${tmpdir}" EXIT echo "${full_name}: Installing." if [[ $EUID == 0 ]] ; then - install_params="--group=0 --owner=0" + install_params="-g 0 -o 0" fi names=$(${XMLSTARLET} sel -t -m "//file" -v "@name" -n ${cache_dir}/${module_dir}/manifest.xml) @@ -229,7 +229,7 @@ for name in ${names} ; do mode=0644 fi - ${INSTALL} -Dp ${install_params} --mode=${mode} ${source_path} ${install_path} + ${INSTALL} -Dp ${install_params} -m ${mode} ${source_path} ${install_path} done ${INSTALL} -Dp ${install_params} --mode=0644 ${cache_dir}/${module_dir}/manifest.xml ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml diff --git a/cel/cel_odbc.c b/cel/cel_odbc.c index a289b877c..05c1095cb 100644 --- a/cel/cel_odbc.c +++ b/cel/cel_odbc.c @@ -849,7 +849,7 @@ static int reload(void) return AST_MODULE_LOAD_SUCCESS; } -AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, ODBC_BACKEND_NAME, +AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "ODBC CEL backend", .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 4859d1a60..de2c15279 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -19542,5 +19542,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, tdesc, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, - .nonoptreq = "res_smdi", + .optional_modules = "res_smdi", ); diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 469fcda9e..eade5d13c 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -14902,5 +14902,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchan .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, - .nonoptreq = "res_crypto", + .optional_modules = "res_crypto", ); diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index 547226c80..2ac7690a6 100644 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -5025,5 +5025,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Media Gateway Control .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, - .nonoptreq = "res_pktccops", + .optional_modules = "res_pktccops", ); diff --git a/channels/chan_motif.c b/channels/chan_motif.c index df1eeb8ce..05184ca04 100644 --- a/channels/chan_motif.c +++ b/channels/chan_motif.c @@ -2821,4 +2821,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Motif Jingle Channel .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, + .requires = "res_xmpp", ); diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 4c30d335b..68da4a1bb 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -3110,4 +3110,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Channel Driver" .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, + .requires = "res_pjsip,res_pjsip_session", ); diff --git a/channels/chan_rtp.c b/channels/chan_rtp.c index 0a59e330e..7d9e26db8 100644 --- a/channels/chan_rtp.c +++ b/channels/chan_rtp.c @@ -432,4 +432,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "RTP Media Channel", .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, + .requires = "res_rtp_multicast", ); diff --git a/channels/chan_sip.c b/channels/chan_sip.c index e8cc591a3..fa9899027 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -35737,5 +35737,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Session Initiation Pr .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, - .nonoptreq = "res_crypto,res_http_websocket", + .optional_modules = "res_crypto,res_http_websocket", ); diff --git a/configs/samples/followme.conf.sample b/configs/samples/followme.conf.sample index 487554d81..25421e651 100644 --- a/configs/samples/followme.conf.sample +++ b/configs/samples/followme.conf.sample @@ -39,7 +39,11 @@ status_prompt=>followme/status sorry_prompt=>followme/sorry ; The global default for 'I'm sorry, but we were unable to locate your party' message. ; -; +connecting_prompt=> +; The global default sound file name for 'Please say hello to the caller' message. +; Setting to an empty string skips playing the prompt. The default is no prompt +; file name. + [default] musicclass=>default ; The moh class that should be used for the caller while they are waiting to be connected. @@ -95,3 +99,9 @@ status_prompt=>followme/status sorry_prompt=>followme/sorry ; The 'I'm sorry, but we were unable to locate your party' message prompt. Default ; is the global default. +; +connecting_prompt=> +; The sound file name for 'Please say hello to the caller' message. Default is the +; global default. +; + diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample index 849932069..a39a8675a 100644 --- a/configs/samples/pjsip.conf.sample +++ b/configs/samples/pjsip.conf.sample @@ -635,6 +635,7 @@ ; "username": Identify by the From or To username and domain ; "auth_username": Identify by the Authorization username and realm ; "ip": Identify by the source IP address + ; "header": Identify by a configured SIP header value. ; In the username and auth_username cases, if an exact match ; on both username and domain/realm fails, the match is ; retried with just the username. @@ -993,11 +994,11 @@ ; (default: "no") ;endpoint_identifier_order=ip,username,anonymous ; The order by which endpoint identifiers are given priority. - ; Currently, "ip", "username", "auth_username" and "anonymous" are valid - ; identifiers as registered by the res_pjsip_endpoint_identifier_* modules. - ; Some modules like res_pjsip_endpoint_identifier_user register more than - ; one identifier. Use the CLI command "pjsip show identifiers" to see the - ; identifiers currently available. + ; Currently, "ip", "header", "username", "auth_username" and "anonymous" + ; are valid identifiers as registered by the res_pjsip_endpoint_identifier_* + ; modules. Some modules like res_pjsip_endpoint_identifier_user register + ; more than one identifier. Use the CLI command "pjsip show identifiers" + ; to see the identifiers currently available. ; (default: ip,username,anonymous) ;max_initial_qualify_time=4 ; The maximum amount of time (in seconds) from ; startup that qualifies should be attempted on all @@ -7604,8 +7604,10 @@ $as_echo "no" >&6; } fi -# Extract the first word of "xmlstarlet", so it can be a program name with args. -set dummy xmlstarlet; ac_word=$2 +for ac_prog in xmlstarlet xml +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XMLSTARLET+:} false; then : @@ -7631,7 +7633,6 @@ done done IFS=$as_save_IFS - test -z "$ac_cv_path_XMLSTARLET" && ac_cv_path_XMLSTARLET=":" ;; esac fi @@ -7645,6 +7646,10 @@ $as_echo "no" >&6; } fi + test -n "$XMLSTARLET" && break +done +test -n "$XMLSTARLET" || XMLSTARLET=":" + # Extract the first word of "bash", so it can be a program name with args. set dummy bash; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -13566,11 +13571,41 @@ if test "$ac_cv_header_sys_wait_h" != "yes"; then as_fn_error $? "*** POSIX.1 compatible sys/wait.h is required." "$LINENO" 5 fi +for ac_header in sys/types.h netinet/in.h arpa/nameser.h netdb.h resolv.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> /* inet_ functions / structs */ +#endif +#ifdef HAVE_ARPA_NAMESER_H +# include <arpa/nameser.h> /* DNS HEADER struct */ +#endif +#ifdef HAVE_NETDB_H +# include <netdb.h> +#endif +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +if test "$ac_cv_header_resolv_h" != "yes"; then + as_fn_error $? "*** resolv.h is required." "$LINENO" 5 +fi + # Check for headers that are unconditionally required on all platforms. Do not use # this to check for headers that are only needed by modules. for ac_header in \ arpa/nameser.h assert.h ctype.h dlfcn.h errno.h fcntl.h float.h grp.h \ - inttypes.h limits.h locale.h math.h pwd.h netinet/in.h regex.h resolv.h \ + inttypes.h limits.h locale.h math.h pwd.h netinet/in.h regex.h \ sched.h stdarg.h stdint.h stdio.h stdlib.h string.h syslog.h \ sys/file.h sys/ioctl.h sys/param.h sys/resource.h sys/socket.h sys/stat.h \ sys/time.h sys/types.h sys/un.h \ diff --git a/configure.ac b/configure.ac index f0a978ee4..64ecbfab3 100644 --- a/configure.ac +++ b/configure.ac @@ -281,7 +281,7 @@ AC_PATH_PROG([RUBBER], [rubber], :) AC_PATH_PROG([CATDVI], [catdvi], :) AC_PATH_PROG([KPATHSEA], [kpsewhich], :) AC_PATH_PROG([XMLLINT], [xmllint], :) -AC_PATH_PROG([XMLSTARLET], [xmlstarlet], :) +AC_PATH_PROGS([XMLSTARLET], [xmlstarlet xml], :) AC_PATH_PROG([BASH], [bash], :) AC_PATH_PROG([GIT], [git], :) AC_PATH_PROG([ALEMBIC], [alembic], :) @@ -605,11 +605,16 @@ if test "$ac_cv_header_sys_wait_h" != "yes"; then AC_MSG_ERROR([*** POSIX.1 compatible sys/wait.h is required.]) fi +AC_HEADER_RESOLV +if test "$ac_cv_header_resolv_h" != "yes"; then + AC_MSG_ERROR([*** resolv.h is required.]) +fi + # Check for headers that are unconditionally required on all platforms. Do not use # this to check for headers that are only needed by modules. AC_CHECK_HEADERS([ \ arpa/nameser.h assert.h ctype.h dlfcn.h errno.h fcntl.h float.h grp.h \ - inttypes.h limits.h locale.h math.h pwd.h netinet/in.h regex.h resolv.h \ + inttypes.h limits.h locale.h math.h pwd.h netinet/in.h regex.h \ sched.h stdarg.h stdint.h stdio.h stdlib.h string.h syslog.h \ sys/file.h sys/ioctl.h sys/param.h sys/resource.h sys/socket.h sys/stat.h \ sys/time.h sys/types.h sys/un.h \ diff --git a/contrib/ast-db-manage/config/versions/52798ad97bdf_add_pjsip_identify_by_header.py b/contrib/ast-db-manage/config/versions/52798ad97bdf_add_pjsip_identify_by_header.py new file mode 100644 index 000000000..ab5939cfe --- /dev/null +++ b/contrib/ast-db-manage/config/versions/52798ad97bdf_add_pjsip_identify_by_header.py @@ -0,0 +1,57 @@ +"""add pjsip identify by header + +Revision ID: 52798ad97bdf +Revises: e2f04d309071 +Create Date: 2018-01-08 12:16:02.782277 + +""" + +# revision identifiers, used by Alembic. +revision = '52798ad97bdf' +down_revision = 'e2f04d309071' + +from alembic import op +import sqlalchemy as sa + + +def column_upgrade(table_name, column_name, enum_name): + if op.get_context().bind.dialect.name != 'postgresql': + if op.get_context().bind.dialect.name == 'mssql': + op.drop_constraint('ck_ps_endpoints_identify_by_pjsip_identify_by_values', + table_name) + op.alter_column(table_name, column_name, type_=sa.String(80)) + return + + # Postgres requires a few more steps + op.execute('ALTER TABLE ' + table_name + ' ALTER COLUMN ' + column_name + + ' TYPE varchar(80) USING identify_by::text::' + enum_name) + + op.execute('DROP TYPE ' + enum_name) + + +def column_downgrade(table_name, column_name, enum_name, enum_values): + if op.get_context().bind.dialect.name != 'postgresql': + op.alter_column(table_name, column_name, + type_=sa.Enum(*enum_values, name=enum_name)) + return + + # Postgres requires a few more steps + updated = sa.Enum(*enum_values, name=enum_name) + updated.create(op.get_bind(), checkfirst=False) + + op.execute('ALTER TABLE ' + table_name + ' ALTER COLUMN ' + column_name + + ' TYPE ' + enum_name + ' USING identify_by::text::' + enum_name) + + +def upgrade(): + # The ps_endpoints identify_by column has always been a comma separated + # list of enum values. This is better represented as a string anyway to + # avoid database compatibility issues. Also future changes are likely + # to allow loadable endpoint identifier names and negating fixed enum + # benefits. + column_upgrade('ps_endpoints', 'identify_by', 'pjsip_identify_by_values') + + +def downgrade(): + column_downgrade('ps_endpoints', 'identify_by', 'pjsip_identify_by_values', + ['username', 'auth_username', 'ip']) diff --git a/funcs/func_aes.c b/funcs/func_aes.c index 7208cd4c8..af3f257e5 100644 --- a/funcs/func_aes.c +++ b/funcs/func_aes.c @@ -180,5 +180,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "AES dialplan functions", .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_crypto", + .requires = "res_crypto", ); diff --git a/funcs/func_pjsip_aor.c b/funcs/func_pjsip_aor.c index 799e9e4ed..589f667af 100644 --- a/funcs/func_pjsip_aor.c +++ b/funcs/func_pjsip_aor.c @@ -181,4 +181,9 @@ static int load_module(void) return ast_custom_function_register(&pjsip_aor_function); } -AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Get information about a PJSIP AOR"); +AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Get information about a PJSIP AOR", + .support_level = AST_MODULE_SUPPORT_CORE, + .load = load_module, + .unload = unload_module, + .requires = "res_pjsip", +); diff --git a/funcs/func_pjsip_contact.c b/funcs/func_pjsip_contact.c index c8403655a..fac4cb68c 100644 --- a/funcs/func_pjsip_contact.c +++ b/funcs/func_pjsip_contact.c @@ -198,4 +198,9 @@ static int load_module(void) return ast_custom_function_register(&pjsip_contact_function); } -AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Get information about a PJSIP contact"); +AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Get information about a PJSIP contact", + .support_level = AST_MODULE_SUPPORT_CORE, + .load = load_module, + .unload = unload_module, + .requires = "res_pjsip", +); diff --git a/funcs/func_pjsip_endpoint.c b/funcs/func_pjsip_endpoint.c index a64d93b1e..e4a6abab3 100644 --- a/funcs/func_pjsip_endpoint.c +++ b/funcs/func_pjsip_endpoint.c @@ -156,4 +156,9 @@ static int load_module(void) return ast_custom_function_register(&pjsip_endpoint_function); } -AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Get information about a PJSIP endpoint"); +AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Get information about a PJSIP endpoint", + .support_level = AST_MODULE_SUPPORT_CORE, + .load = load_module, + .unload = unload_module, + .requires = "res_pjsip", +); diff --git a/include/asterisk/module.h b/include/asterisk/module.h index 103cd3053..ebd41c06d 100644 --- a/include/asterisk/module.h +++ b/include/asterisk/module.h @@ -304,26 +304,28 @@ enum ast_module_load_priority { }; struct ast_module_info { - /*! * The 'self' pointer for a module; it will be set by the loader before * it calls the module's load_module() entrypoint, and used by various * other macros that need to identify the module. */ - struct ast_module *self; - enum ast_module_load_result (*load)(void); /*!< register stuff etc. Optional. */ - int (*reload)(void); /*!< config etc. Optional. */ - int (*unload)(void); /*!< unload. called with the module locked */ - const char *name; /*!< name of the module for loader reference and CLI commands */ - const char *description; /*!< user friendly description of the module. */ + /*! Register stuff etc. Optional. */ + enum ast_module_load_result (*load)(void); + /*! Config etc. Optional. */ + int (*reload)(void); + /*! Unload. called with the module locked */ + int (*unload)(void); + /*! Name of the module for loader reference and CLI commands */ + const char *name; + /*! User friendly description of the module. */ + const char *description; /*! * This holds the ASTERISK_GPL_KEY, signifiying that you agree to the terms of * the Asterisk license as stated in the ASTERISK_GPL_KEY. Your module will not * load if it does not return the EXACT key string. */ - const char *key; unsigned int flags; @@ -337,10 +339,42 @@ struct ast_module_info { * on load. */ unsigned char load_pri; - /*! Modules which should be loaded first, in comma-separated string format. - * These are only required for loading, when the optional_api header file - * detects that the compiler does not support the optional API featureset. */ - const char *nonoptreq; + /*! Modules which must always be started first, in comma-separated string format. */ + const char *requires; + + /*! + * \brief Comma-separated list of optionally required modules. + * + * The listed modules are optional, but load order is enforced. For example + * app_voicemail optionally requires res_adsi. This means that app_voicemail + * will happily load without res_adsi, but if both are being loaded the module + * loader will force res_adsi to start first. + */ + const char *optional_modules; + + /*! + * \brief Modules that we provide enhanced functionality for. + * + * This is similar to a "requires" but specifies that we add functionality to + * the other modules. Any module that requires something we "enhances" will + * also require us, but only if we are dlopen'ed. + * + * Example: + * - res_fax_spandsp has .enhances = "res_fax". + * - res_my_module has .requires = "res_fax" but has no direct knowledge + * of res_fax_spandsp. + * + * This forces the following startup order among the 3 modules: + * 1) res_fax starts. + * 2) res_fax_spandsp starts, holds a reference to res_fax. + * 3) res_mymod starts, holds a reference to res_fax and res_fax_spandsp. + * + * If res_fax_spandsp were not being loaded res_mymod would load with + * res_fax only. If res_fax_spandsp were later loaded res_mymod would + * get a reference to it. + */ + const char *enhances; + /*! The support level for the given module */ enum ast_module_support_level support_level; }; @@ -411,6 +445,8 @@ void __ast_module_unref(struct ast_module *mod, const char *file, int line, cons AST_BUILDOPT_SUM, \ load_pri, \ NULL, \ + NULL, \ + NULL, \ support_level, \ }; \ static void __attribute__((constructor)) __reg_module(void) \ diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 6c48d2e84..66b99b8f7 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -443,6 +443,8 @@ enum ast_sip_endpoint_identifier_type { AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME = (1 << 1), /*! Identify based on source IP address */ AST_SIP_ENDPOINT_IDENTIFY_BY_IP = (1 << 2), + /*! Identify based on arbitrary headers */ + AST_SIP_ENDPOINT_IDENTIFY_BY_HEADER = (1 << 3), }; AST_VECTOR(ast_sip_identify_by_vector, enum ast_sip_endpoint_identifier_type); diff --git a/include/asterisk/vector.h b/include/asterisk/vector.h index 8bd1cefef..d1b2973bf 100644 --- a/include/asterisk/vector.h +++ b/include/asterisk/vector.h @@ -51,8 +51,38 @@ /*! \brief Integer vector definition */ AST_VECTOR(ast_vector_int, int); -/*! \brief String vector definition */ +/*! \brief String vector definitions */ AST_VECTOR(ast_vector_string, char *); +AST_VECTOR(ast_vector_const_string, const char *); + +/*! Options to override default processing of ast_vector_string_split. */ +enum ast_vector_string_split_flags { + /*! Do not trim whitespace from values. */ + AST_VECTOR_STRING_SPLIT_NO_TRIM = 0x01, + /*! Append empty strings to the vector. */ + AST_VECTOR_STRING_SPLIT_ALLOW_EMPTY = 0x02, +}; + +/*! + * \brief Append a string vector by splitting a string. + * + * \param dest Pointer to an initialized vector. + * \param input String buffer to split. + * \param delim String delimeter passed to strsep. + * \param flags Processing options defined by \ref enum ast_vector_string_split_flags. + * \param excludes_cmp NULL or a function like strcmp to exclude duplicate strings. + * + * \retval 0 Success + * \retval -1 Failure + * + * \note All elements added to the vector are allocated. The caller is always + * responsible for calling ast_free on each element in the vector even + * after failure. It's possible for this function to successfully add + * some elements before failing. + */ +int ast_vector_string_split(struct ast_vector_string *dest, + const char *input, const char *delim, int flags, + int (*excludes_cmp)(const char *s1, const char *s2)); /*! * \brief Define a vector structure with a read/write lock diff --git a/main/loader.c b/main/loader.c index 88c1cda97..8f3fbe0c9 100644 --- a/main/loader.c +++ b/main/loader.c @@ -524,9 +524,6 @@ static void unload_dynamic_module(struct ast_module *mod) * If somehow there was another dlopen() on the same module (unlikely, * since that all is supposed to happen in loader.c). * - * Or the lazy resolution of a global symbol (very likely, since that is - * how we load all of our modules that export global symbols). - * * Avoid the temptation of repeating the dlclose(). The other code that * dlopened the module still has its module reference, and should close * it itself. In other situations, dlclose() will happily return success @@ -631,7 +628,8 @@ static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int modules_shutdown(void) { struct ast_module *mod; - int somethingchanged = 1, final = 0; + int somethingchanged; + int res; AST_DLLIST_LOCK(&module_list); @@ -639,17 +637,11 @@ int modules_shutdown(void) * may be still in use, even if all channels are dead. We must therefore * check the usecount before asking modules to unload. */ do { - if (!somethingchanged) { - /*!\note If we go through the entire list without changing - * anything, ignore the usecounts and unload, then exit. */ - final = 1; - } - /* Reset flag before traversing the list */ somethingchanged = 0; AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) { - if (!final && mod->usecount) { + if (mod->usecount) { ast_debug(1, "Passing on %s: its use count is %d\n", mod->resource, mod->usecount); continue; @@ -672,12 +664,12 @@ int modules_shutdown(void) } } } - } while (somethingchanged && !final); + } while (somethingchanged); - final = AST_DLLIST_EMPTY(&module_list); + res = AST_DLLIST_EMPTY(&module_list); AST_DLLIST_UNLOCK(&module_list); - return !final; + return !res; } int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force) @@ -1168,7 +1160,7 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi if ((mod = find_resource(resource_name, 0))) { if (mod->flags.running) { - ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name); + ast_log(LOG_WARNING, "Module '%s' already loaded and running.\n", resource_name); return AST_MODULE_LOAD_DECLINE; } if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) @@ -1248,6 +1240,11 @@ static struct load_order_entry *add_to_load_order(const char *resource, struct l return NULL; order->resource = ast_strdup(resource); + if (!order->resource) { + ast_free(order); + + return NULL; + } order->required = required; AST_LIST_INSERT_TAIL(load_order, order, entry); @@ -1430,7 +1427,6 @@ int load_modules(unsigned int preload_only) add_to_load_order(v->value, &load_order, 1); ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name); } - } /* check if 'autoload' is on */ diff --git a/main/strings.c b/main/strings.c index 82e315aea..ad96df249 100644 --- a/main/strings.c +++ b/main/strings.c @@ -40,6 +40,7 @@ #include <regex.h> #include "asterisk/strings.h" #include "asterisk/pbx.h" +#include "asterisk/vector.h" /*! * core handler for dynamic strings. @@ -389,3 +390,44 @@ char *ast_read_line_from_buffer(char **buffer) return start; } + +int ast_vector_string_split(struct ast_vector_string *dest, + const char *input, const char *delim, int flags, + int (*excludes_cmp)(const char *s1, const char *s2)) +{ + char *buf; + char *cur; + int no_trim = flags & AST_VECTOR_STRING_SPLIT_NO_TRIM; + int allow_empty = flags & AST_VECTOR_STRING_SPLIT_ALLOW_EMPTY; + + ast_assert(dest != NULL); + ast_assert(!ast_strlen_zero(delim)); + + if (ast_strlen_zero(input)) { + return 0; + } + + buf = ast_strdupa(input); + while ((cur = strsep(&buf, delim))) { + if (!no_trim) { + cur = ast_strip(cur); + } + + if (!allow_empty && ast_strlen_zero(cur)) { + continue; + } + + if (excludes_cmp && AST_VECTOR_GET_CMP(dest, cur, !excludes_cmp)) { + continue; + } + + cur = ast_strdup(cur); + if (!cur || AST_VECTOR_APPEND(dest, cur)) { + ast_free(cur); + + return -1; + } + } + + return 0; +} diff --git a/main/taskprocessor.c b/main/taskprocessor.c index 6793542ab..cf82efff2 100644 --- a/main/taskprocessor.c +++ b/main/taskprocessor.c @@ -112,7 +112,13 @@ struct ast_taskprocessor_listener { void *user_data; }; -#define TPS_MAX_BUCKETS 7 +#ifdef LOW_MEMORY +#define TPS_MAX_BUCKETS 61 +#else +/*! \brief Number of buckets in the tps_singletons container. */ +#define TPS_MAX_BUCKETS 1567 +#endif + /*! \brief tps_singletons is the astobj2 container for taskprocessor singletons */ static struct ao2_container *tps_singletons; diff --git a/pbx/pbx_ael.c b/pbx/pbx_ael.c index 6517b3aeb..d55f2d42a 100644 --- a/pbx/pbx_ael.c +++ b/pbx/pbx_ael.c @@ -292,6 +292,7 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk Extension Langu .load = load_module, .unload = unload_module, .reload = reload, + .requires = "res_ael_share", ); #ifdef AAL_ARGCHECK diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c index e0aeb4903..92e71981f 100644 --- a/pbx/pbx_dundi.c +++ b/pbx/pbx_dundi.c @@ -5063,5 +5063,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Distributed Universal Nu .load = load_module, .unload = unload_module, .reload = reload, - .nonoptreq = "res_crypto", + .optional_modules = "res_crypto", ); diff --git a/res/res_agi.c b/res/res_agi.c index 393a50351..2d0dc2743 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -4717,4 +4717,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_speech", ); diff --git a/res/res_ari.c b/res/res_ari.c index 9104eded3..6ce25a582 100644 --- a/res/res_ari.c +++ b/res/res_ari.c @@ -1197,6 +1197,7 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ .load = load_module, .unload = unload_module, .reload = reload_module, - .nonoptreq = "res_http_websocket", + .optional_modules = "res_http_websocket", + .requires = "res_stasis", .load_pri = AST_MODPRI_APP_DEPEND, ); diff --git a/res/res_ari_applications.c b/res/res_ari_applications.c index cf700c464..323bdb39a 100644 --- a/res/res_ari_applications.c +++ b/res/res_ari_applications.c @@ -518,5 +518,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Sta .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_ari_asterisk.c b/res/res_ari_asterisk.c index eb0617b4c..9f76f939b 100644 --- a/res/res_ari_asterisk.c +++ b/res/res_ari_asterisk.c @@ -1239,5 +1239,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Ast .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_ari_bridges.c b/res/res_ari_bridges.c index 35fd3bd7f..34b9d898c 100644 --- a/res/res_ari_bridges.c +++ b/res/res_ari_bridges.c @@ -1579,5 +1579,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Bri .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_ari_channels.c b/res/res_ari_channels.c index f6befcc90..7862c1006 100644 --- a/res/res_ari_channels.c +++ b/res/res_ari_channels.c @@ -2869,5 +2869,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Cha .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_ari_device_states.c b/res/res_ari_device_states.c index f39393562..ec8890b1e 100644 --- a/res/res_ari_device_states.c +++ b/res/res_ari_device_states.c @@ -349,5 +349,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Dev .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_ari_endpoints.c b/res/res_ari_endpoints.c index d1242c0fb..07197ca97 100644 --- a/res/res_ari_endpoints.c +++ b/res/res_ari_endpoints.c @@ -473,5 +473,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - End .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_ari_events.c b/res/res_ari_events.c index f916d0e4e..f750a5454 100644 --- a/res/res_ari_events.c +++ b/res/res_ari_events.c @@ -473,5 +473,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Web .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_ari_mailboxes.c b/res/res_ari_mailboxes.c index 1f6d2cc81..6469f936e 100644 --- a/res/res_ari_mailboxes.c +++ b/res/res_ari_mailboxes.c @@ -355,5 +355,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Mai .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_ari_playbacks.c b/res/res_ari_playbacks.c index 40099cfb4..0148a7400 100644 --- a/res/res_ari_playbacks.c +++ b/res/res_ari_playbacks.c @@ -307,5 +307,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Pla .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_ari_recordings.c b/res/res_ari_recordings.c index fe3d343ee..531ff6574 100644 --- a/res/res_ari_recordings.c +++ b/res/res_ari_recordings.c @@ -891,5 +891,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Rec .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_ari_sounds.c b/res/res_ari_sounds.c index 8d5928a50..5c27ebd92 100644 --- a/res/res_ari_sounds.c +++ b/res/res_ari_sounds.c @@ -237,5 +237,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Sou .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); diff --git a/res/res_chan_stats.c b/res/res_chan_stats.c index 061d0867e..dbc79f03e 100644 --- a/res/res_chan_stats.c +++ b/res/res_chan_stats.c @@ -182,5 +182,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Example of how to use St .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, - .nonoptreq = "res_statsd" + .requires = "res_statsd" ); diff --git a/res/res_endpoint_stats.c b/res/res_endpoint_stats.c index 1e3f104c2..7ce44f958 100644 --- a/res/res_endpoint_stats.c +++ b/res/res_endpoint_stats.c @@ -151,5 +151,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Endpoint statistics", .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, - .nonoptreq = "res_statsd" + .requires = "res_statsd" ); diff --git a/res/res_fax_spandsp.c b/res/res_fax_spandsp.c index a3a82e463..045dbc708 100644 --- a/res/res_fax_spandsp.c +++ b/res/res_fax_spandsp.c @@ -1266,4 +1266,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Spandsp G.711 and T.38 F .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, + .enhances = "res_fax", ); diff --git a/res/res_hep_pjsip.c b/res/res_hep_pjsip.c index 6283efc76..ff0267501 100644 --- a/res/res_hep_pjsip.c +++ b/res/res_hep_pjsip.c @@ -253,4 +253,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "PJSIP HEPv3 Logger", .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, + .requires = "res_hep,res_pjsip", ); diff --git a/res/res_hep_rtcp.c b/res/res_hep_rtcp.c index afad0c845..199c8164d 100644 --- a/res/res_hep_rtcp.c +++ b/res/res_hep_rtcp.c @@ -184,4 +184,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RTCP HEPv3 Logger", .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, + .requires = "res_hep", ); diff --git a/res/res_mwi_external_ami.c b/res/res_mwi_external_ami.c index 8419f2fff..8639fad40 100644 --- a/res/res_mwi_external_ami.c +++ b/res/res_mwi_external_ami.c @@ -370,4 +370,6 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "AMI support for external .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, + .load_pri = AST_MODPRI_CHANNEL_DEPEND - 5, + .requires = "res_mwi_external", ); diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 0311dfd4b..07fc980ef 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -323,6 +323,17 @@ endpoint identification. </para> </enum> + <enum name="header"> + <para>Matches the endpoint based on a configured SIP header + value. + </para> + <para>This method of identification is not configured here + but simply allowed by this configuration option. See the + documentation for the <literal>identify</literal> + configuration section for more details on this method of + endpoint identification. + </para> + </enum> </enumlist> </description> </configOption> @@ -5125,4 +5136,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 5, + .requires = "res_pjproject", ); diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index c79877a85..d1bfdfe01 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -594,6 +594,9 @@ static const char *sip_endpoint_identifier_type2str(enum ast_sip_endpoint_identi case AST_SIP_ENDPOINT_IDENTIFY_BY_IP: str = "ip"; break; + case AST_SIP_ENDPOINT_IDENTIFY_BY_HEADER: + str = "header"; + break; } return str; } @@ -617,6 +620,8 @@ static int sip_endpoint_identifier_str2type(const char *str) method = AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME; } else if (!strcasecmp(str, "ip")) { method = AST_SIP_ENDPOINT_IDENTIFY_BY_IP; + } else if (!strcasecmp(str, "header")) { + method = AST_SIP_ENDPOINT_IDENTIFY_BY_HEADER; } else { method = -1; } diff --git a/res/res_pjsip_acl.c b/res/res_pjsip_acl.c index 5c10e5779..926986422 100644 --- a/res/res_pjsip_acl.c +++ b/res/res_pjsip_acl.c @@ -321,4 +321,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP ACL Resource", .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_authenticator_digest.c b/res/res_pjsip_authenticator_digest.c index ef57e3754..b6f2b74ff 100644 --- a/res/res_pjsip_authenticator_digest.c +++ b/res/res_pjsip_authenticator_digest.c @@ -554,4 +554,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP authentication .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 5, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_caller_id.c b/res/res_pjsip_caller_id.c index 64191a750..16731479e 100644 --- a/res/res_pjsip_caller_id.c +++ b/res/res_pjsip_caller_id.c @@ -19,7 +19,6 @@ /*** MODULEINFO <depend>pjproject</depend> <depend>res_pjsip</depend> - <depend>res_pjsip_session</depend> <support_level>core</support_level> ***/ @@ -764,4 +763,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Caller ID Suppo .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_dialog_info_body_generator.c b/res/res_pjsip_dialog_info_body_generator.c index 7c386e3b2..866ea9df8 100644 --- a/res/res_pjsip_dialog_info_body_generator.c +++ b/res/res_pjsip_dialog_info_body_generator.c @@ -20,7 +20,6 @@ <depend>pjproject</depend> <depend>res_pjsip</depend> <depend>res_pjsip_pubsub</depend> - <depend>res_pjsip_exten_state</depend> <support_level>core</support_level> ***/ @@ -219,4 +218,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Extension State .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, + .requires = "res_pjsip,res_pjsip_pubsub", ); diff --git a/res/res_pjsip_diversion.c b/res/res_pjsip_diversion.c index efb5489f8..84c42dca8 100644 --- a/res/res_pjsip_diversion.c +++ b/res/res_pjsip_diversion.c @@ -19,7 +19,6 @@ /*** MODULEINFO <depend>pjproject</depend> <depend>res_pjsip</depend> - <depend>res_pjsip_session</depend> <support_level>core</support_level> ***/ @@ -429,4 +428,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Add Diversion H .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_dlg_options.c b/res/res_pjsip_dlg_options.c index de1ac97ef..565ad2afc 100644 --- a/res/res_pjsip_dlg_options.c +++ b/res/res_pjsip_dlg_options.c @@ -19,7 +19,6 @@ /*** MODULEINFO <depend>pjproject</depend> <depend>res_pjsip</depend> - <depend>res_pjsip_session</depend> <support_level>core</support_level> ***/ @@ -103,4 +102,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP OPTIONS in dialog .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_dtmf_info.c b/res/res_pjsip_dtmf_info.c index e534f3e27..68df61785 100644 --- a/res/res_pjsip_dtmf_info.c +++ b/res/res_pjsip_dtmf_info.c @@ -19,7 +19,6 @@ /*** MODULEINFO <depend>pjproject</depend> <depend>res_pjsip</depend> - <depend>res_pjsip_session</depend> <support_level>core</support_level> ***/ @@ -178,4 +177,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP DTMF INFO Suppo .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_empty_info.c b/res/res_pjsip_empty_info.c index 774f9de7e..c67835ce0 100644 --- a/res/res_pjsip_empty_info.c +++ b/res/res_pjsip_empty_info.c @@ -19,7 +19,6 @@ /*** MODULEINFO <depend>pjproject</depend> <depend>res_pjsip</depend> - <depend>res_pjsip_session</depend> <support_level>core</support_level> ***/ @@ -84,4 +83,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Empty INFO Supp .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_endpoint_identifier_anonymous.c b/res/res_pjsip_endpoint_identifier_anonymous.c index b47aefa94..16662ebd5 100644 --- a/res/res_pjsip_endpoint_identifier_anonymous.c +++ b/res/res_pjsip_endpoint_identifier_anonymous.c @@ -132,4 +132,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "PJSIP Anonymous endpoint .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c index a672b333a..ee47e4d4e 100644 --- a/res/res_pjsip_endpoint_identifier_ip.c +++ b/res/res_pjsip_endpoint_identifier_ip.c @@ -186,7 +186,7 @@ static int header_identify_match_check(void *obj, void *arg, int flags) return 0; } - return CMP_MATCH | CMP_STOP; + return CMP_MATCH; } /*! \brief Comparator function for matching an object by IP address */ @@ -201,7 +201,7 @@ static int ip_identify_match_check(void *obj, void *arg, int flags) ast_debug(3, "Source address %s matches identify '%s'\n", ast_sockaddr_stringify(addr), ast_sorcery_object_get_id(identify)); - return CMP_MATCH | CMP_STOP; + return CMP_MATCH; } else { ast_debug(3, "Source address %s does not match identify '%s'\n", ast_sockaddr_stringify(addr), @@ -210,48 +210,62 @@ static int ip_identify_match_check(void *obj, void *arg, int flags) } } -static struct ast_sip_endpoint *ip_identify(pjsip_rx_data *rdata) +static struct ast_sip_endpoint *common_identify(ao2_callback_fn *identify_match_cb, void *arg) { - struct ast_sockaddr addr = { { 0, } }; RAII_VAR(struct ao2_container *, candidates, NULL, ao2_cleanup); - RAII_VAR(struct ip_identify_match *, match, NULL, ao2_cleanup); + struct ip_identify_match *match; struct ast_sip_endpoint *endpoint; /* If no possibilities exist return early to save some time */ - if (!(candidates = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL)) || - !ao2_container_count(candidates)) { + candidates = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify", + AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL); + if (!candidates || !ao2_container_count(candidates)) { ast_debug(3, "No identify sections to match against\n"); return NULL; } - ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID); - ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port); - - match = ao2_callback(candidates, 0, ip_identify_match_check, &addr); + match = ao2_callback(candidates, 0, identify_match_cb, arg); if (!match) { - ast_debug(3, "Identify checks by IP address failed to find match: '%s' did not match any identify section rules\n", - ast_sockaddr_stringify(&addr)); - match = ao2_callback(candidates, 0, header_identify_match_check, rdata); - if (!match) { - return NULL; - } + return NULL; } - endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", match->endpoint_name); + endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", + match->endpoint_name); if (endpoint) { - ast_debug(3, "Retrieved endpoint %s\n", ast_sorcery_object_get_id(endpoint)); + ast_debug(3, "Identify '%s' SIP message matched to endpoint %s\n", + ast_sorcery_object_get_id(match), match->endpoint_name); } else { - ast_log(LOG_WARNING, "Identify section '%s' points to endpoint '%s' but endpoint could not be looked up\n", - ast_sorcery_object_get_id(match), match->endpoint_name); + ast_log(LOG_WARNING, "Identify '%s' points to endpoint '%s' but endpoint could not be found\n", + ast_sorcery_object_get_id(match), match->endpoint_name); } + ao2_ref(match, -1); return endpoint; } +static struct ast_sip_endpoint *ip_identify(pjsip_rx_data *rdata) +{ + struct ast_sockaddr addr = { { 0, } }; + + ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID); + ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port); + + return common_identify(ip_identify_match_check, &addr); +} + static struct ast_sip_endpoint_identifier ip_identifier = { .identify_endpoint = ip_identify, }; +static struct ast_sip_endpoint *header_identify(pjsip_rx_data *rdata) +{ + return common_identify(header_identify_match_check, rdata); +} + +static struct ast_sip_endpoint_identifier header_identifier = { + .identify_endpoint = header_identify, +}; + /*! \brief Helper function which performs a host lookup and adds result to identify match */ static int ip_identify_match_host_lookup(struct ip_identify_match *identify, const char *host) { @@ -720,6 +734,7 @@ static int load_module(void) ast_sorcery_load_object(ast_sip_get_sorcery(), "identify"); ast_sip_register_endpoint_identifier_with_name(&ip_identifier, "ip"); + ast_sip_register_endpoint_identifier_with_name(&header_identifier, "header"); ast_sip_register_endpoint_formatter(&endpoint_identify_formatter); cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL); @@ -764,4 +779,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP IP endpoint ide .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_endpoint_identifier_user.c b/res/res_pjsip_endpoint_identifier_user.c index ff97a62e4..1b0c7d99a 100644 --- a/res/res_pjsip_endpoint_identifier_user.c +++ b/res/res_pjsip_endpoint_identifier_user.c @@ -214,4 +214,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP username endpoi .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_exten_state.c b/res/res_pjsip_exten_state.c index 3e756134c..e70eba7cd 100644 --- a/res/res_pjsip_exten_state.c +++ b/res/res_pjsip_exten_state.c @@ -1015,4 +1015,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Extension State .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND + 5, + .requires = "res_pjsip,res_pjsip_pubsub,res_pjsip_outbound_publish", ); diff --git a/res/res_pjsip_header_funcs.c b/res/res_pjsip_header_funcs.c index 648f1c860..06fba0635 100644 --- a/res/res_pjsip_header_funcs.c +++ b/res/res_pjsip_header_funcs.c @@ -629,4 +629,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Header Function .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip,res_pjsip_session", ); diff --git a/res/res_pjsip_history.c b/res/res_pjsip_history.c index d6b3eebe9..40d26d59d 100644 --- a/res/res_pjsip_history.c +++ b/res/res_pjsip_history.c @@ -1403,4 +1403,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP History", .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_logger.c b/res/res_pjsip_logger.c index d29a6e213..460b6a34f 100644 --- a/res/res_pjsip_logger.c +++ b/res/res_pjsip_logger.c @@ -262,4 +262,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Packet Logger", .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_messaging.c b/res/res_pjsip_messaging.c index b6e7a64c3..3739bcf93 100644 --- a/res/res_pjsip_messaging.c +++ b/res/res_pjsip_messaging.c @@ -19,7 +19,6 @@ /*** MODULEINFO <depend>pjproject</depend> <depend>res_pjsip</depend> - <depend>res_pjsip_session</depend> <support_level>core</support_level> ***/ @@ -850,4 +849,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Messaging Suppo .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c index 5423038e6..92dc7dc65 100644 --- a/res/res_pjsip_mwi.c +++ b/res/res_pjsip_mwi.c @@ -1397,4 +1397,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP MWI resource", .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DEPEND + 5, + .requires = "res_pjsip,res_pjsip_pubsub", ); diff --git a/res/res_pjsip_mwi_body_generator.c b/res/res_pjsip_mwi_body_generator.c index e8279101c..65ac60067 100644 --- a/res/res_pjsip_mwi_body_generator.c +++ b/res/res_pjsip_mwi_body_generator.c @@ -116,4 +116,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP MWI resource", .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, + .requires = "res_pjsip,res_pjsip_pubsub", ); diff --git a/res/res_pjsip_nat.c b/res/res_pjsip_nat.c index e1d56e6af..4231a1ec3 100644 --- a/res/res_pjsip_nat.c +++ b/res/res_pjsip_nat.c @@ -378,4 +378,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP NAT Support", .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_notify.c b/res/res_pjsip_notify.c index 59b7c6ea4..9767c56b5 100644 --- a/res/res_pjsip_notify.c +++ b/res/res_pjsip_notify.c @@ -1032,4 +1032,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "CLI/AMI PJSIP NOTIFY .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_one_touch_record_info.c b/res/res_pjsip_one_touch_record_info.c index ec5f9be3e..ef59fca13 100644 --- a/res/res_pjsip_one_touch_record_info.c +++ b/res/res_pjsip_one_touch_record_info.c @@ -19,7 +19,6 @@ /*** MODULEINFO <depend>pjproject</depend> <depend>res_pjsip</depend> - <depend>res_pjsip_session</depend> <support_level>core</support_level> ***/ @@ -129,4 +128,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP INFO One Touch .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_outbound_authenticator_digest.c b/res/res_pjsip_outbound_authenticator_digest.c index 7e2d71129..54bba08de 100644 --- a/res/res_pjsip_outbound_authenticator_digest.c +++ b/res/res_pjsip_outbound_authenticator_digest.c @@ -224,4 +224,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP authentication .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_outbound_publish.c b/res/res_pjsip_outbound_publish.c index e5f12951f..b4e3320f4 100644 --- a/res/res_pjsip_outbound_publish.c +++ b/res/res_pjsip_outbound_publish.c @@ -1702,4 +1702,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, + .requires = "res_pjproject,res_pjsip", ); diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c index d9afcd284..79bea482b 100644 --- a/res/res_pjsip_outbound_registration.c +++ b/res/res_pjsip_outbound_registration.c @@ -2289,4 +2289,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Outbound Regist .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_path.c b/res/res_pjsip_path.c index e170a750d..b245f159d 100644 --- a/res/res_pjsip_path.c +++ b/res/res_pjsip_path.c @@ -264,4 +264,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Path Header Sup .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_phoneprov_provider.c b/res/res_pjsip_phoneprov_provider.c index 7e082c4b5..11031c3c1 100644 --- a/res/res_pjsip_phoneprov_provider.c +++ b/res/res_pjsip_phoneprov_provider.c @@ -418,4 +418,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Phoneprov Provi .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip,res_phoneprov", ); diff --git a/res/res_pjsip_pidf_body_generator.c b/res/res_pjsip_pidf_body_generator.c index 29c9e6be2..6426dfa9d 100644 --- a/res/res_pjsip_pidf_body_generator.c +++ b/res/res_pjsip_pidf_body_generator.c @@ -135,4 +135,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Extension State .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, + .requires = "res_pjsip,res_pjsip_pubsub", ); diff --git a/res/res_pjsip_pidf_digium_body_supplement.c b/res/res_pjsip_pidf_digium_body_supplement.c index 93e4982e2..f855e2153 100644 --- a/res/res_pjsip_pidf_digium_body_supplement.c +++ b/res/res_pjsip_pidf_digium_body_supplement.c @@ -114,4 +114,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP PIDF Digium pre .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, + .requires = "res_pjsip,res_pjsip_pubsub", ); diff --git a/res/res_pjsip_pidf_eyebeam_body_supplement.c b/res/res_pjsip_pidf_eyebeam_body_supplement.c index 40470840c..6629aa3c1 100644 --- a/res/res_pjsip_pidf_eyebeam_body_supplement.c +++ b/res/res_pjsip_pidf_eyebeam_body_supplement.c @@ -111,4 +111,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP PIDF Eyebeam su .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, + .requires = "res_pjsip,res_pjsip_pubsub", ); diff --git a/res/res_pjsip_publish_asterisk.c b/res/res_pjsip_publish_asterisk.c index 53ee60fe4..13d7fd43b 100644 --- a/res/res_pjsip_publish_asterisk.c +++ b/res/res_pjsip_publish_asterisk.c @@ -934,4 +934,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Asterisk Event .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND + 5, + .requires = "res_pjsip,res_pjsip_outbound_publish,res_pjsip_pubsub", ); diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c index 1f24de050..af696b849 100644 --- a/res/res_pjsip_pubsub.c +++ b/res/res_pjsip_pubsub.c @@ -5518,4 +5518,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_refer.c b/res/res_pjsip_refer.c index 62f8b67de..3100993de 100644 --- a/res/res_pjsip_refer.c +++ b/res/res_pjsip_refer.c @@ -1229,4 +1229,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Blind and Atten .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip,res_pjsip_session,res_pjsip_pubsub", ); diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c index f0da6dee2..7277a5f4f 100644 --- a/res/res_pjsip_registrar.c +++ b/res/res_pjsip_registrar.c @@ -1134,4 +1134,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Registrar Suppo .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 3, + .requires = "res_pjproject,res_pjsip", ); diff --git a/res/res_pjsip_registrar_expire.c b/res/res_pjsip_registrar_expire.c index fe4a60da8..85e3fb859 100644 --- a/res/res_pjsip_registrar_expire.c +++ b/res/res_pjsip_registrar_expire.c @@ -150,4 +150,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Contact Auto-Ex .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_rfc3326.c b/res/res_pjsip_rfc3326.c index d49a170d3..8b8035efc 100644 --- a/res/res_pjsip_rfc3326.c +++ b/res/res_pjsip_rfc3326.c @@ -19,7 +19,6 @@ /*** MODULEINFO <depend>pjproject</depend> <depend>res_pjsip</depend> - <depend>res_pjsip_session</depend> <support_level>core</support_level> ***/ @@ -156,4 +155,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP RFC3326 Support .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index 9e0411903..3cc97644a 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -1970,4 +1970,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP SDP RTP/AVP str .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, + .requires = "res_pjsip,res_pjsip_session", ); diff --git a/res/res_pjsip_send_to_voicemail.c b/res/res_pjsip_send_to_voicemail.c index 1cd28ceac..06c3edc03 100644 --- a/res/res_pjsip_send_to_voicemail.c +++ b/res/res_pjsip_send_to_voicemail.c @@ -236,4 +236,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP REFER Send to V .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip,res_pjsip_session", ); diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 53f60cc3b..8247fbaaa 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -4202,4 +4202,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_sips_contact.c b/res/res_pjsip_sips_contact.c index 7579be6f3..41b26df7d 100644 --- a/res/res_pjsip_sips_contact.c +++ b/res/res_pjsip_sips_contact.c @@ -104,4 +104,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "UAC SIPS Contact supp .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c index 8f1905f6e..7b7cd9910 100644 --- a/res/res_pjsip_t38.c +++ b/res/res_pjsip_t38.c @@ -1053,4 +1053,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP T.38 UDPTL Supp .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, + .requires = "res_pjsip,res_pjsip_session", ); diff --git a/res/res_pjsip_transport_management.c b/res/res_pjsip_transport_management.c index eb92eb7a5..acffb86dc 100644 --- a/res/res_pjsip_transport_management.c +++ b/res/res_pjsip_transport_management.c @@ -397,4 +397,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Reliable Transp .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4, + .requires = "res_pjsip", ); diff --git a/res/res_pjsip_transport_websocket.c b/res/res_pjsip_transport_websocket.c index 3ce90390c..af1345f35 100644 --- a/res/res_pjsip_transport_websocket.c +++ b/res/res_pjsip_transport_websocket.c @@ -518,4 +518,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP WebSocket Trans .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, + .requires = "res_pjsip,res_http_websocket", ); diff --git a/res/res_pjsip_xpidf_body_generator.c b/res/res_pjsip_xpidf_body_generator.c index 41f6224d1..f7c84db3d 100644 --- a/res/res_pjsip_xpidf_body_generator.c +++ b/res/res_pjsip_xpidf_body_generator.c @@ -20,7 +20,6 @@ <depend>pjproject</depend> <depend>res_pjsip</depend> <depend>res_pjsip_pubsub</depend> - <depend>res_pjsip_exten_state</depend> <support_level>core</support_level> ***/ @@ -177,4 +176,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Extension State .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, + .requires = "res_pjsip,res_pjsip_pubsub", ); diff --git a/res/res_stasis_answer.c b/res/res_stasis_answer.c index 407a63135..6ec50c81b 100644 --- a/res/res_stasis_answer.c +++ b/res/res_stasis_answer.c @@ -73,5 +73,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Stasis applicatio .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_stasis" + .requires = "res_stasis", ); diff --git a/res/res_stasis_device_state.c b/res/res_stasis_device_state.c index 6527af4a6..be09b15ad 100644 --- a/res/res_stasis_device_state.c +++ b/res/res_stasis_device_state.c @@ -482,5 +482,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Stasis applicatio .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_stasis" + .requires = "res_stasis", ); diff --git a/res/res_stasis_mailbox.c b/res/res_stasis_mailbox.c index 5ed061de2..3d0e9db69 100644 --- a/res/res_stasis_mailbox.c +++ b/res/res_stasis_mailbox.c @@ -161,5 +161,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Stasis applicatio .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_stasis,res_mwi_external" + .requires = "res_stasis,res_mwi_external" ); diff --git a/res/res_stasis_playback.c b/res/res_stasis_playback.c index ca0446b89..5b8256fc4 100644 --- a/res/res_stasis_playback.c +++ b/res/res_stasis_playback.c @@ -759,5 +759,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Stasis applicatio .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_stasis,res_stasis_recording" + .requires = "res_stasis,res_stasis_recording" ); diff --git a/res/res_stasis_recording.c b/res/res_stasis_recording.c index 56984cb40..17213aa24 100644 --- a/res/res_stasis_recording.c +++ b/res/res_stasis_recording.c @@ -655,6 +655,6 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_stasis", + .requires = "res_stasis", .load_pri = AST_MODPRI_APP_DEPEND ); diff --git a/res/res_stasis_snoop.c b/res/res_stasis_snoop.c index f797a9b94..b234de111 100644 --- a/res/res_stasis_snoop.c +++ b/res/res_stasis_snoop.c @@ -445,5 +445,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Stasis applicatio .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_stasis" + .requires = "res_stasis", ); diff --git a/res/stasis_recording/stored.c b/res/stasis_recording/stored.c index 9df5d75dc..ac216ff8c 100644 --- a/res/stasis_recording/stored.c +++ b/res/stasis_recording/stored.c @@ -330,6 +330,7 @@ struct stasis_app_stored_recording *stasis_app_stored_recording_find_by_name( RAII_VAR(char *, file_with_ext, NULL, ast_free); int res; struct stat file_stat; + int prefix_len = strlen(ast_config_AST_RECORDING_DIR); errno = 0; @@ -350,18 +351,28 @@ struct stasis_app_stored_recording *stasis_app_stored_recording_find_by_name( ast_string_field_build(recording, file, "%s/%s", dir, file); if (!ast_begins_with(dir, ast_config_AST_RECORDING_DIR)) { - /* Attempt to escape the recording directory */ - ast_log(LOG_WARNING, "Attempt to access invalid recording %s\n", - name); - errno = EACCES; - return NULL; + /* It's possible that one or more component of the recording path is + * a symbolic link, this would prevent dir from ever matching. */ + char *real_basedir = realpath(ast_config_AST_RECORDING_DIR, NULL); + + if (!real_basedir || !ast_begins_with(dir, real_basedir)) { + /* Attempt to escape the recording directory */ + ast_log(LOG_WARNING, "Attempt to access invalid recording directory %s\n", + dir); + ast_std_free(real_basedir); + errno = EACCES; + + return NULL; + } + + prefix_len = strlen(real_basedir); + ast_std_free(real_basedir); } /* The actual name of the recording is file with the config dir * prefix removed. */ - ast_string_field_set(recording, name, - recording->file + strlen(ast_config_AST_RECORDING_DIR) + 1); + ast_string_field_set(recording, name, recording->file + prefix_len + 1); file_with_ext = find_recording(dir, file); if (!file_with_ext) { diff --git a/rest-api-templates/res_ari_resource.c.mustache b/rest-api-templates/res_ari_resource.c.mustache index d4ccda9e8..c1f680f21 100644 --- a/rest-api-templates/res_ari_resource.c.mustache +++ b/rest-api-templates/res_ari_resource.c.mustache @@ -324,6 +324,6 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - {{{ .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari,res_stasis", + .requires = "res_ari,res_ari_model,res_stasis", ); {{/api_declaration}} diff --git a/tests/test_ari.c b/tests/test_ari.c index bce5f95d6..a5db2284f 100644 --- a/tests/test_ari.c +++ b/tests/test_ari.c @@ -573,5 +573,5 @@ static int load_module(void) AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ARI testing", .load = load_module, .unload = unload_module, - .nonoptreq = "res_ari", + .requires = "res_ari", ); diff --git a/tests/test_ari_model.c b/tests/test_ari_model.c index caf411878..e5a96cdd1 100644 --- a/tests/test_ari_model.c +++ b/tests/test_ari_model.c @@ -452,4 +452,9 @@ static int load_module(void) return AST_MODULE_LOAD_SUCCESS; } -AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Skeleton (sample) Test"); +AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Skeleton (sample) Test", + .support_level = AST_MODULE_SUPPORT_CORE, + .load = load_module, + .unload = unload_module, + .requires = "res_ari_model", +); diff --git a/tests/test_res_pjsip_scheduler.c b/tests/test_res_pjsip_scheduler.c index da51d43be..47a7034ff 100644 --- a/tests/test_res_pjsip_scheduler.c +++ b/tests/test_res_pjsip_scheduler.c @@ -396,4 +396,9 @@ static int unload_module(void) return 0; } -AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "res_pjsip scheduler test module"); +AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "res_pjsip scheduler test module", + .support_level = AST_MODULE_SUPPORT_CORE, + .load = load_module, + .unload = unload_module, + .requires = "res_pjsip", +); diff --git a/tests/test_res_stasis.c b/tests/test_res_stasis.c index cb79fa6fe..077cc4c7a 100644 --- a/tests/test_res_stasis.c +++ b/tests/test_res_stasis.c @@ -195,5 +195,5 @@ static int load_module(void) AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Stasis Core testing", .load = load_module, .unload = unload_module, - .nonoptreq = "res_stasis", + .requires = "res_stasis", ); diff --git a/tests/test_stasis_endpoints.c b/tests/test_stasis_endpoints.c index 134738fee..42c7532eb 100644 --- a/tests/test_stasis_endpoints.c +++ b/tests/test_stasis_endpoints.c @@ -306,5 +306,5 @@ static int load_module(void) AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Endpoint stasis-related testing", .load = load_module, .unload = unload_module, - .nonoptreq = "res_stasis_test", + .requires = "res_stasis_test", ); diff --git a/third-party/pjproject/patches/0060-sip_msg-Prevent-crash-on-header-without-vptr.patch b/third-party/pjproject/patches/0060-sip_msg-Prevent-crash-on-header-without-vptr.patch new file mode 100644 index 000000000..c96292a95 --- /dev/null +++ b/third-party/pjproject/patches/0060-sip_msg-Prevent-crash-on-header-without-vptr.patch @@ -0,0 +1,47 @@ +From cf6b662b8fe450ea7dc6eb5adb2b878971ce0d67 Mon Sep 17 00:00:00 2001 +From: George Joseph <gjoseph@digium.com> +Date: Wed, 10 Jan 2018 08:48:32 -0700 +Subject: [PATCH] sip_msg: Prevent crash on header without vptr + +Occasionally a header with no vptr gets into the list of header. This +causes a crash when printing them. We still need to figure out how +the header got there but this patch at least prevents the crash by checking +for a non-NULL vptr before attempting to call its print function. +--- + pjsip/src/pjsip/sip_msg.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/pjsip/src/pjsip/sip_msg.c b/pjsip/src/pjsip/sip_msg.c +index 76d07b563..194b5ee01 100644 +--- a/pjsip/src/pjsip/sip_msg.c ++++ b/pjsip/src/pjsip/sip_msg.c +@@ -26,6 +26,7 @@ + #include <pj/string.h> + #include <pj/pool.h> + #include <pj/assert.h> ++#include <pj/log.h> + #include <pjlib-util/string.h> + + PJ_DEF_DATA(const pjsip_method) pjsip_invite_method = +@@ -469,6 +470,8 @@ PJ_DEF(pj_ssize_t) pjsip_msg_print( const pjsip_msg *msg, + + *p++ = '\r'; + *p++ = '\n'; ++ } else { ++ PJ_LOG(1, ("sip_msg", "Header with no vptr encountered!! Current buffer: %.*s", (int)(p-buf), buf)); + } + } + +@@ -576,6 +579,9 @@ PJ_DEF(void*) pjsip_hdr_shallow_clone( pj_pool_t *pool, const void *hdr_ptr ) + PJ_DEF(int) pjsip_hdr_print_on( void *hdr_ptr, char *buf, pj_size_t len) + { + pjsip_hdr *hdr = (pjsip_hdr*) hdr_ptr; ++ if (!hdr->vptr) { ++ return 0; ++ } + return (*hdr->vptr->print_on)(hdr_ptr, buf, len); + } + +-- +2.14.3 + |