asterisk-16.x: add Asterisk 16

Initial commit of Asterisk 16. Cleans up Makefile; the version number
now only occurs once in it.

Upstream removed the following modules:

  - format_jpeg
  - res_pjsip_registrar_expire (functionality was moved into
    res_pjsip_registrar.)

pjsip has a new dependency, res-http-websocket.

Notes:

  - replaced res_ninit patch

    Replaced patch with the one from Alpine. It's a bit more flexible and
    allows usage of res_ninit where available (when building against
    glibc).

  - fixed musl compiles

    astmm.h now always gets included by asterisk.h, redefining allocators.
    This causes breakage on musl:

    ccache_cc -o chan_pjsip.o -c chan_pjsip.c -MD -MT chan_pjsip.o -MF .chan_pjsip.o.d -MP -pthread -I/home/sk/tmp/openwrt/build_dir/target-mips_24kc_musl/asterisk-16.2.1/include -Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -mips16 -minterlink-mips16 -iremap/home/sk/tmp/openwrt/build_dir/target-mips_24kc_musl/asterisk-16.2.1:asterisk-16.2.1 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -I/home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/usr/lib/libiconv-stub/include -I/home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/usr/lib/libintl-stub/include -I/home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/usr/include -I/home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/include -I/home/sk/tmp/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/usr/include -I/home/sk/tmp/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/include/fortify -I/home/sk/tmp/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/include -I/home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/usr/lib/libiconv-stub/include -I/home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/usr/lib/libintl-stub/include    -I/home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/usr/include/libxml2  -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations       -fPIC -DAST_MODULE=\"chan_pjsip\" -DAST_MODULE_SELF_SYM=__internal_chan_pjsip_self  -DPJ_AUTOCONF=1 -DPJ_IS_BIG_ENDIAN=1 -DPJ_IS_LITTLE_ENDIAN=0 -fPIC -I/home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/usr/include
    In file included from /home/sk/tmp/openwrt/build_dir/target-mips_24kc_musl/asterisk-16.2.1/include/asterisk.h:23:0,
                     from chan_pjsip.c:35:
    /home/sk/tmp/openwrt/build_dir/target-mips_24kc_musl/asterisk-16.2.1/include/asterisk/astmm.h:158:35: error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
      Do_not_use_calloc__use_ast_calloc->fail(a, b)
                                       ^
    /home/sk/tmp/openwrt/build_dir/target-mips_24kc_musl/asterisk-16.2.1/include/asterisk/astmm.h:162:77: error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
      Do_not_use_free__use_ast_free_or_ast_std_free_for_remotely_allocated_memory->fail(a)
                                                                                 ^
    make[4]: *** [/home/sk/tmp/openwrt/build_dir/target-mips_24kc_musl/asterisk-16.2.1/Makefile.rules:153: chan_pjsip.o] Error 1

    The problem is that with _GNU_SOURCE defined musl also declares calloc in
    <sched.h> - and when asterisk's source includes <sched.h> _after_
    "asterisk/astmm.h" the definition clashes with the macro. Timo Teräs from
    Alpine Linux fixed this by including <pthread.h> in "asterisk/compat.h". He
    chose to include <pthread.h> instead of <sched.h> because the original
    header inclusion chain seems to be "asterisk/astobj2.h" ->
    "asterisk/lock.h" -> <pthread.h> -> <sched.h>. It seems Asterisk
    practically never includes <sched.h> directly.

  - added loader workaround for musl

    When the modules are loaded, asterisk segfaults on musl.

       Asterisk Dynamic Loader Starting:
      [Mar  2 22:30:05] NOTICE[20712]: loader.c:2230 load_modules: 91 modules will be loaded.
      Segmentation fault

      [48817.544248] do_page_fault(): sending SIGSEGV to asterisk for invalid read access from 00000000
      [48817.544258] epc = 77f6b764 in libc.so[77ef8000+94000]
      [48817.544285] ra  = 0048d579 in asterisk[400000+160000]

    The real problem is that the loader expects dlopen to always run the
    constructor, which doesn't happen with musl, because its dlopen is
    permanent.

    This commit adds a new configure switch '--enable-permanent-dlopen'.
    When enabled, the loader will manually call 'ast_module_register(...)'
    and 'ast_module_unregister(...)' when needed.

  - allow eventfd detection

    Asterisk 16 wants to use eventfd, but it doesn't allow the detection
    during cross-compiling. This results in runtime warnings, for instance
    when shutting down:

      [Mar  2 22:37:41] WARNING[21593]: alertpipe.c:112 ast_alertpipe_read: read() failed: Bad file descriptor
      [Mar  2 22:37:41] WARNING[21593]: alertpipe.c:112 ast_alertpipe_read: read() failed: Bad file descriptor
      [Mar  2 22:37:41] WARNING[21593]: alertpipe.c:112 ast_alertpipe_read: read() failed: Bad file descriptor

    Relax the configure script so that eventfd can also be detected when
    cross-compiling.

Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
This commit is contained in:
Sebastian Kemper 2019-04-27 16:04:34 +02:00
parent 9a8f3b3726
commit 6cdf80bd46
12 changed files with 1468 additions and 0 deletions

