rtpengine: new package 526/head
authorSebastian Kemper <sebastian_ml@gmx.net>
Mon, 4 May 2020 18:00:59 +0000 (20:00 +0200)
committerSebastian Kemper <sebastian_ml@gmx.net>
Mon, 4 May 2020 18:01:01 +0000 (20:01 +0200)
rtpengine is a proxy for RTP traffic. It has lots of capabilities,
including transcoding, in-kernel forwarding and SRTP transport, to name
a few.

Packaging:

  1. regular rtpengine
  2. rtpengine variant without transcoding support (smaller dependency
     tree)
  3. recording daemon
  4. kernel module
  5. iptables module

Simple init scripts (procd) are included, plus a hotplug script for
rtpengine.

Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
net/rtpengine/Makefile [new file with mode: 0644]
net/rtpengine/files/rtpengine-recording.conf [new file with mode: 0644]
net/rtpengine/files/rtpengine-recording.init [new file with mode: 0644]
net/rtpengine/files/rtpengine.conf [new file with mode: 0644]
net/rtpengine/files/rtpengine.hotplug [new file with mode: 0644]
net/rtpengine/files/rtpengine.init [new file with mode: 0644]
net/rtpengine/patches/01-cflags.patch [new file with mode: 0644]
net/rtpengine/patches/02-kernel-include.patch [new file with mode: 0644]
net/rtpengine/patches/03-uclibc-getloadavg.patch [new file with mode: 0644]

