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 <sebastian_ml@gmx.net>
This commit is contained in:
Sebastian Kemper 2020-05-04 20:00:59 +02:00
parent 3e8a75a622
commit ff67aa6f79
9 changed files with 506 additions and 0 deletions

250
net/rtpengine/Makefile Normal file
View file

@ -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))

View file

@ -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.

View file

@ -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
}

View file

@ -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

View file

@ -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
}

View file

@ -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
}

View file

@ -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)

View file

@ -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>

View file

@ -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) {