1037
net/asterisk-16.x/Makefile Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,4 @@
## startup options for /etc/init.d/asterisk
ENABLE_ASTERISK="yes"
OPTIONS=""

View file

@ -0,0 +1,33 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2014 OpenWrt.org
START=99
APP=asterisk
OPTIONS=
DEST=
DEFAULT=$DEST/etc/default/$APP
BIN_FILE=$DEST/usr/sbin/$APP
PID_FILE=$DEST/var/run/$APP/$APP.pid
start() {
[ -f $DEFAULT ] && . $DEFAULT
[ -d $DEST/var/run/asterisk ] || mkdir -p $DEST/var/run/asterisk
[ -d $DEST/var/log/asterisk ] || mkdir -p $DEST/var/log/asterisk
[ -d $DEST/var/spool/asterisk ] || mkdir -p $DEST/var/spool/asterisk
[ -d $DEST/var/lib/asterisk ] || mkdir -p $DEST/var/lib/asterisk
[ -d $DEST/var/lib/asterisk/keys ] || mkdir -p $DEST/var/lib/asterisk/keys
[ -d $DEST/var/log/asterisk/cdr-csv ] || mkdir -p $DEST/var/log/asterisk/cdr-csv
SERVICE_PID_FILE="/var/run/asterisk/asterisk.pid" \
service_start $BIN_FILE $OPTIONS
}
stop() {
SERVICE_PID_FILE="/var/run/asterisk/asterisk.pid" \
service_stop $BIN_FILE
}
reload() {
SERVICE_PID_FILE="/var/run/asterisk/asterisk.pid" \
service_reload $BIN_FILE
}

View file

