diff --git a/.github/workflows.cfg b/.github/workflows.cfg index b0a61760a..1c6d55c1f 100644 --- a/.github/workflows.cfg +++ b/.github/workflows.cfg @@ -1,8 +1,9 @@ # Comment the line(s) below to disable particular pipeline(s): -do_Docker=true -do_FullBuild=true -do_FuncTest=true -do_Fuzzing=true -do_Glitch=true -do_MinBuild=true +do_Docker=false +do_FullBuild=false +do_FuncTest=false +do_Fuzzing=false +do_Glitch=false +do_MinBuild=false +do_DebianPackage=true diff --git a/.github/workflows/.jobs_configure.yml b/.github/workflows/.jobs_configure.yml index f38fd2c15..3e1ca6188 100644 --- a/.github/workflows/.jobs_configure.yml +++ b/.github/workflows/.jobs_configure.yml @@ -21,6 +21,9 @@ on: do_MinBuild: description: "Whether the current workflow should continue" value: ${{ jobs.check_disabled_actions.outputs.do_MinBuild }} + do_DebianPackage: + description: "Whether the current workflow should continue" + value: ${{ jobs.check_disabled_actions.outputs.do_DebianPackage }} jobs: check_disabled_actions: @@ -33,6 +36,7 @@ jobs: do_Fuzzing: ${{ steps.check_status.outputs.do_Fuzzing }} do_Glitch: ${{ steps.check_status.outputs.do_Glitch }} do_MinBuild: ${{ steps.check_status.outputs.do_MinBuild }} + do_DebianPackage: ${{ steps.check_status.outputs.do_DebianPackage }} steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/rtpproxy_ci.yml b/.github/workflows/rtpproxy_ci.yml index 82b60e660..b27d4f3ab 100644 --- a/.github/workflows/rtpproxy_ci.yml +++ b/.github/workflows/rtpproxy_ci.yml @@ -94,6 +94,80 @@ jobs: - name: build run: sh -x ./scripts/do-build.sh cleanbuild + DebianPackage: + name: Debian package build + needs: LoadJobs_conf + if: needs.LoadJobs_conf.outputs.do_DebianPackage == 'true' + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + - name: Install build tools + run: | + sudo apt-get update + sudo apt-get install -y build-essential devscripts debhelper pkg-config libssl-dev libbcg729-dev libgsm1-dev libsndfile1-dev libunwind-dev libsrtp2-dev libsystemd-dev fakeroot zip + - name: Build Debian package + env: + DEB_BUILD_OPTIONS: nocheck + run: | + dpkg-buildpackage -us -uc -b + + - name: Collect Debian packages + run: | + set -euo pipefail + mkdir -p debian-artifacts + shopt -s nullglob + for artifact in ../*.deb ../*.ddeb ../*.buildinfo ../*.changes; do + [ -e "${artifact}" ] || continue + base=$(basename "${artifact}") + mv "${artifact}" "debian-artifacts/${base}" + done + + - name: Test install Debian packages + run: | + set -euo pipefail + shopt -s nullglob + pkgs=(./debian-artifacts/*.deb) + if [ "${#pkgs[@]}" -eq 0 ]; then + echo "No Debian packages produced" >&2 + exit 1 + fi + sudo apt-get install -y "${pkgs[@]}" + + - name: Exercise systemd service + run: | + set -euo pipefail + sudo systemctl daemon-reload + sudo systemctl enable --now rtpproxy.socket + sudo systemctl start rtpproxy.service + sudo systemctl status --no-pager rtpproxy.service + sudo systemctl restart rtpproxy.service + sudo systemctl status --no-pager rtpproxy.service + sudo systemctl stop rtpproxy.service + sudo systemctl status --no-pager rtpproxy.service || true + sudo systemctl disable --now rtpproxy.socket + + - name: Setup GitHub Actions artifact client + uses: lhotari/gh-actions-artifact-client@v2 + + - name: Upload Debian artifacts + run: | + set -euo pipefail + shopt -s nullglob + uploaded=0 + for file in debian-artifacts/*.deb debian-artifacts/*.ddeb debian-artifacts/*.buildinfo debian-artifacts/*.changes; do + [ -e "$file" ] || continue + uploaded=1 + name=$(basename "$file") + echo "Uploading $name, file: $file" + zip - "$file" | gh-actions-artifact-client.js upload "$name" --retentionDays=7 + done + if [ "$uploaded" -eq 0 ]; then + echo "No Debian artifacts found for upload" >&2 + exit 1 + fi + FullBuild: name: Full Build needs: [LoadJobs_conf, MinBuild] @@ -427,7 +501,8 @@ jobs: GIT_BRANCH="${GIT_BRANCH#refs/tags/}" echo "GIT_BRANCH=${GIT_BRANCH}" >> $GITHUB_ENV OS_TAG="`echo ${BASE_IMAGE} | sed 's|:|_|g'`" - CCACHE_IMAGE="${{ env.GHCR_REPO }}:${GIT_BRANCH}-${OS_TAG}-cccache" + BRANCH_TAG="`echo ${GIT_BRANCH} | sed 's|/|_|g'`" + CCACHE_IMAGE="${{ env.GHCR_REPO }}:${BRANCH_TAG}-${OS_TAG}-cccache" if ! docker pull ${CCACHE_IMAGE} 2>&1 >/dev/null then CCACHE_BIMAGE="scratch" @@ -435,6 +510,7 @@ jobs: CCACHE_BIMAGE="${CCACHE_IMAGE}" fi docker pull ${CCACHE_BIN_IMAGE} + echo "BRANCH_TAG=${BRANCH_TAG}" >> $GITHUB_ENV echo "CCACHE_IMAGE=${CCACHE_IMAGE}" >> $GITHUB_ENV echo "CCACHE_BIMAGE=${CCACHE_BIMAGE}" >> $GITHUB_ENV echo "BUILD_IMAGE=${{ env.LOCAL_REPO }}:latest-${OS_TAG}" >> $GITHUB_ENV @@ -463,12 +539,12 @@ jobs: with: images: ${{ env.DOCKER_REPO }} tags: | - type=schedule,suffix=-${{ env.OS_TAG}} - type=ref,event=branch,suffix=-${{ env.OS_TAG}} - type=ref,event=tag,suffix=-${{ env.OS_TAG}} - type=ref,event=pr,suffix=-${{ env.OS_TAG}} - type=raw,value=latest-${{ env.OS_TAG}},enable={{is_default_branch}} - type=sha,suffix=-${{ env.OS_TAG}} + type=schedule,suffix=-${{ env.OS_TAG }} + type=ref,event=branch,suffix=-${{ env.OS_TAG }} + type=ref,event=tag,suffix=-${{ env.OS_TAG }} + type=ref,event=pr,suffix=-${{ env.OS_TAG }} + type=raw,value=latest-${{ env.OS_TAG }},enable={{is_default_branch}} + type=sha,suffix=-${{ env.OS_TAG }} type=raw,value=latest,enable=${{ env.ADD_LATEST == 'true' }} - name: Extract metadata (tags, labels) for GHCR @@ -477,18 +553,18 @@ jobs: with: images: ${{ env.GHCR_REPO }} tags: | - type=schedule,suffix=-${{ env.OS_TAG}} - type=ref,event=branch,suffix=-${{ env.OS_TAG}} - type=ref,event=tag,suffix=-${{ env.OS_TAG}} - type=ref,event=pr,suffix=-${{ env.OS_TAG}} - type=raw,value=latest-${{ env.OS_TAG}},enable={{is_default_branch}} - type=sha,suffix=-${{ env.OS_TAG}} + type=schedule,suffix=-${{ env.OS_TAG }} + type=ref,event=branch,suffix=-${{ env.OS_TAG }} + type=ref,event=tag,suffix=-${{ env.OS_TAG }} + type=ref,event=pr,suffix=-${{ env.OS_TAG }} + type=raw,value=latest-${{ env.OS_TAG }},enable={{is_default_branch}} + type=sha,suffix=-${{ env.OS_TAG }} type=raw,value=latest,enable=${{ env.ADD_LATEST == 'true' }} - name: Build Docker image uses: docker/build-push-action@v6 env: - CACHE_SPEC: "type=registry,ref=${{ env.GHCR_REPO }}:${{ env.GIT_BRANCH }}-${{ env.OS_TAG}}-buildcache" + CACHE_SPEC: "type=registry,ref=${{ env.GHCR_REPO }}:${{ env.BRANCH_TAG }}-${{ env.OS_TAG }}-buildcache" with: context: . file: ./docker/Dockerfile diff --git a/LICENSE b/LICENSE index bc0b3353b..c1515b524 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ BSD 2-Clause License Copyright (c) 2004-2006 Maxim Sobolev -Copyright (c) 2006-2019, Sippy Software, Inc., http://www.sippysoft.com +Copyright (c) 2006-2025, Sippy Software, Inc., http://www.sippysoft.com All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/debian/README.source b/debian/README.source new file mode 100644 index 000000000..ba4fe6b8f --- /dev/null +++ b/debian/README.source @@ -0,0 +1,13 @@ +Building the Debian packaging helpers locally requires the Debian helper tools. + +Before invoking commands such as `debian/rules clean` or `dpkg-buildpackage`, +install the packaging toolchain, for example: + +``` +sudo apt-get update +sudo apt-get install debhelper +``` + +The packaging workflow in CI already provisions these dependencies. When +working on the packaging locally you need to provision them once per build +environment. diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..d34e1af4f --- /dev/null +++ b/debian/changelog @@ -0,0 +1,35 @@ +rtpproxy (3.1+dev1) unstable; urgency=medium + + * Build librtpproxy during package configuration and ship a new + rtpproxy-dev package with the static archive and public header. + * Add optional audio and unwind build dependencies required by the + librtpproxy-enabled build. + * Split debugging helpers and *_debug modules into the rtpproxy-debug + binary package. + * Ship the DTLS gateway and ICE lite modules in their respective + runtime and debug packages to avoid missing-file warnings. + * Depend on libsrtp2 during the build so the crypto modules are + compiled and available for packaging. + * Enable systemd integration by building against libsystemd-dev and + configuring with --enable-systemd. + * Preserve librtpproxy's static archive contents under LTO by appending + -ffat-lto-objects to the maintainer build flags. + * Reuse the upstream systemd service and socket units in Debian builds, + installing their shared sysconfig file for consistent configuration. + * Update the systemd service to supervise rtpproxy via systemd sockets + so the packaged unit works with Type=notify without extra tuning. + * Create a dedicated rtpproxy user and group at install time so the + service runs under a locked-down account by default. + * Align the packaged systemd unit with /run paths so PID tracking stays + consistent with RuntimeDirectory management. + * Keep ExecStart's pidfile flag pointed at /run/rtpproxy/rtpproxy.pid + because the MAINPID environment variable is not available at start + time. + + -- Maxim Sobolev Wed, 15 May 2024 00:00:00 +0000 + +rtpproxy (3.1) unstable; urgency=medium + + * Initial release of Debian packaging skeleton. + + -- Maxim Sobolev Wed, 15 May 2024 00:00:00 +0000 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..29eeba7db --- /dev/null +++ b/debian/control @@ -0,0 +1,48 @@ +Source: rtpproxy +Section: net +Priority: optional +Maintainer: Maxim Sobolev +Build-Depends: debhelper-compat (= 13), + pkg-config, + libssl-dev, + libbcg729-dev, + libgsm1-dev, + libsndfile1-dev, + libunwind-dev, + libsrtp2-dev, + libsystemd-dev +Standards-Version: 4.6.2 +Homepage: https://github.com/sippy/rtpproxy +Vcs-Git: https://github.com/sippy/rtpproxy.git +Vcs-Browser: https://github.com/sippy/rtpproxy +Rules-Requires-Root: no + +Package: rtpproxy +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends}, adduser +Description: High-performance SIP RTP media proxy + RTPProxy is a high-performance, scalable media relay designed for + SIP-based applications. It supports advanced media handling features + such as secure RTP, codec transcoding modules, and high availability + deployments. + +Package: rtpproxy-debug +Section: debug +Architecture: any +Depends: ${misc:Depends}, rtpproxy (= ${binary:Version}) +Multi-Arch: same +Description: Debug helpers and modules for RTPProxy + This package provides the debugging-friendly binaries and modules for + RTPProxy, including the rtpproxy_debug control tool, UDP contention + tester, and the *_debug.so plugin variants. + +Package: rtpproxy-dev +Section: libdevel +Architecture: any +Depends: ${misc:Depends}, rtpproxy (= ${binary:Version}) +Multi-Arch: same +Description: Development files for librtpproxy instrumentation library + librtpproxy exposes the internal RTPProxy engine to external tooling + for instrumentation and advanced control. This development package + ships the static archive and public header needed to link against the + library. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000..58176f9e1 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,30 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: rtpproxy +Upstream-Contact: Maxim Sobolev +Source: https://github.com/sippy/rtpproxy + +Files: * +Copyright: 2004-2006 Maxim Sobolev + 2006-2025 Sippy Software, Inc. +License: BSD-2-Clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 000000000..fac29b400 --- /dev/null +++ b/debian/dirs @@ -0,0 +1,2 @@ +etc/sysconfig +var/lib/rtpproxy diff --git a/debian/rtpproxy-debug.install b/debian/rtpproxy-debug.install new file mode 100644 index 000000000..73993ff55 --- /dev/null +++ b/debian/rtpproxy-debug.install @@ -0,0 +1,7 @@ +usr/bin/rtpproxy_debug +usr/bin/udp_contention +usr/lib/*/rtpproxy/rtpp_acct_csv_debug.so +usr/lib/*/rtpproxy/rtpp_acct_rtcp_hep_debug.so +usr/lib/*/rtpproxy/rtpp_catch_dtmf_debug.so +usr/lib/*/rtpproxy/rtpp_dtls_gw_debug.so +usr/lib/*/rtpproxy/rtpp_ice_lite_debug.so diff --git a/debian/rtpproxy-dev.install b/debian/rtpproxy-dev.install new file mode 100644 index 000000000..6d50d166a --- /dev/null +++ b/debian/rtpproxy-dev.install @@ -0,0 +1,2 @@ +usr/include/librtpproxy.h +usr/lib/*/librtpproxy.a diff --git a/debian/rtpproxy.examples b/debian/rtpproxy.examples new file mode 100644 index 000000000..d113092de --- /dev/null +++ b/debian/rtpproxy.examples @@ -0,0 +1 @@ +doc/rtpproxy.conf.sample diff --git a/debian/rtpproxy.install b/debian/rtpproxy.install new file mode 100644 index 000000000..8953d31c8 --- /dev/null +++ b/debian/rtpproxy.install @@ -0,0 +1,11 @@ +usr/bin/makeann +usr/bin/extractaudio +usr/bin/rtpproxy +usr/lib/*/rtpproxy/rtpp_acct_csv.so +usr/lib/*/rtpproxy/rtpp_acct_rtcp_hep.so +usr/lib/*/rtpproxy/rtpp_catch_dtmf.so +usr/lib/*/rtpproxy/rtpp_dtls_gw.so +usr/lib/*/rtpproxy/rtpp_ice_lite.so +rpm/rtpproxy.service usr/lib/systemd/system/ +rpm/rtpproxy.socket usr/lib/systemd/system/ +rpm/rtpproxy.sysconfig etc/sysconfig/rtpproxy diff --git a/debian/rtpproxy.manpages b/debian/rtpproxy.manpages new file mode 100644 index 000000000..3952ce28b --- /dev/null +++ b/debian/rtpproxy.manpages @@ -0,0 +1 @@ +rtpproxy.8 diff --git a/debian/rtpproxy.postinst b/debian/rtpproxy.postinst new file mode 100755 index 000000000..a984bac5b --- /dev/null +++ b/debian/rtpproxy.postinst @@ -0,0 +1,19 @@ +#!/bin/sh +set -e + +case "$1" in + configure) + if ! getent group rtpproxy >/dev/null; then + addgroup --system rtpproxy + fi + if ! getent passwd rtpproxy >/dev/null; then + adduser --system --ingroup rtpproxy --home /var/lib/rtpproxy \ + --shell /usr/sbin/nologin --no-create-home rtpproxy + fi + install -d -o rtpproxy -g rtpproxy -m 0750 /var/lib/rtpproxy + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/debian/rtpproxy.postrm b/debian/rtpproxy.postrm new file mode 100755 index 000000000..3f606dfef --- /dev/null +++ b/debian/rtpproxy.postrm @@ -0,0 +1,17 @@ +#!/bin/sh +set -e + +case "$1" in + purge) + if command -v deluser >/dev/null 2>&1; then + deluser --system --quiet rtpproxy || true + fi + if command -v delgroup >/dev/null 2>&1; then + delgroup --quiet rtpproxy || true + fi + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..ae425b0ad --- /dev/null +++ b/debian/rules @@ -0,0 +1,27 @@ +#!/usr/bin/make -f + +export DEB_CFLAGS_MAINT_APPEND = -ffat-lto-objects +export DEB_CXXFLAGS_MAINT_APPEND = -ffat-lto-objects + +%: + dh $@ + +override_dh_auto_configure: + dh_auto_configure -- --enable-librtpproxy --enable-systemd --enable-lto=yes + +override_dh_update_autotools_config: + @echo "Skipping autotools config update" + +override_dh_autoreconf: + @echo "Skipping autoreconf; using bundled configure script" + +override_dh_shlibdeps: + dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info + +execute_after_dh_auto_install: + rm -f debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/rtpproxy/*.la + rm -f debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/librtpproxy.la + rm -f debian/tmp/usr/share/man/man8/rtpproxy.8 + +override_dh_auto_test: + @echo "Skipping upstream tests for package build" diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000..89ae9db8f --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/debian/watch b/debian/watch new file mode 100644 index 000000000..421b4b0d0 --- /dev/null +++ b/debian/watch @@ -0,0 +1,3 @@ +version=4 +opts=filenamemangle=s/.+\/v?(\d[^/]+)\.tar\.gz/rtpproxy-$1\.tar.gz/ \ + https://github.com/sippy/rtpproxy/releases .*/archive/refs/tags/v?(\d[^/]+)\.tar\.gz diff --git a/doc/rtpproxy.conf.sample b/doc/rtpproxy.conf.sample new file mode 100644 index 000000000..9dcff869a --- /dev/null +++ b/doc/rtpproxy.conf.sample @@ -0,0 +1,18 @@ +# Example rtpproxy configuration file in UCL format. +# +# Enable accounting modules shipped with the Debian rtpproxy package. +# Comment or remove any modules you do not plan to use. The runtime will +# automatically load the shared object that matches each module name. +modules { + acct_csv { + logfile = /var/log/rtpproxy/rtpproxy.csv + } + + # Forward RTCP reports to a HEP collector. + acct_rtcp_hep { + capt_host = 127.0.0.1 + capt_port = 9060 + capt_ptype = udp + capt_id = 101 + } +} diff --git a/docker/Dockerfile b/docker/Dockerfile index b5bb5d6bf..c0cbbb274 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -51,6 +51,7 @@ WORKDIR /rtpproxy COPY --from=ccache_bin /usr/bin/ccache /usr/bin/ccache ARG TARGETPLATFORM ARG BASE_IMAGE +ENV CCACHE_COMPILERCHECK="content" RUN env `./scripts/build/get-arch-buildargs.sh platformopts` \ /rtpproxy/docker/build.sh RUN ls -l /usr/local/bin/rtpproxy* diff --git a/rpm/rtpproxy.service b/rpm/rtpproxy.service index f7f8c7371..1b465a328 100644 --- a/rpm/rtpproxy.service +++ b/rpm/rtpproxy.service @@ -1,14 +1,19 @@ [Unit] -Description=A symmetric RTP proxy +Description=RTPProxy media relay +Documentation=man:rtpproxy(8) After=network.target [Service] Type=notify User=rtpproxy Group=rtpproxy -EnvironmentFile=/etc/sysconfig/rtpproxy -PIDFile=/var/run/rtpproxy/rtpproxy.pid -ExecStart=/usr/bin/rtpproxy -f -p /var/run/rtpproxy/rtpproxy.pid $OPTIONS +EnvironmentFile=-/etc/sysconfig/rtpproxy +PIDFile=/run/rtpproxy/rtpproxy.pid +RuntimeDirectory=rtpproxy +RuntimeDirectoryMode=0755 +ExecStart=/usr/bin/rtpproxy -f -s systemd: -p /run/rtpproxy/rtpproxy.pid $OPTIONS +ExecReload=/bin/kill -HUP $MAINPID +Restart=on-failure [Install] Also=rtpproxy.socket diff --git a/rpm/rtpproxy.sysconfig b/rpm/rtpproxy.sysconfig index 9186ef794..58275d90b 100644 --- a/rpm/rtpproxy.sysconfig +++ b/rpm/rtpproxy.sysconfig @@ -1 +1,9 @@ +# Command-line options passed to rtpproxy by the systemd unit. +# +# The service already enables foreground operation and manages the runtime +# directory, so typically only the control socket and advertised addresses +# need to be provided here. For example: +# OPTIONS="-s udp:127.0.0.1:7722 -l 203.0.113.10/198.51.100.10" +# +# Leave the value empty to accept the built-in defaults. OPTIONS=""