diff --git a/net/rtpengine/Makefile b/net/rtpengine/Makefile
new file mode 100644 (file)
index 0000000..01b36bc
--- /dev/null
@@ -0,0 +1,250 @@
+#
+# Copyright (C) 2020 Sebastian Kemper <sebastian_ml@gmx.net>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=rtpengine
+PKG_VERSION:=mr8.3.1.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/sipwise/rtpengine/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=18c998b776b36bec6d8c9d92ba21a38ffad76ccd20d66f99799420550eaa6fd4
+
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_MAINTAINER:=Sebastian Kemper <sebastian_ml@gmx.net>
+
+PKG_BUILD_PARALLEL:=1
+
+PKG_BUILD_DEPENDS:=gperf/host
+
+include $(INCLUDE_DIR)/package.mk
+
+ENGINE_DEPENDS := \
+       +glib2 \
+       +json-glib \
+       +libevent2 \
+       +libevent2-pthreads \
+       +libhiredis \
+       +libip4tc \
+       +libopenssl \
+       +libpcap \
+       +libpcre \
+       +xmlrpc-c-client \
+       +zlib
+
+ENGINE_DEPENDS_TRANSCODING := \
+       $(ENGINE_DEPENDS) \
+       +bcg729 \
+       +libffmpeg-full \
+       +libmariadb \
+       +libspandsp
+
+RECORDING_DEPENDS := \
+       +glib2 \
+       +libffmpeg-full \
+       +libmariadb \
+       +libopenssl
+
+RTPENGINE_USERID:=$(PKG_NAME)=378:$(PKG_NAME)=378
+
+define Package/rtpengine/Default
+  URL:=https://github.com/sipwise/rtpengine
+endef
+
+define Package/rtpengine/Template
+$(call Package/rtpengine/Default)
+  TITLE:=Sipwise RTP Engine
+  CATEGORY:=Network
+  SECTION:=net
+  SUBMENU:=Telephony
+  USERID:=$(RTPENGINE_USERID)
+endef
+
+define Package/rtpengine/description/Template
+The Sipwise NGCP rtpengine is a proxy for RTP traffic and other UDP
+based media traffic. It's meant to be used with the Kamailio SIP proxy
+and forms a drop-in replacement for any of the other available RTP and
+media proxies.
+endef
+
+define Package/rtpengine
+$(call Package/rtpengine/Template)
+  VARIANT:=transcode
+  DEPENDS := \
+         $(patsubst +%,+PACKAGE_rtpengine:%,$(ENGINE_DEPENDS_TRANSCODING)) \
+         +IPV6:libip6tc
+endef
+
+define Package/rtpengine/conffiles
+/etc/config/rtpengine
+/etc/init.d/rtpengine
+/etc/rtpengine/rtpengine.conf
+endef
+
+define Package/rtpengine/description
+$(call Package/rtpengine/description/Template)
+
+Please consider installing kmod-ipt-rtpengine.
+
+endef
+
+define Package/rtpengine/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/daemon/rtpengine $(1)/usr/bin
+
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/rtpengine.init $(1)/etc/init.d/rtpengine
+
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/rtpengine.conf $(1)/etc/config/rtpengine
+
+       $(INSTALL_DIR) $(1)/etc/rtpengine
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/etc/rtpengine.sample.conf \
+                               $(1)/etc/rtpengine/rtpengine.conf
+
+       $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
+       $(INSTALL_BIN) ./files/rtpengine.hotplug \
+               $(1)/etc/hotplug.d/iface/90-rtpengine
+endef
+
+define Package/rtpengine-no-transcode
+$(call Package/rtpengine/Template)
+  TITLE+= (no transcoding)
+  VARIANT:=no-transcode
+  CONFLICTS:=rtpengine
+  DEPENDS := \
+         $(patsubst +%,+PACKAGE_rtpengine-no-transcode:%,$(ENGINE_DEPENDS)) \
+         +IPV6:libip6tc
+endef
+
+Package/rtpengine-no-transcode/conffiles=$(Package/rtpengine/conffiles)
+
+define Package/rtpengine-no-transcode/description
+$(call Package/rtpengine/description/Template)
+
+This package comes without transcoding support.
+
+Please consider installing kmod-ipt-rtpengine.
+
+endef
+
+Package/rtpengine-no-transcode/install=$(Package/rtpengine/install)
+
+define Package/rtpengine-recording
+$(call Package/rtpengine/Default)
+  TITLE:=Sipwise RTP Recording Daemon
+  CATEGORY:=Network
+  SECTION:=net
+  SUBMENU:=Telephony
+  USERID:=$(RTPENGINE_USERID)
+  DEPENDS:=$(patsubst +%,+PACKAGE_rtpengine-recording:%,$(RECORDING_DEPENDS))
+endef
+
+define Package/rtpengine-recording/conffiles
+/etc/config/rtpengine-recording
+/etc/rtpengine/rtpengine-recording.conf
+endef
+
+define Package/rtpengine-recording/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) \
+               $(PKG_BUILD_DIR)/recording-daemon/rtpengine-recording \
+                                                       $(1)/usr/bin
+
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/rtpengine-recording.init \
+               $(1)/etc/init.d/rtpengine-recording
+
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/rtpengine-recording.conf \
+               $(1)/etc/config/rtpengine-recording
+
+       $(INSTALL_DIR) $(1)/etc/rtpengine
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/etc/rtpengine-recording.sample.conf \
+                               $(1)/etc/rtpengine/rtpengine-recording.conf
+endef
+
+define Package/iptables-mod-rtpengine
+$(call Package/rtpengine/Default)
+  TITLE:=Sipwise rtpengine iptables extension
+  CATEGORY:=Network
+  SECTION:=net
+  SUBMENU:=Firewall
+  DEPENDS:=+PACKAGE_iptables-mod-rtpengine:libxtables
+endef
+
+define Package/iptables-mod-rtpengine/install
+       $(INSTALL_DIR) $(1)/usr/lib/iptables
+       $(INSTALL_BIN) \
+               $(PKG_BUILD_DIR)/iptables-extension/libxt_RTPENGINE.so \
+                                               $(1)/usr/lib/iptables
+endef
+
+define KernelPackage/ipt-rtpengine
+$(call Package/rtpengine/Default)
+  TITLE:=Sipwise rtpengine netfilter module
+  SUBMENU:=Netfilter Extensions
+  FILES:=$(PKG_BUILD_DIR)/kernel-module/xt_RTPENGINE.$(LINUX_KMOD_SUFFIX)
+  AUTOLOAD:=$(call AutoProbe,xt_RTPENGINE)
+  DEPENDS := \
+         +PACKAGE_kmod-ipt-rtpengine:kmod-crypto-hash \
+         +PACKAGE_kmod-ipt-rtpengine:kmod-ipt-core
+  MODPARAMS.xt_RTPENGINE := \
+         proc_uid=$(PKG_NAME) \
+         proc_gid=$(PKG_NAME)
+endef
+
+define KernelPackage/ipt-rtpengine/description
+Netfilter kernel module for rtpengine
+
+endef
+
+MAKE_VARS+=RTPENGINE_VERSION=$(PKG_VERSION)
+
+ifeq ($(BUILD_VARIANT),no-transcode)
+  MAKE_VARS+=with_transcoding=no
+endif
+
+define Build/Configure
+endef
+
+define Build/Compile
+
+ifneq ($(CONFIG_PACKAGE_kmod-ipt-rtpengine),)
+       RTPENGINE_VERSION=$(PKG_VERSION) $(MAKE) \
+               -C $(PKG_BUILD_DIR)/kernel-module \
+               KSRC=$(LINUX_DIR) \
+               ARCH=$(LINUX_KARCH) \
+               CROSS_COMPILE=$(TARGET_CROSS)
+endif
+
+ifneq ($(CONFIG_PACKAGE_iptables-mod-rtpengine),)
+       $(call Build/Compile/Default,-C $(PKG_BUILD_DIR)/iptables-extension)
+endif
+
+ifneq ($(CONFIG_PACKAGE_rtpengine)$(CONFIG_PACKAGE_rtpengine-no-transcode),)
+       $(call Build/Compile/Default,-C $(PKG_BUILD_DIR)/daemon)
+endif
+
+ifneq ($(CONFIG_PACKAGE_rtpengine-recording),)
+       $(call Build/Compile/Default,-C $(PKG_BUILD_DIR)/recording-daemon)
+endif
+
+endef
+
+define Build/InstallDev
+endef
+
+$(eval $(call BuildPackage,rtpengine-no-transcode))
+$(eval $(call KernelPackage,ipt-rtpengine))
+$(eval $(call BuildPackage,iptables-mod-rtpengine))
+$(eval $(call BuildPackage,rtpengine))
+$(eval $(call BuildPackage,rtpengine-recording))
diff --git a/net/rtpengine/files/rtpengine-recording.conf b/net/rtpengine/files/rtpengine-recording.conf
new file mode 100644 (file)
index 0000000..d0a8218
--- /dev/null
@@ -0,0 +1,10 @@
+config rtpengine-recording global
+       option enabled 0                        # 0 - disabled, 1 - enabled
+
+# You can start multiple instances. You must specify a section name from
+# "/etc/rtpengine/rtpengine-recording.conf".
+
+config instance 'instance1'
+       option section 'rtpengine-recording'
+       option opts '--log-level=6'             # Options passed to rtpengine-recording
+                                               # instance.
diff --git a/net/rtpengine/files/rtpengine-recording.init b/net/rtpengine/files/rtpengine-recording.init
new file mode 100644 (file)
index 0000000..cd5badc
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/sh /etc/rc.common
+
+START=91
+
+NAME=rtpengine-recording
+COMMAND="/usr/bin/$NAME"
+
+USE_PROCD=1
+
+#PROCD_DEBUG=1
+
+LOGGER="/usr/bin/logger -t $NAME"
+LOG_ERR="$LOGGER -p user.err -s"
+
+run_instance() {
+       procd_open_instance
+       procd_set_param command $COMMAND
+       procd_append_param command \
+               --config-file=/etc/rtpengine/$NAME.conf \
+               --config-section="$2" \
+               $3 \
+               -f
+       # forward all output to logd
+       procd_set_param stderr 1
+       procd_set_param stdout 1
+       procd_set_param pidfile "/var/run/$NAME-$1.pid"
+       procd_set_param user rtpengine
+       procd_close_instance
+
+       $LOGGER instance "$1" has started
+}
+
+handle_instance() {
+       config_get opts "$1" opts
+       config_get section "$1" section
+
+       run_instance "$1" "$section" "$opts"
+}
+
+start_service() {
+       config_load $NAME
+
+       config_get_bool enabled global enabled 0
+
+       if [ "$enabled" -eq 1 ]; then
+               config_foreach handle_instance instance
+       else
+               $LOG_ERR service not enabled
+               $LOG_ERR edit /etc/config/$NAME
+       fi
+}
diff --git a/net/rtpengine/files/rtpengine.conf b/net/rtpengine/files/rtpengine.conf
new file mode 100644 (file)
index 0000000..93d9e20
--- /dev/null
@@ -0,0 +1,17 @@
+config rtpengine global
+       option enabled 0                        # 0 - disabled, 1 - enabled
+
+# You can start multiple instances. You must specify a section name from
+# "/etc/rtpengine/rtpengine.conf".
+
+config instance 'instance1'
+       option section 'rtpengine'
+       option opts '--log-level=6'             # Options passed to rtpengine
+                                               # instance.
+
+#config instance 'instance2'
+       #option section 'rtpengine-testing'
+       #option opts ''
+
+config rtpengine 'hotplug'
+       #option interface 'wan'                 # uncomment to enable hotplug
diff --git a/net/rtpengine/files/rtpengine.hotplug b/net/rtpengine/files/rtpengine.hotplug
new file mode 100644 (file)
index 0000000..3fa3f09
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+[ "$ACTION" = ifup ] || exit 0
+
+NAME=rtpengine
+COMMAND=/etc/init.d/$NAME
+LOGGER="/usr/bin/logger -t hotplug"
+
+$COMMAND enabled || exit 0
+
+. /lib/functions.sh
+
+config_load $NAME
+
+config_get_bool enabled global enabled 0
+[ $enabled -eq 0 ] && exit 0
+
+config_get hotplug_iface hotplug interface
+
+[ "$INTERFACE" = "$hotplug_iface" ] && {
+       $LOGGER "Restarting $NAME due to \"$ACTION\" of \"$INTERFACE\""
+       $COMMAND restart
+}
diff --git a/net/rtpengine/files/rtpengine.init b/net/rtpengine/files/rtpengine.init
new file mode 100644 (file)
index 0000000..d56912a
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/sh /etc/rc.common
+
+START=90
+
+NAME=rtpengine
+COMMAND="/usr/bin/$NAME"
+
+USE_PROCD=1
+
+#PROCD_DEBUG=1
+
+LOGGER="/usr/bin/logger -t $NAME"
+LOG_ERR="$LOGGER -p user.err -s"
+
+run_instance() {
+       procd_open_instance
+       procd_set_param command $COMMAND
+       procd_append_param command \
+               --config-file=/etc/$NAME/$NAME.conf \
+               --config-section="$2" \
+               $3 \
+               -f
+       # forward all output to logd
+       procd_set_param stderr 1
+       procd_set_param stdout 1
+       procd_set_param pidfile "/var/run/$NAME-$1.pid"
+       procd_set_param user $NAME
+       procd_close_instance
+
+       $LOGGER instance "$1" has started
+}
+
+handle_instance() {
+       config_get opts "$1" opts
+       config_get section "$1" section
+
+       run_instance "$1" "$section" "$opts"
+}
+
+start_service() {
+       config_load $NAME
+
+       config_get_bool enabled global enabled 0
+
+       rtp_spool_dir=/var/spool/rtpengine
+
+       if [ "$enabled" -eq 1 ]; then
+               if ! [ -e "$rtp_spool_dir" ]; then
+                       mkdir -m 0750 -p "$rtp_spool_dir"
+                       [ -d "$rtp_spool_dir" ] && \
+                               chown $NAME:$NAME "$rtp_spool_dir"
+               fi
+               config_foreach handle_instance instance
+       else
+               $LOG_ERR service not enabled
+               $LOG_ERR edit /etc/config/$NAME
+       fi
+}
diff --git a/net/rtpengine/patches/01-cflags.patch b/net/rtpengine/patches/01-cflags.patch
new file mode 100644 (file)
index 0000000..6be3d78
--- /dev/null
@@ -0,0 +1,41 @@
+--- a/daemon/Makefile
++++ b/daemon/Makefile
+@@ -51,7 +51,7 @@ endif
+ endif
+ endif
+-CFLAGS=               -g -Wall -Wstrict-prototypes -pthread -fno-strict-aliasing
++CFLAGS+=      -g -Wall -Wstrict-prototypes -pthread -fno-strict-aliasing
+ CFLAGS+=      -std=c99
+ CFLAGS+=      $(shell pkg-config --cflags glib-2.0)
+ CFLAGS+=      $(shell pkg-config --cflags gthread-2.0)
+--- a/lib/lib.Makefile
++++ b/lib/lib.Makefile
+@@ -47,8 +47,6 @@ endif
+ ifeq ($(DBG),yes)
+ CFLAGS+=      -D__DEBUG=1
+-else
+-CFLAGS+=      -O3
+ endif
+--- a/iptables-extension/Makefile
++++ b/iptables-extension/Makefile
+@@ -1,5 +1,5 @@
+ CC?=gcc
+-CFLAGS                = -O2 -Wall -Wstrict-prototypes -shared -fPIC
++CFLAGS                += -Wall -Wstrict-prototypes -shared -fPIC
+ ifneq ($(RTPENGINE_VERSION),)
+   CFLAGS      += -DRTPENGINE_VERSION="\"$(RTPENGINE_VERSION)\""
+ else
+--- a/recording-daemon/Makefile
++++ b/recording-daemon/Makefile
+@@ -1,6 +1,6 @@
+ TARGET=               rtpengine-recording
+-CFLAGS=               -g -Wall -Wstrict-prototypes -pthread -I. -I../lib/ -I../kernel-module/
++CFLAGS+=      -g -Wall -Wstrict-prototypes -pthread -I. -I../lib/ -I../kernel-module/
+ CFLAGS+=      -std=c99 -fno-strict-aliasing
+ CFLAGS+=      -D_GNU_SOURCE -D_POSIX_SOURCE -D_POSIX_C_SOURCE
+ CFLAGS+=      $(shell pkg-config --cflags glib-2.0)
diff --git a/net/rtpengine/patches/02-kernel-include.patch b/net/rtpengine/patches/02-kernel-include.patch
new file mode 100644 (file)
index 0000000..f050583
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/kernel-module/xt_RTPENGINE.c
++++ b/kernel-module/xt_RTPENGINE.c
+@@ -2,6 +2,7 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/ip.h>
++#include <net/ip6_checksum.h>
+ #include <linux/udp.h>
+ #include <linux/icmp.h>
+ #include <linux/version.h>
diff --git a/net/rtpengine/patches/03-uclibc-getloadavg.patch b/net/rtpengine/patches/03-uclibc-getloadavg.patch
new file mode 100644 (file)
index 0000000..9351de5
--- /dev/null
@@ -0,0 +1,46 @@
+--- a/daemon/load.c
++++ b/daemon/load.c
+@@ -14,6 +14,43 @@ int cpu_usage; // percent times 100 (0 -
+ static long used_last, idle_last;
++/* uclibc and dietlibc do not have this junk -ReneR */
++#if defined (__UCLIBC__) || defined (__dietlibc__)
++static int getloadavg(double loadavg[], int nelem) {
++  int fd;
++
++  fd = open ("/proc/loadavg", O_RDONLY);
++  if (fd < 0)
++    return -1;
++  else
++    {
++      char buf[65], *p;
++      ssize_t nread;
++      int i;
++
++      nread = read (fd, buf, sizeof buf - 1);
++      close (fd);
++      if (nread <= 0)
++        return -1;
++      buf[nread - 1] = '\0';
++
++      if (nelem > 3)
++      nelem = 3;
++      p = buf;
++      for (i = 0; i < nelem; ++i)
++        {
++          char *endp;
++          loadavg[i] = strtod (p, &endp);
++          if (endp == p)
++            return -1;
++          p = endp;
++        }
++
++      return i;
++    }
++}
++#endif
++
+ void load_thread(void *dummy) {
+       while (!rtpe_shutdown) {
+               if (rtpe_config.load_limit) {