@ -0,0 +1,22 @@
--- a/configure.ac
+++ b/configure.ac
@@ -1016,19 +1016,6 @@ AC_LINK_IFELSE(
]
)
-# Some platforms define sem_init(), but only support sem_open(). joyous.
-AC_MSG_CHECKING(for working unnamed semaphores)
-AC_RUN_IFELSE(
- [AC_LANG_PROGRAM([#include <semaphore.h>],
- [sem_t sem; return sem_init(&sem, 0, 0);])],
- AC_MSG_RESULT(yes)
- AC_DEFINE([HAS_WORKING_SEMAPHORE], 1, [Define to 1 if anonymous semaphores work.]),
- AC_MSG_RESULT(no),
- AC_MSG_RESULT(cross-compile)
- AC_MSG_NOTICE([WARNING: result yes guessed because of cross compilation])
- AC_DEFINE([HAS_WORKING_SEMAPHORE], 1, [Define to 1 if anonymous semaphores work.])
-)
-
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
if test "${ac_cv_pthread_rwlock_timedwrlock}" = "yes"; then

View file

@ -0,0 +1,33 @@
From 9b4070944578336506cd0a76de6f733c72d0ca74 Mon Sep 17 00:00:00 2001
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Date: Sat, 13 Oct 2018 11:11:15 +0200
Subject: [PATCH] configure: fix detection of re-entrant resolver functions
Fixes https://issues.asterisk.org/jira/browse/ASTERISK-21795
uClibc does not provide res_nsearch:
asterisk-16.0.0/main/dns.c:506: undefined reference to `res_nsearch'
Patch coded by Yann E. MORIN:
http://lists.busybox.net/pipermail/buildroot/2018-October/232630.html
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
---
configure.ac | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/configure.ac
+++ b/configure.ac
@@ -1396,7 +1396,11 @@ AC_LINK_IFELSE(
#include <arpa/nameser.h>
#endif
#include <resolv.h>],
- [int foo = res_ninit(NULL);])],
+ [
+ int foo;
+ foo = res_ninit(NULL);
+ foo = res_nsearch(NULL, NULL, 0, 0, NULL, 0);
+ ])],
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_RES_NINIT], 1, [Define to 1 if your system has the re-entrant resolver functions.])
AC_SEARCH_LIBS(res_9_ndestroy, resolv)

View file

@ -0,0 +1,22 @@
--- a/res/ael/ael.flex
+++ b/res/ael/ael.flex
@@ -601,7 +601,7 @@ includes { STORE_POS; return KW_INCLUDES
snprintf(fnamebuf2,sizeof(fnamebuf2), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, fnamebuf);
ast_copy_string(fnamebuf,fnamebuf2,sizeof(fnamebuf));
}
-#ifdef SOLARIS
+#if !defined(HAVE_GLOB_NOMAGIC) || !defined(HAVE_GLOB_BRACE) || defined(DEBUG_NONGNU)
glob_ret = glob(fnamebuf, GLOB_NOCHECK, NULL, &globbuf);
#else
glob_ret = glob(fnamebuf, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);
--- a/res/ael/ael_lex.c
+++ b/res/ael/ael_lex.c
@@ -1982,7 +1982,7 @@ YY_RULE_SETUP
snprintf(fnamebuf2,sizeof(fnamebuf2), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, fnamebuf);
ast_copy_string(fnamebuf,fnamebuf2,sizeof(fnamebuf));
}
-#ifdef SOLARIS
+#if !defined(HAVE_GLOB_NOMAGIC) || !defined(HAVE_GLOB_BRACE) || defined(DEBUG_NONGNU)
glob_ret = glob(fnamebuf, GLOB_NOCHECK, NULL, &globbuf);
#else
glob_ret = glob(fnamebuf, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);

View file

@ -0,0 +1,11 @@
--- a/include/asterisk/lock.h
+++ b/include/asterisk/lock.h
@@ -66,7 +66,7 @@
#define AST_PTHREADT_NULL (pthread_t) -1
#define AST_PTHREADT_STOP (pthread_t) -2
-#if (defined(SOLARIS) || defined(BSD))
+#if (defined(SOLARIS) || defined(BSD) || !defined(HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP))
#define AST_MUTEX_INIT_W_CONSTRUCTORS
#endif /* SOLARIS || BSD */

View file

@ -0,0 +1,10 @@
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -187,7 +187,6 @@ check_expr2: $(ASTTOPDIR)/main/ast_expr2
$(CC) -g -o check_expr2 ast_expr2fz.o ast_expr2z.o astmm.o -lm $(_ASTLDFLAGS)
$(ECHO_PREFIX) echo " [RM] ast_expr2fz.o ast_expr2z.o"
rm ast_expr2z.o ast_expr2fz.o
- ./check_expr2 expr2.testinput
smsq: smsq.o strcompat.o
smsq: LIBS+=$(POPT_LIB)

View file

@ -0,0 +1,28 @@
--- a/build_tools/make_build_h
+++ b/build_tools/make_build_h
@@ -5,6 +5,14 @@ MACHINE=`uname -m | sed 's/\\\\/\\\\\\\
OS=`uname -s`
USER=`id | awk -F")" '{print $1}'| awk -F"(" '{print $2}' | sed 's/\\\\/\\\\\\\\/g'`
DATE=`date -u "+%Y-%m-%d %H:%M:%S"`
+if [ -n "${SOURCE_DATE_EPOCH}" ]; then
+ # building reproducibly, faking some data
+ HOSTNAME='openwrt.org'
+ KERNEL='unknown'
+ MACHINE='unknown'
+ USER='nobody'
+ DATE=`date -u "+%Y-%m-%d %H:%M:%S" -d @${SOURCE_DATE_EPOCH}`
+fi
cat << END
/*
* build.h
--- a/Makefile
+++ b/Makefile
@@ -484,7 +484,7 @@ doc/core-en_US.xml: makeopts .lastclean
@echo "<docs xmlns:xi=\"http://www.w3.org/2001/XInclude\">" >> $@
@for x in $(MOD_SUBDIRS); do \
printf "$$x " ; \
- for i in `find $$x -name '*.c'`; do \
+ for i in `find $$x -name '*.c' | LC_ALL=C sort`; do \
$(AWK) -f build_tools/get_documentation $$i >> $@ ; \
done ; \
done

View file

@ -0,0 +1,10 @@
--- a/include/asterisk/compat.h
+++ b/include/asterisk/compat.h
@@ -30,6 +30,7 @@
#include <inttypes.h>
#include <limits.h>
#include <unistd.h>
+#include <pthread.h>
#ifdef HAVE_STDDEF_H
#include <stddef.h>

View file

@ -0,0 +1,247 @@
commit 02fda2b478f98cf3b8a1df76f772bf0be73bddd5
Author: Sebastian Kemper <sebastian_ml@gmx.net>
Date: Tue Apr 2 22:49:52 2019 +0200
loader: support for permanent dlopen()
Asterisk assumes that dlopen() will always run the constructor of a
shared library and every dlclose() will run its destructor. But dlopen()
may be permanent, meaning the constructor will only be run once, as is
the case with musl libc.
With a permanent dlopen() the Asterisk module loader does not work
correctly, because it's expectations regarding when the constructors and
destructors are run are not met. In fact a segmentation fault will occur
when the first module is "re-opened" that has AST_MODFLAG_GLOBAL_SYMBOLS
set (the dlopen() does not call the constructor, resource_being_loaded
is not set to NULL, then strlen is called with NULL instead of a string,
see issue ASTERISK-28319).
This commit adds code to the loader that will manually run the
constructors/destructors of the (non-builtin) modules where needed. To
achieve this a new ao2 container (linked list) is started and filled
with objects that contain the names of the modules and the pointers to
their respective info structs.
This behavior can be activated when configuring Asterisk
(--enable-permanent-dlopen). By default this is disabled, of course.
ASTERISK-28319 #close
Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
Change-Id: I86693a0ecf25d5ba81c73773a03df4abc3426875
--- a/configure.ac
+++ b/configure.ac
@@ -727,6 +727,20 @@ if test "${DISABLE_XMLDOC}" != "yes"; th
fi
+AC_ARG_ENABLE([permanent-dlopen],
+ [AS_HELP_STRING([--enable-permanent-dlopen],
+ [Enable when your libc has a permanent dlopen like musl])],
+ [case "${enableval}" in
+ y|ye|yes) PERMANENT_DLOPEN=yes ;;
+ n|no) PERMANENT_DLOPEN=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-permanent-dlopen) ;;
+ esac], [PERMANENT_DLOPEN=no])
+
+AC_SUBST([PERMANENT_DLOPEN])
+if test "${PERMANENT_DLOPEN}" == "yes"; then
+ AC_DEFINE([HAVE_PERMANENT_DLOPEN], 1, [Define to support libc with permanent dlopen.])
+fi
+
# some embedded systems omit internationalization (locale) support
AC_CHECK_HEADERS([xlocale.h])
--- a/main/loader.c
+++ b/main/loader.c
@@ -153,6 +153,117 @@ static unsigned int loader_ready;
static struct ast_vector_string startup_errors;
static struct ast_str *startup_error_builder;
+#if defined(HAVE_PERMANENT_DLOPEN)
+#define FIRST_DLOPEN 999
+
+struct ao2_container *info_list = NULL;
+
+struct info_list_obj {
+ const struct ast_module_info *info;
+ int dlopened;
+ char name[0];
+};
+
+static struct info_list_obj *info_list_obj_alloc(const char *name,
+ const struct ast_module_info *info)
+{
+ struct info_list_obj *new_entry;
+
+ new_entry = ao2_alloc(sizeof(*new_entry) + strlen(name) + 1, NULL);
+
+ if (!new_entry) {
+ return NULL;
+ }
+
+ strcpy(new_entry->name, name); /* SAFE */
+ new_entry->info = info;
+ new_entry->dlopened = FIRST_DLOPEN;
+
+ return new_entry;
+}
+
+AO2_STRING_FIELD_CMP_FN(info_list_obj, name)
+
+static char *get_name_from_resource(const char *resource)
+{
+ int len;
+ const char *last_three;
+ char *mod_name;
+
+ if (!resource) {
+ return NULL;
+ }
+
+ len = strlen(resource);
+ if (len > 3) {
+ last_three = &resource[len-3];
+ if (!strcasecmp(last_three, ".so")) {
+ mod_name = ast_calloc(1, len - 2);
+ if (mod_name) {
+ ast_copy_string(mod_name, resource, len - 2);
+ return mod_name;
+ } else {
+ /* Unable to allocate memory. */
+ return NULL;
+ }
+ }
+ }
+
+ /* Resource is the name - happens when manually unloading a module. */
+ mod_name = ast_calloc(1, len + 1);
+ if (mod_name) {
+ ast_copy_string(mod_name, resource, len + 1);
+ return mod_name;
+ }
+
+ /* Unable to allocate memory. */
+ return NULL;
+}
+
+static void manual_mod_reg(const void *lib, const char *resource)
+{
+ struct info_list_obj *obj_tmp;
+ char *mod_name;
+
+ if (lib) {
+ mod_name = get_name_from_resource(resource);
+ if (mod_name) {
+ obj_tmp = ao2_find(info_list, mod_name, OBJ_SEARCH_KEY);
+ if (obj_tmp) {
+ if (obj_tmp->dlopened == FIRST_DLOPEN) {
+ obj_tmp->dlopened = 1;
+ } else {
+ ast_module_register(obj_tmp->info);
+ }
+ ao2_ref(obj_tmp, -1);
+ }
+ ast_free(mod_name);
+ }
+ }
+}
+
+static void manual_mod_unreg(const char *resource)
+{
+ struct info_list_obj *obj_tmp;
+ char *mod_name;
+
+ /* When Asterisk shuts down the destructor is called automatically. */
+ if (ast_shutdown_final()) {
+ return;
+ }
+
+ mod_name = get_name_from_resource(resource);
+ if (mod_name) {
+ obj_tmp = ao2_find(info_list, mod_name, OBJ_SEARCH_KEY);
+ if (obj_tmp) {
+ ast_module_unregister(obj_tmp->info);
+ ao2_ref(obj_tmp, -1);
+ }
+ ast_free(mod_name);
+ }
+}
+#endif
+
static __attribute__((format(printf, 1, 2))) void module_load_error(const char *fmt, ...)
{
char *copy = NULL;
@@ -597,6 +708,23 @@ void ast_module_register(const struct as
/* give the module a copy of its own handle, for later use in registrations and the like */
*((struct ast_module **) &(info->self)) = mod;
+
+#if defined(HAVE_PERMANENT_DLOPEN)
+ if (mod->flags.builtin != 1) {
+ struct info_list_obj *obj_tmp = ao2_find(info_list, info->name,
+ OBJ_SEARCH_KEY);
+
+ if (!obj_tmp) {
+ obj_tmp = info_list_obj_alloc(info->name, info);
+ if (obj_tmp) {
+ ao2_link(info_list, obj_tmp);
+ ao2_ref(obj_tmp, -1);
+ }
+ } else {
+ ao2_ref(obj_tmp, -1);
+ }
+ }
+#endif
}
static int module_post_register(struct ast_module *mod)
@@ -843,6 +971,10 @@ static void logged_dlclose(const char *n
error = dlerror();
ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
S_OR(name, "unknown"), S_OR(error, "Unknown error"));
+#if defined(HAVE_PERMANENT_DLOPEN)
+ } else {
+ manual_mod_unreg(name);
+#endif
}
}
@@ -949,6 +1081,9 @@ static struct ast_module *load_dlopen(co
resource_being_loaded = mod;
mod->lib = dlopen(filename, flags);
+#if defined(HAVE_PERMANENT_DLOPEN)
+ manual_mod_reg(mod->lib, mod->resource);
+#endif
if (resource_being_loaded) {
struct ast_str *list;
int c = 0;
@@ -968,6 +1103,9 @@ static struct ast_module *load_dlopen(co
resource_being_loaded = mod;
mod->lib = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+#if defined(HAVE_PERMANENT_DLOPEN)
+ manual_mod_reg(mod->lib, mod->resource);
+#endif
if (resource_being_loaded) {
resource_being_loaded = NULL;
@@ -2206,6 +2344,15 @@ int load_modules(void)
ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
+#if defined(HAVE_PERMANENT_DLOPEN)
+ info_list = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL,
+ info_list_obj_cmp_fn); /* must not be cleaned at shutdown */
+ if (!info_list) {
+ fprintf(stderr, "Module info list allocation failure.\n");
+ return 1;
+ }
+#endif
+
AST_LIST_HEAD_INIT_NOLOCK(&load_order);
AST_DLLIST_LOCK(&module_list);

View file

@ -0,0 +1,11 @@
--- a/configure.ac
+++ b/configure.ac
@@ -1189,7 +1189,7 @@ if test "${ac_cv_have_variable_fdset}x"
fi
AC_MSG_CHECKING([if we have usable eventfd support])
-AC_RUN_IFELSE(
+AC_LINK_IFELSE(
[AC_LANG_PROGRAM([#include <sys/eventfd.h>],
[return eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE) == -1;])],
AC_MSG_RESULT(yes)