From ff67aa6f79a73e48115464b542c58c09bf969e62 Mon Sep 17 00:00:00 2001 From: Sebastian Kemper Date: Mon, 4 May 2020 20:00:59 +0200 Subject: [PATCH] rtpengine: new package 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 --- net/rtpengine/Makefile | 250 ++++++++++++++++++ net/rtpengine/files/rtpengine-recording.conf | 10 + net/rtpengine/files/rtpengine-recording.init | 51 ++++ net/rtpengine/files/rtpengine.conf | 17 ++ net/rtpengine/files/rtpengine.hotplug | 23 ++ net/rtpengine/files/rtpengine.init | 58 ++++ net/rtpengine/patches/01-cflags.patch | 41 +++ net/rtpengine/patches/02-kernel-include.patch | 10 + .../patches/03-uclibc-getloadavg.patch | 46 ++++ 9 files changed, 506 insertions(+) create mode 100644 net/rtpengine/Makefile create mode 100644 net/rtpengine/files/rtpengine-recording.conf create mode 100644 net/rtpengine/files/rtpengine-recording.init create mode 100644 net/rtpengine/files/rtpengine.conf create mode 100644 net/rtpengine/files/rtpengine.hotplug create mode 100644 net/rtpengine/files/rtpengine.init create mode 100644 net/rtpengine/patches/01-cflags.patch create mode 100644 net/rtpengine/patches/02-kernel-include.patch create mode 100644 net/rtpengine/patches/03-uclibc-getloadavg.patch diff --git a/net/rtpengine/Makefile b/net/rtpengine/Makefile new file mode 100644 index 0000000..01b36bc --- /dev/null +++ b/net/rtpengine/Makefile @@ -0,0 +1,250 @@ +# +# Copyright (C) 2020 Sebastian Kemper +# +# 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 + +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 index 0000000..d0a8218 --- /dev/null +++ b/net/rtpengine/files/rtpengine-recording.conf @@ -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 index 0000000..cd5badc --- /dev/null +++ b/net/rtpengine/files/rtpengine-recording.init @@ -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 index 0000000..93d9e20 --- /dev/null +++ b/net/rtpengine/files/rtpengine.conf @@ -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 index 0000000..3fa3f09 --- /dev/null +++ b/net/rtpengine/files/rtpengine.hotplug @@ -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 index 0000000..d56912a --- /dev/null +++ b/net/rtpengine/files/rtpengine.init @@ -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 index 0000000..6be3d78 --- /dev/null +++ b/net/rtpengine/patches/01-cflags.patch @@ -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 index 0000000..f050583 --- /dev/null +++ b/net/rtpengine/patches/02-kernel-include.patch @@ -0,0 +1,10 @@ +--- a/kernel-module/xt_RTPENGINE.c ++++ b/kernel-module/xt_RTPENGINE.c +@@ -2,6 +2,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/net/rtpengine/patches/03-uclibc-getloadavg.patch b/net/rtpengine/patches/03-uclibc-getloadavg.patch new file mode 100644 index 0000000..9351de5 --- /dev/null +++ b/net/rtpengine/patches/03-uclibc-getloadavg.patch @@ -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) { -- 2.30.2