diff --git a/.github/workflows/.rtp.io.yml b/.github/workflows/.rtp.io.yml new file mode 100644 index 00000000000..fc163091029 --- /dev/null +++ b/.github/workflows/.rtp.io.yml @@ -0,0 +1,274 @@ +name: rtp.io + +on: + workflow_call: + inputs: + llvm-version: + required: true + type: string + llvm-version-old: + required: true + type: string + ghcr-repo: + required: false + type: string + default: ghcr.io/${{ github.repository_owner }}/opensips + rtpp-repo: + required: false + type: string + default: ghcr.io/sippy/rtpproxy:latest + rtpp-tag: + required: false + type: string + default: debian_12-slim + +jobs: + set_env: + name: Set Environment + runs-on: ubuntu-latest + env: + BASE_IMAGE: ${{ inputs.rtpp-repo }}-${{ inputs.rtpp-tag }} + outputs: + platforms: ${{ steps.set-env.outputs.platforms }} + build-matrix: ${{ steps.set-env.outputs.build-matrix }} + test-matrix: ${{ steps.set-env.outputs.test-matrix }} + build-os: ${{ steps.set-env.outputs.build-os }} + build-image: ${{ steps.set-env.outputs.build-image }} + git-branch: ${{ steps.set-env.outputs.git-branch }} + steps: + - uses: actions/checkout@v4 + + - name: Set dynamic environment + id: set-env + run: | + BUILD_OS="`echo ${{ inputs.rtpp-tag }} | sed 's|-.*|| ; s|_|-|g'`" + PLATFORMS="`docker manifest inspect ${{ env.BASE_IMAGE }} | \ + jq -r '.manifests[] | "\(.platform.os)/\(.platform.architecture)\(if .platform.variant != null then "/\(.platform.variant)" else "" end)"' | \ + sort -u | grep -v unknown | BUILD_OS="${BUILD_OS}" ./scripts/build/get-arch-buildargs.rtp.io fltplatforms | paste -sd ','`" + BUILD_MATRIX="`echo ${PLATFORMS} | tr ',' '\n' | jq -R . | jq -s . | tr '\n' ' '`" + GIT_BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" + GIT_BRANCH="${GIT_BRANCH#refs/tags/}" + BUILD_IMAGE="${{ inputs.ghcr-repo }}:rtp.io-${{ inputs.rtpp-tag }}-${GIT_BRANCH}" + echo "Platforms: ${PLATFORMS}" + for _p in `echo ${PLATFORMS} | tr ',' '\n'`; \ + do \ + if TARGETPLATFORM="${_p}" BUILD_OS="${BUILD_OS}" ./scripts/build/get-arch-buildargs.rtp.io isbrokenplatform; \ + then \ + TEST_MATRIX="${_p}${TEST_MATRIX:+,}${TEST_MATRIX}"; \ + fi; \ + done + TEST_MATRIX="`echo ${TEST_MATRIX} | tr ',' '\n' | jq -R . | jq -s . | tr '\n' ' '`" + echo "platforms=${PLATFORMS}" >> $GITHUB_OUTPUT + echo "build-matrix=${BUILD_MATRIX}" >> $GITHUB_OUTPUT + echo "test-matrix=${TEST_MATRIX}" >> $GITHUB_OUTPUT + echo "build-os=${BUILD_OS}" >> $GITHUB_OUTPUT + echo "build-image=${BUILD_IMAGE}" >> $GITHUB_OUTPUT + echo "git-branch=${GIT_BRANCH}" >> $GITHUB_OUTPUT + + build_rtp_io_dock: + name: Build Container (GHCR) + needs: set_env + runs-on: ubuntu-latest + if: ${{ github.event_name != 'pull_request' }} + permissions: + packages: write + env: + BASE_IMAGE: ${{ inputs.rtpp-repo }}-${{ inputs.rtpp-tag }} + BUILD_OS: ${{ needs.set_env.outputs.build-os }} + PLATFORMS: ${{ needs.set_env.outputs.platforms }} + BUILD_IMAGE: ${{ needs.set_env.outputs.build-image }} + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Checkout VoIPTests repo + uses: actions/checkout@v4 + with: + repository: 'sippy/voiptests' + path: dist/voiptests + + - name: Checkout RTPProxy repo + uses: actions/checkout@v4 + with: + repository: 'sippy/rtpproxy' + path: dist/rtpproxy + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Docker image + uses: docker/build-push-action@v6 + env: + CACHE_SPEC: "type=registry,ref=${{ env.BUILD_IMAGE }}-buildcache" + with: + context: . + file: ./docker/Dockerfile.rtp.io + build-args: | + BASE_IMAGE=${{ env.BASE_IMAGE }} + BUILD_OS=${{ env.BUILD_OS }} + LLVM_VER=${{ inputs.llvm-version }} + LLVM_VER_OLD=${{ inputs.llvm-version-old }} + platforms: ${{ env.PLATFORMS }} + cache-from: ${{ env.CACHE_SPEC }} + cache-to: ${{ env.CACHE_SPEC }},mode=max + tags: ${{ env.BUILD_IMAGE }} + push: true + + build_rtp_io_dock_local: + name: Build Container (Local) + needs: set_env + runs-on: ubuntu-latest + if: ${{ github.event_name == 'pull_request' }} + strategy: + fail-fast: false + matrix: + platform: ${{ fromJSON(needs.set_env.outputs.build-matrix) }} + env: + BASE_IMAGE: ${{ inputs.rtpp-repo }}-${{ inputs.rtpp-tag }} + BUILD_OS: ${{ needs.set_env.outputs.build-os }} + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Checkout VoIPTests repo + uses: actions/checkout@v4 + with: + repository: 'sippy/voiptests' + path: dist/voiptests + + - name: Checkout RTPProxy repo + uses: actions/checkout@v4 + with: + repository: 'sippy/rtpproxy' + path: dist/rtpproxy + + - name: Set up QEMU + if: matrix.platform != 'linux/386' && matrix.platform != 'linux/amd64' + uses: docker/setup-qemu-action@v3 + with: + platforms: ${{ matrix.platform }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set dynamic environment + id: set-env + run: | + OUTPUT_TAG="myimage:`echo ${{ matrix.platform }} | sed 's|/|-|g'`" + OUTPUT_IMAGE_N="image-${BUILD_OS}-`echo ${{ matrix.platform }} | sed 's|/|-|g'`" + OUTPUT_IMAGE="./${OUTPUT_IMAGE_N}.tar" + CACHE_SPEC="type=gha,scope=${OUTPUT_IMAGE_N}-buildcache" + echo OUTPUT_TAG="${OUTPUT_TAG}" >> $GITHUB_ENV + echo OUTPUT_IMAGE="${OUTPUT_IMAGE}" >> $GITHUB_ENV + echo OUTPUT_IMAGE_N="${OUTPUT_IMAGE_N}" >> $GITHUB_ENV + echo CACHE_SPEC="${CACHE_SPEC}" >> $GITHUB_ENV + + - name: Build Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./docker/Dockerfile.rtp.io + build-args: | + BASE_IMAGE=${{ env.BASE_IMAGE }} + BUILD_OS=${{ env.BUILD_OS }} + LLVM_VER=${{ inputs.llvm-version }} + LLVM_VER_OLD=${{ inputs.llvm-version-old }} + platforms: ${{ matrix.platform }} + tags: ${{ env.OUTPUT_TAG }} + outputs: type=docker,dest=${{ env.OUTPUT_IMAGE }} + cache-from: ${{ env.CACHE_SPEC }} + cache-to: ${{ env.CACHE_SPEC }},mode=max + + - name: Upload image artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ env.OUTPUT_IMAGE_N }} + path: ${{ env.OUTPUT_IMAGE }} + + test_rtp_io_dock: + name: Test (GHCR) + needs: [build_rtp_io_dock, set_env] + runs-on: ubuntu-latest + if: ${{ github.event_name != 'pull_request' }} + strategy: + fail-fast: false + matrix: + platform: ${{ fromJSON(needs.set_env.outputs.test-matrix) }} + env: + TARGETPLATFORM: ${{ matrix.platform }} + BUILD_IMAGE: ${{ needs.set_env.outputs.build-image }} + BUILD_OS: ${{ needs.set_env.outputs.build-os }} + + steps: + - name: Set up QEMU + if: matrix.platform != 'linux/386' && matrix.platform != 'linux/amd64' + uses: docker/setup-qemu-action@v3 + with: + platforms: ${{ env.TARGETPLATFORM }} + + - name: Test ${{ env.TARGETPLATFORM }} + run: | + docker pull ${BUILD_IMAGE} + docker run --platform ${TARGETPLATFORM} --name test --cap-add=SYS_PTRACE \ + --privileged --sysctl net.ipv6.conf.all.disable_ipv6=0 ${BUILD_IMAGE} + timeout-minutes: 2 + + test_rtp_io_local: + name: Test (LOCAL) + needs: [build_rtp_io_dock_local, set_env] + runs-on: ubuntu-latest + if: ${{ github.event_name == 'pull_request' }} + strategy: + fail-fast: false + matrix: + platform: ${{ fromJSON(needs.set_env.outputs.test-matrix) }} + env: + TARGETPLATFORM: ${{ matrix.platform }} + BUILD_IMAGE: ${{ needs.set_env.outputs.build-image }} + BUILD_OS: ${{ needs.set_env.outputs.build-os }} + + steps: + - name: Set dynamic environment + id: set-env + run: | + OUTPUT_TAG="myimage:`echo ${{ matrix.platform }} | sed 's|/|-|g'`" + OUTPUT_IMAGE_N="image-${BUILD_OS}-`echo ${{ matrix.platform }} | sed 's|/|-|g'`" + OUTPUT_IMAGE="./${OUTPUT_IMAGE_N}.tar" + echo OUTPUT_TAG="${OUTPUT_TAG}" >> $GITHUB_ENV + echo OUTPUT_IMAGE="${OUTPUT_IMAGE}" >> $GITHUB_ENV + echo OUTPUT_IMAGE_N="${OUTPUT_IMAGE_N}" >> $GITHUB_ENV + + - name: Set up QEMU + if: matrix.platform != 'linux/386' && matrix.platform != 'linux/amd64' + uses: docker/setup-qemu-action@v3 + with: + platforms: ${{ env.TARGETPLATFORM }} + + - name: Download image artifact + uses: actions/download-artifact@v4 + with: + name: ${{ env.OUTPUT_IMAGE_N }} + path: . + + - name: Load Docker image + run: docker load -i ${{ env.OUTPUT_IMAGE }} + + - name: Test ${{ env.TARGETPLATFORM }} + run: | + docker run --platform ${TARGETPLATFORM} --name test --cap-add=SYS_PTRACE \ + --privileged --sysctl net.ipv6.conf.all.disable_ipv6=0 ${OUTPUT_TAG} + timeout-minutes: 2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6b34bcc88fb..d8e12380ec9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -56,6 +56,8 @@ jobs: compiler: 'clang-16' - os: 24.04 compiler: 'clang-17' + - os: 24.04 + compiler: 'clang-18' # Steps represent a sequence of tasks that will be executed as part of the job steps: diff --git a/.github/workflows/rtp.io.yml b/.github/workflows/rtp.io.yml new file mode 100644 index 00000000000..c29b77b85db --- /dev/null +++ b/.github/workflows/rtp.io.yml @@ -0,0 +1,132 @@ +# This is a basic workflow to help you get started with Actions + +name: rtp.io + +# Controls when the action will run. +on: + # Triggers the workflow on all push or pull request events + push: + pull_request: + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + LLVM_VER: 18 + LLVM_VER_OLD: 16 + GHCR_REPO: ghcr.io/${{ github.repository_owner }}/opensips + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + build_test_rtp_io_quick: + name: Build & Test rtp.io module (Quick) + # The type of runner that the job will run on + runs-on: ubuntu-latest + container: + image: sippylabs/rtpproxy:latest + options: --cap-add=SYS_PTRACE --privileged --sysctl net.ipv6.conf.all.disable_ipv6=0 + env: + PYTHON_VERSION: 3.12 + BUILD_OS: ubuntu-latest + outputs: + llvm_ver: ${{ steps.set_outputs.outputs.LLVM_VER }} + llvm_ver_old: ${{ steps.set_outputs.outputs.LLVM_VER_OLD }} + ghcr-repo: ${{ steps.set_outputs.outputs.GHCR_REPO }} + + steps: + - name: Set up environment + run: echo "COMPILER=clang-${LLVM_VER}" >> $GITHUB_ENV + + - name: Install git + run: | + apt-get update + apt-get install -y git lsb-release gnupg2 wget + + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Checkout VoIPTests repo + uses: actions/checkout@v4 + with: + repository: 'sippy/voiptests' + path: dist/voiptests + + - name: Checkout RTPProxy repo + uses: actions/checkout@v4 + with: + repository: 'sippy/rtpproxy' + path: dist/rtpproxy + + - name: Install dependencies + run: | + sh -x scripts/build/reset_sources.sh + sh -x scripts/build/install_depends.sh + + - name: Build + run: | + KEEP_MODULES="dialog sipmsgops sl tm rr maxfwd rtp.io rtpproxy textops" + SKIP_MODULES="usrloc event_routing clusterer rtp_relay" + mkdir tmp + cd modules + mv ${KEEP_MODULES} ${SKIP_MODULES} ../tmp + rm -rf * + cd ../tmp + mv ${KEEP_MODULES} ${SKIP_MODULES} ../modules + cd .. + rmdir tmp + EXCLUDE_MODULES_ADD="${SKIP_MODULES}" sh -x scripts/build/do_build.sh + + - name: Build rtp.io module + run: | + apt-get install -y libsrtp2-dev + ONE_MODULE=rtp.io LDFLAGS=-flto CFLAGS=-flto sh -x scripts/build/do_build.sh + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Define PYTHON_CMD + run: | + PYTHON_VER="`echo ${{ env.PYTHON_VERSION }} | sed 's|-dev$||'`" + echo "PYTHON_CMD=python${PYTHON_VER}" >> $GITHUB_ENV + + - name: Test rtp.io module + env: + MM_TYPE: opensips + MM_BRANCH: master + MM_ROOT: ../.. + RTPP_BRANCH: DOCKER + RTPPC_TYPE: rtp.io + RTPPROXY_DIST: ../../dist/rtpproxy + run: | + export CC="${COMPILER}" + cd dist/rtpproxy + ./configure + cd ../../dist/voiptests + python -m pip install -r requirements.txt + DEBIAN_FRONTEND=noninteractive apt-get install -y gpp + sh -x ./test_run.sh + + - name: Pass Environment + id: set_outputs + run: | + echo "LLVM_VER=${LLVM_VER}" >> $GITHUB_OUTPUT + echo "LLVM_VER_OLD=${LLVM_VER_OLD}" >> $GITHUB_OUTPUT + GHCR_REPO="ghcr.io/${{ github.repository_owner }}/opensips" + echo "GHCR_REPO=${GHCR_REPO}" | tr '[:upper:]' '[:lower:]' >> $GITHUB_OUTPUT + + build_test_rtp_io_dock: + name: Build & Test OpenSIPS+rtp.io + needs: build_test_rtp_io_quick + uses: ./.github/workflows/.rtp.io.yml + with: + rtpp-tag: ${{ matrix.rtpp-tag }} + llvm-version: ${{ needs.build_test_rtp_io_quick.outputs.llvm_ver }} + llvm-version-old: ${{ needs.build_test_rtp_io_quick.outputs.llvm_ver_old }} + ghcr-repo: ${{ needs.build_test_rtp_io_quick.outputs.ghcr-repo }} + strategy: + fail-fast: false + matrix: + rtpp-tag: [debian_12-slim, ubuntu_latest] diff --git a/Makefile.conf.template b/Makefile.conf.template index 83765830130..04260d2df1b 100644 --- a/Makefile.conf.template +++ b/Makefile.conf.template @@ -71,7 +71,18 @@ #xmpp= Gateway between OpenSIPS and a jabber server. It enables the exchange of IMs between SIP clients and XMPP(jabber) clients. | parsing/building XML files, typically libexpat1-devel #uuid= UUID generator | uuid-dev -exclude_modules?= aaa_diameter aaa_radius auth_jwt b2b_logic_xml cachedb_cassandra cachedb_couchbase cachedb_dynamodb cachedb_memcached cachedb_mongodb cachedb_redis carrierroute cgrates compression cpl_c db_berkeley db_http db_mysql db_oracle db_perlvdb db_postgres db_sqlite db_unixodbc dialplan emergency event_rabbitmq event_kafka event_sqs h350 httpd http2d identity jabber json launch_darkly ldap lua mi_xmlrpc_ng mmgeoip osp perl pi_http presence presence_dialoginfo presence_mwi presence_reginfo presence_xml presence_dfks proto_ipsec proto_sctp proto_tls proto_wss pua pua_bla pua_dialoginfo pua_mi pua_reginfo pua_usrloc pua_xmpp python regex rabbitmq_consumer rest_client rls siprec sngtc snmpstats stir_shaken tls_mgm tls_openssl tls_wolfssl uuid xcap xcap_client xml xmpp +exclude_modules?= aaa_diameter aaa_radius auth_jwt b2b_logic_xml \ + cachedb_cassandra cachedb_couchbase cachedb_dynamodb cachedb_memcached \ + cachedb_mongodb cachedb_redis carrierroute cgrates compression cpl_c \ + db_berkeley db_http db_mysql db_oracle db_perlvdb db_postgres db_sqlite \ + db_unixodbc dialplan emergency event_rabbitmq event_kafka event_sqs h350 \ + httpd http2d identity jabber json launch_darkly ldap lua mi_xmlrpc_ng \ + mmgeoip osp perl pi_http presence presence_dialoginfo presence_mwi \ + presence_reginfo presence_xml presence_dfks proto_ipsec proto_sctp proto_tls \ + proto_wss pua pua_bla pua_dialoginfo pua_mi pua_reginfo pua_usrloc pua_xmpp \ + python regex rabbitmq_consumer rest_client rls siprec sngtc snmpstats \ + stir_shaken tls_mgm tls_openssl tls_wolfssl uuid xcap xcap_client xml \ + xmpp rtp.io include_modules?= diff --git a/Makefile.defs b/Makefile.defs index 2bbf6fa78c6..4b3d9ebd6fc 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -1124,7 +1124,7 @@ endif #ARCH, sparc64 #if ipaq/netwinder ifeq ($(ARCH), arm) # if gcc -ifeq ($(CC_NAME), gcc) +ifeq ($(CC_NAME:clang=gcc), gcc) #common stuff CFLAGS+=$(CC_OPTIMIZE_FLAG) -funroll-loops -Wcast-align $(PROFILE) \ -Wall -marm @@ -1298,7 +1298,7 @@ endif #ARCH, ppc #if ppc64 ifeq ($(ARCH), ppc64) # if gcc -ifeq ($(CC_NAME), gcc) +ifeq ($(CC_NAME:clang=gcc), gcc) #common stuff CFLAGS+=$(CC_OPTIMIZE_FLAG) -funroll-loops $(PROFILE) -Wall ifeq ($(CC_CLASS), 4.x) diff --git a/docker/Dockerfile.rtp.io b/docker/Dockerfile.rtp.io new file mode 100644 index 00000000000..8debfe6b90f --- /dev/null +++ b/docker/Dockerfile.rtp.io @@ -0,0 +1,57 @@ +# syntax=docker/dockerfile:1.7-labs + +ARG BASE_IMAGE="sippylabs/rtpproxy:latest" +FROM --platform=$TARGETPLATFORM $BASE_IMAGE AS build +LABEL maintainer="Maksym Sobolyev " + +USER root + +# Set Environment Variables +ENV DEBIAN_FRONTEND=noninteractive + +WORKDIR /src + +ARG LLVM_VER=18 +ARG LLVM_VER_OLD=16 +ARG TARGETPLATFORM +ARG BUILD_OS=ubuntu-latest +RUN --mount=type=bind,source=scripts/build,target=scripts/build \ + --mount=type=cache,target=/var/cache/apt,sharing=locked \ + env `./scripts/build/get-arch-buildargs.rtp.io platformopts` \ + sh -x scripts/build/install_depends.sh && \ + eval `./scripts/build/get-arch-buildargs.rtp.io platformopts` && \ + apt-get install -y libsrtp2-dev ${LINKER} +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + apt-get install -y gpp python-is-python3 python3-pip +RUN --mount=type=bind,source=dist/voiptests/requirements.txt,target=requirements.txt \ + --mount=type=cache,target=/root/.cache/pip,sharing=locked \ + python -m pip install --break-system-packages -U -r requirements.txt + +COPY --exclude=.git --exclude=.github --exclude=docker --exclude=dist \ + . . + +ARG KEEP_MODULES="dialog sipmsgops sl tm rr maxfwd rtp.io rtpproxy textops" +ARG SKIP_MODULES="usrloc event_routing clusterer rtp_relay" +RUN mkdir tmp && cd modules && mv ${KEEP_MODULES} ${SKIP_MODULES} ../tmp && \ + rm -rf * && cd ../tmp && mv ${KEEP_MODULES} ${SKIP_MODULES} ../modules && \ + cd .. && rmdir tmp +RUN EXCLUDE_MODULES_ADD="${SKIP_MODULES}" \ + env `./scripts/build/get-arch-buildargs.rtp.io platformopts` \ + sh -x scripts/build/do_build.sh +RUN env ONE_MODULE=rtp.io LDFLAGS="-flto -fuse-ld=lld" CFLAGS=-flto \ + env `./scripts/build/get-arch-buildargs.rtp.io platformopts` \ + sh -x scripts/build/do_build.sh +COPY --exclude=.git --exclude=.github dist/rtpproxy dist/rtpproxy +RUN eval `./scripts/build/get-arch-buildargs.rtp.io platformopts` && \ + cd dist/rtpproxy && CC="${COMPILER}" ./configure + +COPY --exclude=.git --exclude=.github dist/voiptests dist/voiptests + +ENV MM_TYPE=opensips +ENV MM_BRANCH=master +ENV MM_ROOT=../.. +ENV RTPP_BRANCH=DOCKER +ENV RTPPC_TYPE=rtp.io +ENV RTPPROXY_DIST=../../dist/rtpproxy +WORKDIR dist/voiptests +ENTRYPOINT [ "sh", "-x", "./test_run.sh" ] diff --git a/io_wait.h b/io_wait.h index 0d9eee44a99..5231d07fed2 100644 --- a/io_wait.h +++ b/io_wait.h @@ -94,7 +94,9 @@ #ifdef __OS_linux #include /* for GLIBC version testing */ #endif +#ifdef EXTRA_DEBUG #include "lib/dbg/backtrace.h" +#endif #ifndef FD_TYPE_DEFINED typedef int fd_type; @@ -732,13 +734,17 @@ inline static int io_watch_del(io_wait_h* h, int fd, int idx, if (!(idx>=0 && idxfd_no)) { LM_CRIT("[%s] FD index check failed, idx=%d, max=%d" " operating on %d\n",h->name, idx, h->fd_no, fd ); +#ifdef EXTRA_DEBUG log_backtrace(); +#endif rla_dump(); idx = -1; } else if (h->fd_array[idx].fd!=fd) { LM_CRIT("[%s] FD consistency check failed, idx=%d points to fd=%d," " but operating on %d\n",h->name, idx, h->fd_array[idx].fd, fd ); +#ifdef EXTRA_DEBUG log_backtrace(); +#endif rla_dump(); idx = -1; } diff --git a/modules/osp/timeapi.c b/modules/osp/timeapi.c index 7321030ce03..8739c56acdc 100644 --- a/modules/osp/timeapi.c +++ b/modules/osp/timeapi.c @@ -32,21 +32,10 @@ * 2016-01-25 Time related functions. */ -#define _XOPEN_SOURCE 600 /* glibc2 on linux, bsd */ -#define _XOPEN_SOURCE_EXTENDED 1 /* solaris */ - -/** - * * _XOPEN_SOURCE creates conflict in swab definition in Solaris - * */ -#ifdef __OS_solaris - #undef _XOPEN_SOURCE -#endif - +/* make strptime available */ +#define _GNU_SOURCE #include -#undef _XOPEN_SOURCE -#undef _XOPEN_SOURCE_EXTENDED - #include #include #include "../../dprint.h" diff --git a/modules/rtp.io/Makefile b/modules/rtp.io/Makefile new file mode 100644 index 00000000000..5b8b8f9f008 --- /dev/null +++ b/modules/rtp.io/Makefile @@ -0,0 +1,12 @@ +# rtp.io module makefile + +include ../../Makefile.defs + +auto_gen= +NAME=rtp.io.so + +DEFS+=-I$(LOCALBASE)/include +LIBS += -Wl,--whole-archive $(LOCALBASE)/lib/librtpproxy.a -Wl,--no-whole-archive \ + -lm -lssl -lcrypto `pkg-config --libs --static libsrtp2` + +include ../../Makefile.modules diff --git a/modules/rtp.io/doc/contributors.xml b/modules/rtp.io/doc/contributors.xml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/modules/rtp.io/doc/rtp.io.xml b/modules/rtp.io/doc/rtp.io.xml new file mode 100644 index 00000000000..63f10a0d03b --- /dev/null +++ b/modules/rtp.io/doc/rtp.io.xml @@ -0,0 +1,29 @@ + + + + + + + +%docentities; + +]> + + + + RTP.io Module + &osipsname; + + + + &admin; + &faq; + &contrib; + + &docCopyrights; + ©right; 2023 Sippy Software, Inc. + diff --git a/modules/rtp.io/doc/rtp.io_admin.xml b/modules/rtp.io/doc/rtp.io_admin.xml new file mode 100644 index 00000000000..37e678046b7 --- /dev/null +++ b/modules/rtp.io/doc/rtp.io_admin.xml @@ -0,0 +1,72 @@ + + + + &adminguide; + +
+ Overview + + The RTP.io module provides an integrated solution + for handling RTP traffic within &osips;, enabling RTP relaying and + processing directly inside the OpenSIPS process. This eliminates the + need for external processes such as RTPProxy, resulting in a more + streamlined, efficient, and manageable system for certain use cases. + + + The rtp.io module starts RTP handling threads in the main + OpenSIPS process and allows the rtpproxy module to access these + threads via a one-to-one socket pair. This tight integration facilitates efficient + RTP traffic management within OpenSIPS without relying on external RTP handling + services. + + + The module requires RTPProxy version 3.1 or higher, compiled + with the option to build. It utilizes the + librtpproxy library to manage RTP traffic and interfaces with the + existing rtpproxy module to generate commands, parse responses, + and process SIP messages. + + + When the rtpproxy module is loaded without arguments and the + rtp.io module is also loaded, the sockets exported by + rtp.io are used automatically in set 0. + Alternatively, these sockets can be incorporated into other sets by using the + "rtp.io:auto" moniker. + +
+ +
+ Dependencies + +
+ +
+ Exported Parameters +
+ <varname>rtpproxy_args</varname>(string) + + Command-line parameteres passed down to the embedded RTPProxy + module upon initialization. Refer to the RTPProxy + documentation for the full list. + + + + Parameter has no default value. + + + + Set <varname>rtpproxy_args</varname> parameter + +... +modparam("rtp.io", "rtpproxy_args", "-m 12000 -M 15000 -l 0.0.0.0 -6 /::") +... + + +
+
+ +
+ Exported Functions + +
+
diff --git a/modules/rtp.io/rtp_io.c b/modules/rtp.io/rtp_io.c new file mode 100644 index 00000000000..ae91b0c9823 --- /dev/null +++ b/modules/rtp.io/rtp_io.c @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2023 Sippy Software, Inc. + * + * This file is part of opensips, a free SIP server. + * + * opensips is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * opensips is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include + +#include "../../sr_module.h" +#include "../../mod_fix.h" +#include "../../pt.h" +#include "../../dprint.h" + +#include "librtpproxy.h" + +#include "rtp_io.h" +#include "rtp_io_util.h" +#include "rtp_io_params.h" + +static int mod_init(void); +static int child_init(int rank); +static void mod_destroy(void); + +static const dep_export_t deps = { + { /* OpenSIPS module dependencies */ + { MOD_TYPE_DEFAULT, "rtpproxy", DEP_SILENT|DEP_REVERSE }, + { MOD_TYPE_NULL, NULL, 0 }, + }, +}; + +static int rtp_io_getchildsock(int); + +/* + * Exported functions + */ +static const cmd_export_t cmds[] = { + {"rtp_io_getchildsock", (cmd_function)rtp_io_getchildsock, {0}, 0}, + {0} +}; + +/* + * Exported params + */ +static const param_export_t params[] = { + {"rtpproxy_args", STR_PARAM|USE_FUNC_PARAM, (void*)rio_set_rtpp_args}, + {0} +}; + +struct module_exports exports= { + "rtp.io", /* module's name */ + MOD_TYPE_DEFAULT,/* class of this module */ + MODULE_VERSION, + DEFAULT_DLFLAGS, /* dlopen flags */ + 0, /* load function */ + &deps, /* OpenSIPS module dependencies */ + cmds, /* exported functions */ + 0, /* exported async functions */ + params, /* param exports */ + 0, /* exported statistics */ + 0, /* exported MI functions */ + NULL, /* exported pseudo-variables */ + 0, /* exported transformations */ + 0, /* extra processes */ + 0, /* module pre-initialization function */ + mod_init, /* module initialization function */ + 0, /* reply processing function */ + mod_destroy, + child_init, /* per-child init function */ + 0 +}; + +#if defined(__linux__) +static int optreset; /* Not present in linux */ +#endif + +static struct opt_save { + char *optarg; + int optind; + int optopt; + int opterr; + int optreset; +} opt_save = {.optind = 1}; + +#define OPT_SAVE() (opt_save = (struct opt_save){optarg, optind, optopt, opterr, optreset}) +#define OPT_RESTORE() ({ \ + optarg = opt_save.optarg; \ + optind = opt_save.optind; \ + optopt = opt_save.optopt; \ + opterr = opt_save.opterr; \ + optreset = opt_save.optreset; \ +}) + +#define howmany(x, y) (sizeof(x) / sizeof(y)) + +static struct rtpp_env argv0 = {.cp = "rtpproxy"}; + +static struct rtp_io_desc rpi_desc = { + .env = {.len = 1, .first = &argv0, .last = &argv0}, +}; + +struct rtp_io_desc *rpi_descp = &rpi_desc; + +#define ENV_ADD(x, elabel, ...) { \ + struct rtpp_env *_e = rtp_io_env_asprintf((x), ##__VA_ARGS__); \ + if (_e == NULL) \ + goto elabel; \ + rtp_io_env_append(&rpi_descp->env, _e); \ +} + +static int +rio_socks_init(int nsocks) +{ + size_t asize; + struct rtp_io_socks *socks; + + LM_DBG("allocating %s(%d)\n", exports.name, nsocks); + + asize = sizeof(struct rtp_io_socks) + (nsocks * sizeof(int) * 2); + socks = malloc(asize); + if (socks == NULL) + goto e0; + + memset(socks, '\0', asize); + rpi_descp->socks = socks; + return 0; +e0: + return -1; +} + +static int mod_init(void) +{ + int nsocks; + const char * const argv_stat[] = { + "-d", "err", + "-n", "tcp:127.0.0.1:9642", + "--dso", "catch_dtmf", + "--dso", "dtls_gw", + "--dso", "ice_lite", + }; + + nsocks = count_child_processes(); + + if (nsocks <= 1) + goto e0; + + LM_DBG("initializing %s(%d)\n", exports.name, nsocks); + + if (rio_socks_init(nsocks) != 0) + goto e0; + + for (int i = 0; i < howmany(argv_stat, *argv_stat); i++) { + ENV_ADD(argv_stat[i], e1); + } + + for (int i = 0; i < nsocks; i++) { + int *fdp = &rpi_descp->socks->holder[i * 2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdp) < 0) + goto e1; + ENV_ADD("-s", e1); + ENV_ADD("fd:%d", e1, fdp[0]); + } + + + int argc; + const char *const *argv = rtp_io_env_gen_argv(&rpi_descp->env, &argc); + if (argv == NULL) + goto e1; + + OPT_RESTORE(); + rpi_descp->rtpp_cfsp = rtpp_main(argc, argv); + free((void *)argv); + if (rpi_descp->rtpp_cfsp == NULL) + goto e1; + + rpi_descp->socks->n = nsocks; + + return 0; +e1: + free(rpi_descp->socks); +e0: + return -1; +} + +void mod_destroy(void) +{ + struct rtpp_env *enext; + + LM_DBG("cleaning up %s...\n", exports.name); + rtpp_shutdown(rpi_descp->rtpp_cfsp); + for (const struct rtpp_env *e = rpi_descp->env.first; e != NULL; e = enext) { + enext = e->next; + if (e->atype == env_heap) + free(e->_cp); + if (e == &argv0) + continue; + free((void *)e); + } + for (int i = 0; i < (rpi_descp->socks->n * 2); i++) { + if (rpi_descp->socks->holder[i] != -1) + close(rpi_descp->socks->holder[i]); + } + free(rpi_descp->socks); +} + +#include + +static int +child_init(int rank) +{ + + assert(rank >= 0); + + for (int i = 0; i < rpi_descp->socks->n; i++) { + int *fdp = &rpi_descp->socks->holder[i * 2]; + if (close(fdp[0]) < 0) + return (-1); + fdp[0] = -1; + if (i == rank - 1) + continue; + if (close(fdp[1]) < 0) + return (-1); + fdp[1] = -1; + } + + return (0); +} + +static int rtp_io_getchildsock(int rank) +{ + + if (rank < 1 || rank > rpi_descp->socks->n) + return (-1); + + int *fdp = &rpi_descp->socks->holder[(rank - 1) * 2]; + return (fdp[1]); +} diff --git a/modules/rtp.io/rtp_io.h b/modules/rtp.io/rtp_io.h new file mode 100644 index 00000000000..3990cdbe655 --- /dev/null +++ b/modules/rtp.io/rtp_io.h @@ -0,0 +1,34 @@ +#pragma once + +struct rtpp_cfg; + +struct rtpp_env { + union { + const char *cp; + char *_cp; + }; + enum {env_static=0, env_heap=1} atype; + struct rtpp_env *next; +}; + +struct rtpp_env_hd { + int len; + const struct rtpp_env *first; + union { + const struct rtpp_env *last; + struct rtpp_env *_last; + }; +}; + +struct rtp_io_socks { + int n; + int holder[]; +}; + +struct rtp_io_desc { + struct rtpp_cfg *rtpp_cfsp; + struct rtpp_env_hd env; + struct rtp_io_socks *socks; +}; + +extern struct rtp_io_desc *rpi_descp; diff --git a/modules/rtp.io/rtp_io_api.h b/modules/rtp.io/rtp_io_api.h new file mode 100644 index 00000000000..c09bf127e69 --- /dev/null +++ b/modules/rtp.io/rtp_io_api.h @@ -0,0 +1,3 @@ +#pragma once + +typedef int (*rtp_io_getchildsock_t)(int); diff --git a/modules/rtp.io/rtp_io_params.c b/modules/rtp.io/rtp_io_params.c new file mode 100644 index 00000000000..ca75c8eeef4 --- /dev/null +++ b/modules/rtp.io/rtp_io_params.c @@ -0,0 +1,38 @@ +#include +#include + +#include "../../sr_module.h" + +#include "rtp_io.h" +#include "rtp_io_util.h" +#include "rtp_io_params.h" + +int +rio_set_rtpp_args(modparam_t type, void *val) +{ + char * p; + + p = (char *)val; + + + if (p == NULL || *p == '\0') { + return 0; + } + do { + char *ep = strchr(p, ' '); + if (ep != NULL) { + *ep = '\0'; + } + struct rtpp_env *rep = rtp_io_env_strref(p); + if (rep == NULL) { + return -1; + } + rtp_io_env_append(&rpi_descp->env, rep); + if (ep == NULL) + break; + p = ep + 1; + while (isspace(*p)) + p++; + } while (*p != '\0'); + return 0; +} diff --git a/modules/rtp.io/rtp_io_params.h b/modules/rtp.io/rtp_io_params.h new file mode 100644 index 00000000000..57c273e7813 --- /dev/null +++ b/modules/rtp.io/rtp_io_params.h @@ -0,0 +1,3 @@ +#pragma once + +int rio_set_rtpp_args(modparam_t, void *); diff --git a/modules/rtp.io/rtp_io_util.c b/modules/rtp.io/rtp_io_util.c new file mode 100644 index 00000000000..61020dbf5dd --- /dev/null +++ b/modules/rtp.io/rtp_io_util.c @@ -0,0 +1,78 @@ +#define _GNU_SOURCE +#include +#include +#include +#include + +#include "rtp_io.h" +#include "rtp_io_util.h" + +struct rtpp_env * +rtp_io_env_asprintf(const char *format, ...) +{ + va_list ap; + int rc; + char *cp; + + va_start(ap, format); + rc = vasprintf(&cp, format, ap); + va_end(ap); + if (rc < 0) + goto e0; + struct rtpp_env *rep = rtp_io_env_strref(cp); + if (rep != NULL) { + rep->atype = env_heap; + } else { + free(cp); + } + return rep; +e0: + return (NULL); +} + +struct rtpp_env * +rtp_io_env_strref(const char *cp) +{ + struct rtpp_env *rep; + + rep = malloc(sizeof(struct rtpp_env)); + if (rep == NULL) + goto e0; + memset(rep, '\0', sizeof(struct rtpp_env)); + rep->cp = cp; + return (rep); +e0: + return (NULL); +} + +void +rtp_io_env_append(struct rtpp_env_hd *ecp, struct rtpp_env *ep) +{ + if (ecp->first == NULL) { + ecp->last = ecp->first = ep; + } else { + ecp->_last->next = ep; + ecp->last = ep; + } + ecp->len += 1; +} + +const char *const * +rtp_io_env_gen_argv(struct rtpp_env_hd *ecp, int *lenp) +{ + const char **rval; + const struct rtpp_env *ep; + + size_t asize = ecp->len * sizeof(rval[0]); + rval = malloc(asize); + if (rval == NULL) + return (NULL); + memset(rval, '\0', asize); + ep = ecp->first; + for (int i = 0; i < ecp->len; i++) { + rval[i] = ep->cp; + ep = ep->next; + } + *lenp = ecp->len; + return (const char *const *)rval; +} diff --git a/modules/rtp.io/rtp_io_util.h b/modules/rtp.io/rtp_io_util.h new file mode 100644 index 00000000000..5f1b2df70d2 --- /dev/null +++ b/modules/rtp.io/rtp_io_util.h @@ -0,0 +1,10 @@ +#pragma once + +struct rtpp_env; +struct rtpp_env_hd; + +struct rtpp_env *rtp_io_env_asprintf(const char *, ...); +struct rtpp_env *rtp_io_env_strref(const char *); + +void rtp_io_env_append(struct rtpp_env_hd *, struct rtpp_env *); +const char *const * rtp_io_env_gen_argv(struct rtpp_env_hd *, int *); diff --git a/modules/rtpproxy/rtppn_connect.c b/modules/rtpproxy/rtppn_connect.c index aed2cb5eddd..13724fdf4ff 100644 --- a/modules/rtpproxy/rtppn_connect.c +++ b/modules/rtpproxy/rtppn_connect.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -66,6 +67,7 @@ int connect_rtpp_node(struct rtpp_node *pnode) struct addrinfo hints, *res; struct sockaddr_un sau; + assert(pnode->rn_umode != CM_RTPIO); /* * This is UDP, TCP, UDP6 or TCP6. Detect host and port; lookup host; * do connect() in order to specify peer address diff --git a/modules/rtpproxy/rtpproxy.c b/modules/rtpproxy/rtpproxy.c index ea232aacb54..fbb5590252b 100644 --- a/modules/rtpproxy/rtpproxy.c +++ b/modules/rtpproxy/rtpproxy.c @@ -188,6 +188,8 @@ #include "rtpproxy_vcmd.h" #include "rtppn_connect.h" #include "../rtp_relay/rtp_relay.h" +#include "../rtp.io/rtp_io_api.h" + #define NH_TABLE_VERSION 0 #define DEFAULT_RTPP_SET_ID 0 @@ -368,6 +370,7 @@ static int rtpproxy_autobridge = 0; static pid_t mypid; static int myrand = 0; static unsigned int myseqn = 0; +static int myrank = 0; static str nortpproxy_str = str_init("a=nortpproxy:yes"); str rtpp_notify_socket = {0, 0}; /* @@ -385,8 +388,13 @@ struct rtpp_set_head ** rtpp_set_list =0; struct rtpp_set ** default_rtpp_set=0; static int default_rtpp_set_no = DEFAULT_RTPP_SET_ID; +struct rtpp_sock { + int fd; + enum comm_modes rn_umode; +}; + /* array with the sockets used by rtpporxy (per process)*/ -static int *rtpp_socks = 0; +static struct rtpp_sock *rtpp_socks = NULL; static unsigned int *rtpp_no = 0; static unsigned int *list_version; static unsigned int my_version = 0; @@ -641,8 +649,7 @@ static int rtpproxy_set_notify(modparam_t type, void * val) return 0; } -static int add_rtpproxy_socks(struct rtpp_set * rtpp_list, - char * rtpproxy){ +static int add_rtpproxy_socks(struct rtpp_set * rtpp_list, char *rtpproxy){ /* Make rtp proxies list. */ char *p, *p1, *p2, *p3, *p4, *plim; struct rtpp_node *pnode; @@ -726,6 +733,13 @@ static int add_rtpproxy_socks(struct rtpp_set * rtpp_list, } else if (strncasecmp(pnode->rn_address, "cunix:", 6) == 0) { pnode->rn_umode = CM_CUNIX; pnode->rn_address += 6; + } else if (strncasecmp(pnode->rn_address, "rtp.io:auto", 11) == 0) { + if (pnode->rn_address[11] != '\0') { + LM_ERR("only \"rtp.io:auto\" is supported\n"); + return -1; + } + pnode->rn_umode = CM_RTPIO; + pnode->rn_address += 11; } if (rtpp_list->rn_first == NULL) { @@ -1131,6 +1145,13 @@ static int mod_preinit(void) return 0; } +static rtp_io_getchildsock_t +rtp_io_childsock_f(void) +{ + + return (rtp_io_getchildsock_t)find_export("rtp_io_getchildsock", 0); +} + static int mod_init(void) { @@ -1181,8 +1202,11 @@ mod_init(void) if(db_url.s == NULL) { if (rtpp_sets == 0) { - LM_ERR("no rtpproxy set specified\n"); - return -1; + int rtp_io_found = (rtp_io_childsock_f() == NULL) ? 0 : 1; + if (!rtp_io_found || rtpproxy_add_rtpproxy_set("rtp.io:auto", -1) != 0) { + LM_ERR("no rtpproxy set specified"); + return -1; + } } /* storing the list of rtp proxy sets in shared memory*/ @@ -1370,7 +1394,7 @@ mod_init(void) static int mi_child_init(void) { - if(child_init(1) < 0) + if (child_init(1) < 0) { LM_ERR("Failed to initial rtpp socks\n"); return -1; @@ -1480,6 +1504,7 @@ child_init(int rank) mypid = getpid(); myrand = rand()%10000; + myrank = rank; return connect_rtpproxies(NULL); } @@ -1495,7 +1520,8 @@ int connect_rtpproxies(struct rtpp_set *filter) LM_DBG("[Re]connecting sockets (%d > %d)\n", *rtpp_no, rtpp_number); if (*rtpp_no > rtpp_number) { - rtpp_socks = (int*)pkg_realloc(rtpp_socks, *rtpp_no * sizeof(int) ); + size_t asize = *rtpp_no * sizeof(rtpp_socks[0]); + rtpp_socks = (typeof(rtpp_socks))pkg_realloc(rtpp_socks, asize); if (rtpp_socks==NULL) { LM_ERR("no more pkg memory\n"); return -1; @@ -1510,16 +1536,31 @@ int connect_rtpproxies(struct rtpp_set *filter) continue; for (pnode=rtpp_list->rn_first; pnode!=0; pnode = pnode->rn_next){ - if (pnode->rn_umode == CM_UNIX) { - rtpp_socks[pnode->idx] = -1; - } else { - rtpp_socks[pnode->idx] = connect_rtpp_node(pnode); - LM_INFO("created to %d\n", rtpp_socks[pnode->idx]); - if (rtpp_socks[pnode->idx] == -1) { + switch (pnode->rn_umode) { + case CM_UNIX: + rtpp_socks[pnode->idx].fd = -1; + break; + case CM_RTPIO: + { + rtp_io_getchildsock_t gcs_f; + gcs_f = rtp_io_childsock_f(); + if (gcs_f == NULL) { + LM_ERR("rtp.io is not loaded\n"); + return -1; + } + rtpp_socks[pnode->idx].fd = gcs_f(myrank); + } + break; + default: + rtpp_socks[pnode->idx].fd = connect_rtpp_node(pnode); + LM_INFO("created to %d\n", rtpp_socks[pnode->idx].fd); + if (rtpp_socks[pnode->idx].fd == -1) { LM_ERR("connect_rtpp_node() failed\n"); return -1; } + break; } + rtpp_socks[pnode->idx].rn_umode = pnode->rn_umode; pnode->rn_disabled = rtpp_test(pnode, 0, 1); } @@ -1549,13 +1590,15 @@ int update_rtpp_proxies(struct rtpp_set *filter) { update_rtpp_notify(); for (i = 0; i < rtpp_number; i++) { + if (rtpp_socks[i].rn_umode == CM_RTPIO) + continue; if (!filter || (filter->rtpp_socks_idx <= i && i < filter->rtpp_socks_idx + filter->rtpp_node_count)) { - LM_DBG("closing rtpp_socks[%d] | filter_set: %d\n", i, + LM_DBG("closing rtpp_socks[%d].fd | filter_set: %d\n", i, filter ? filter->id_set : -1); - shutdown(rtpp_socks[i], SHUT_RDWR); - close(rtpp_socks[i]); + shutdown(rtpp_socks[i].fd, SHUT_RDWR); + close(rtpp_socks[i].fd); } } @@ -2135,9 +2178,10 @@ send_rtpp_command(struct rtpp_node *node, struct rtpproxy_vcmd *vcmd, int vcnt) max_vcnt = IOV_MAX; #endif - if (rtpp_socks[node->idx] == -1 && node->rn_umode != CM_UNIX) { - rtpp_socks[node->idx] = connect_rtpp_node(node); - if (rtpp_socks[node->idx] == -1) { + if (rtpp_socks[node->idx].fd == -1 && node->rn_umode != CM_UNIX && + node->rn_umode != CM_RTPIO) { + rtpp_socks[node->idx].fd = connect_rtpp_node(node); + if (rtpp_socks[node->idx].fd == -1) { LM_ERR("connect_rtpp_node() failed\n"); return (NULL); } @@ -2218,18 +2262,18 @@ send_rtpp_command(struct rtpp_node *node, struct rtpproxy_vcmd *vcmd, int vcnt) } } else { int rtry = CM_STREAM(node) ? 1 : rtpproxy_retr; - fds[0].fd = rtpp_socks[node->idx]; + fds[0].fd = rtpp_socks[node->idx].fd; fds[0].events = POLLIN | POLLRDHUP; fds[0].revents = 0; /* Drain input buffer */ while ((poll(fds, 1, 0) == 1) && ((fds[0].revents & POLLIN) != 0)) { if (fds[0].revents & (POLLERR|POLLNVAL|POLLRDHUP)) { - LM_ERR("error on rtpproxy socket %d!\n", rtpp_socks[node->idx]); + LM_ERR("error on rtpproxy socket %d!\n", rtpp_socks[node->idx].fd); break; } fds[0].revents = 0; - if (recv(rtpp_socks[node->idx], buf, sizeof(buf) - 1, 0) < 0 && + if (recv(rtpp_socks[node->idx].fd, buf, sizeof(buf) - 1, 0) < 0 && errno != EINTR) { LM_ERR("error while draining rtpproxy %d!\n", errno); break; @@ -2245,7 +2289,7 @@ send_rtpp_command(struct rtpp_node *node, struct rtpproxy_vcmd *vcmd, int vcnt) for (i = 0; i < rtry; i++) { int buflen = sizeof(buf)-1; do { - len = writev(rtpp_socks[node->idx], cv, vcnt + 1); + len = writev(rtpp_socks[node->idx].fd, cv, vcnt + 1); } while (len == -1 && (errno == EINTR || errno == ENOBUFS)); if (len <= 0) { LM_ERR("can't send (#%d iovec buffers) command to a RTP proxy (%d:%s)\n", @@ -2257,7 +2301,7 @@ send_rtpp_command(struct rtpp_node *node, struct rtpproxy_vcmd *vcmd, int vcnt) int s_errno; do { - len = recv(rtpp_socks[node->idx], cp, buflen, 0); + len = recv(rtpp_socks[node->idx].fd, cp, buflen, 0); } while (len == -1 && errno == EINTR); s_errno = (len < 0) ? errno : 0; if (len <= 0) { @@ -2306,9 +2350,9 @@ send_rtpp_command(struct rtpp_node *node, struct rtpproxy_vcmd *vcmd, int vcnt) return cp; badproxy: LM_ERR("proxy <%s> does not respond, disable it\n", node->rn_url.s); - if (CM_STREAM(node)) { - close(rtpp_socks[node->idx]); - rtpp_socks[node->idx] = -1; + if (CM_STREAM(node) && node->rn_umode != CM_RTPIO) { + close(rtpp_socks[node->idx].fd); + rtpp_socks[node->idx].fd = -1; } node->rn_disabled = 1; node->rn_recheck_ticks = get_ticks() + rtpproxy_disable_tout; diff --git a/modules/rtpproxy/rtpproxy.h b/modules/rtpproxy/rtpproxy.h index 53be6cc1a7d..b2e0c6839ab 100644 --- a/modules/rtpproxy/rtpproxy.h +++ b/modules/rtpproxy/rtpproxy.h @@ -41,7 +41,7 @@ struct rtpproxy_vcmd; #define AF_LOCAL AF_UNIX #endif -enum comm_modes {CM_UNIX = 0, CM_CUNIX, CM_UDP, CM_TCP, CM_UDP6, CM_TCP6}; +enum comm_modes {CM_UNIX = 0, CM_CUNIX, CM_RTPIO, CM_UDP, CM_TCP, CM_UDP6, CM_TCP6}; struct rtpp_node { unsigned int idx; /* overall index */ @@ -57,7 +57,8 @@ struct rtpp_node { struct rtpp_node *rn_next; }; -#define CM_STREAM(ndp) ((ndp)->rn_umode == CM_TCP || (ndp)->rn_umode == CM_TCP6 || (ndp)->rn_umode == CM_CUNIX) +#define CM_STREAM(ndp) ((ndp)->rn_umode == CM_TCP || (ndp)->rn_umode == CM_TCP6 || \ + (ndp)->rn_umode == CM_CUNIX || (ndp)->rn_umode == CM_RTPIO) /* Supported version of the RTP proxy command protocol */ #define SUP_CPROTOVER 20040107 diff --git a/modules/stir_shaken/stir_shaken.c b/modules/stir_shaken/stir_shaken.c index 779efc4c6b2..5c76d26c02d 100644 --- a/modules/stir_shaken/stir_shaken.c +++ b/modules/stir_shaken/stir_shaken.c @@ -33,22 +33,10 @@ * */ +/* make strptime available */ #define _GNU_SOURCE -#define _XOPEN_SOURCE 600 /* glibc2 on linux, bsd */ -#define _XOPEN_SOURCE_EXTENDED 1 /* solaris */ - -/** - * _XOPEN_SOURCE creates conflict in swab definition in Solaris - */ -#ifdef __OS_solaris - #undef _XOPEN_SOURCE -#endif - #include -#undef _XOPEN_SOURCE -#undef _XOPEN_SOURCE_EXTENDED - #include #undef _GNU_SOURCE diff --git a/scripts/build/do_build.sh b/scripts/build/do_build.sh index b5f2b103f88..425fdba9676 100755 --- a/scripts/build/do_build.sh +++ b/scripts/build/do_build.sh @@ -8,11 +8,20 @@ set -e EXCLUDE_MODULES="db_oracle osp sngtc cachedb_cassandra cachedb_couchbase \ cachedb_mongodb auth_jwt event_kafka aaa_diameter launch_darkly http2d \ - snmpstats cachedb_dynamodb event_sqs" + snmpstats cachedb_dynamodb event_sqs rtp.io" if [ ! -z "${EXCLUDE_MODULES_ADD}" ] then EXCLUDE_MODULES="${EXCLUDE_MODULES} ${EXCLUDE_MODULES_ADD}" fi -CC_EXTRA_OPTS=${CC_EXTRA_OPTS:-"-Werror"} FASTER=1 NICER=0 make \ - exclude_modules="${EXCLUDE_MODULES}" "${@}" ${MAKE_TGT:-"all"} +MAKE_ENV="FASTER=1 NICER=0" +MAKE_CMD="${MAKE_ENV} make" + +if [ ! -z "${ONE_MODULE}" ] +then + env CC_EXTRA_OPTS="${CC_EXTRA_OPTS:-"-Werror -Wno-atomic-alignment"}" ${MAKE_CMD} \ + -C "modules/${ONE_MODULE}" +else + env CC_EXTRA_OPTS="${CC_EXTRA_OPTS:-"-Werror -Wno-atomic-alignment"}" ${MAKE_CMD} \ + exclude_modules="${EXCLUDE_MODULES}" "${@}" ${MAKE_TGT:-"all"} +fi diff --git a/scripts/build/get-arch-buildargs.rtp.io b/scripts/build/get-arch-buildargs.rtp.io new file mode 100755 index 00000000000..0268319a4f9 --- /dev/null +++ b/scripts/build/get-arch-buildargs.rtp.io @@ -0,0 +1,67 @@ +#!/bin/sh + +set -e + +isbrokenplatform() { + case "${BUILD_OS}" in + debian*) + case "${TARGETPLATFORM}" in + linux/386 | linux/arm/v7 | linux/mips64le | linux/ppc64le | linux/s390x) + exit 1 + ;; + esac + ;; + ubuntu*) + case "${TARGETPLATFORM}" in + linux/arm/v7 | linux/ppc64le | linux/s390x | linux/arm64) + exit 1 + ;; + esac + ;; + esac + exit 0 +} + +fltplatforms() { + case "${BUILD_OS}" in + debian*) + FILT="grep -v -e ^linux/arm/v5\$" # broken 64-bit stdatomics + ;; + *) + FILT="cat" + ;; + esac + ${FILT} +} + +platformopts() { + out="COMPILER=clang-${LLVM_VER} LINKER=lld-${LLVM_VER}" + case "${BUILD_OS}" in + debian*) + case "${TARGETPLATFORM}" in + linux/ppc64le | linux/arm/v7 | linux/mips64le | linux/arm/v5) + out="COMPILER=clang-${LLVM_VER_OLD} LINKER=lld-${LLVM_VER_OLD}" + ;; + esac + ;; + esac + echo "${out}" + echo "${@}" +} + +case "${1}" in +platformopts) + shift + platformopts "${@}" + ;; +fltplatforms) + fltplatforms + ;; +isbrokenplatform) + isbrokenplatform + ;; +*) + echo "usage: `basename "${0}"` (platformopts|fltplatforms) [opts]" 2>&1 + exit 1 + ;; +esac diff --git a/scripts/build/install_depends.sh b/scripts/build/install_depends.sh index 845e4989d3c..d8b62dfdf2d 100755 --- a/scripts/build/install_depends.sh +++ b/scripts/build/install_depends.sh @@ -15,6 +15,10 @@ do then pkg="python-dev-is-python3" fi + if [ "${BUILD_OS%-*}" = "debian" -a "${pkg}" = libmysqlclient-dev ] + then + pkg="libmariadb-dev" + fi _PKGS="${_PKGS} ${pkg}" done PKGS="${_PKGS}" diff --git a/transformations.c b/transformations.c index 443a8376cc7..68e108de15c 100644 --- a/transformations.c +++ b/transformations.c @@ -23,22 +23,10 @@ * \brief Support for transformations */ +/* make strptime available */ #define _GNU_SOURCE -#define _XOPEN_SOURCE 600 /* glibc2 on linux, bsd */ -#define _XOPEN_SOURCE_EXTENDED 1 /* solaris */ - -/** - * _XOPEN_SOURCE creates conflict in swab definition in Solaris - */ -#ifdef __OS_solaris - #undef _XOPEN_SOURCE -#endif - #include -#undef _XOPEN_SOURCE -#undef _XOPEN_SOURCE_EXTENDED - #include #include #include